PWM

250 阅读1分钟
#define gpd0con *(volatile unsigned *)0xe02000a0 // 控制路线gpd0con
#define tcfg0 *(volatile unsigned *)0xe2500000	 // 预分频器0
#define tcfg1 *(volatile unsigned *)0xe2500004	 // 预分频器1
#define tcntb0 *(volatile unsigned *)0xe250000c	 // 计数器
#define tcmpb0 *(volatile unsigned *)0xe2500010	 // 比较器
#define tint_cstat *(volatile unsigned *)0xe2500044
#define tcon *(volatile unsigned *)0xe2500008 //定时器控制寄存器

//vic0
#define vic0intselect *(volatile unsigned *)0xf200000c
#define vic0intenable *(volatile unsigned *)0xf2000010
#define vic0vectaddr21 *(volatile unsigned *)0xf2000154

#define vic0address *(volatile unsigned *)0xf2000f00

void timer0_init(void);
void vic0_init(void);
void cpu_int_on(void);
void clear_int(void);
__attribute__((interrupt)) void isr(void);

int i = 1;

void _start(void)
{
	timer0_init();
	vic0_init();
	cpu_int_on();
}

void timer0_init(void)
{
	//gpd0配置成timer0功能
	gpd0con = gpd0con & ~0xf | 0x2;
	//enable interrupt
	tint_cstat |= 0x1; // 设置中断
	//timer0 clk=0.5MHZ
	tcfg0 = 131;
	tcfg1 &= ~0xf;

	//timer0 产生中断的频率为 1200HZ=0.5M/1200
	tcntb0 = 1200;
	tcmpb0 = 1;
	//开启手动更新  禁止自动加载
	tcon = tcon & ~(0x1 << 3) | (0x1 << 1);
	//开启自动加载,禁止手动更新,开启timer0
	tcon = tcon & ~(0x1 << 1) | (0x1 << 3) | 0x1;
}

void vic0_init(void)
{
	vic0intselect &= ~(0x1 << 21);
	vic0intenable |= (0x1 << 21);
	vic0vectaddr21 = isr;
}

void cpu_int_on(void)
{
	__asm__ __volatile__(

		"mrs r0,cpsr\n"
		"bic r0,r0,#0x80\n"
		"msr cpsr,r0\n"
		:
		:);
}

void clear_int(void)
{
	vic0address = 1;

	tint_cstat |= (0x1 << 5);
}

__attribute__((interrupt)) void isr(void)
{
	//占空比从1/1200 到1199/1200
	tcmpb0 = tcntb0 * (i % 1200) / 1200;
	i++;
	clear_int();
}