pwm
pulse-width-modulation
说在前面
一样,也是第二次学习了,确实有点印象的话好理解很多。
关于定时器吧
记得以前上学学51的时候有个TH和TL寄存器的,(不知道有没有记错了)也是一样一个负责load值进去,一个负责减好像。。。扯远了。。
回归正题吧
定时器就是用来定时的,这里就是一直计数计数,打到某个数值之后产生中断,这里的中断应该就是reload那些值进去给down-counting寄存器。
其实TNCTB和TCMPB以及TCNT这三个寄存器完成的只是一个周期的事情。
要连续不断产生一个pwm波形的话就必须不断的重复这个周期,然后这里呢它有一个自动重装载机制,所以就能一直重复这个周期,产生一个波形。
主要要配置的寄存器
看这款开发板,从数据手册的overview里面可以大概知道需要配置的寄存器有
TCNT down-counter
TCONTB 是一个buffer寄存器,给这个TCNT去load值的
TCMPB 是一个比较寄存器,跟TCNT去比较的,比较的高地就用来产生波形的
下面是一个从数据手册上的截图,是一个pwm周期的例子
继续看数据手册,有一个pwm定时器的时钟数图,结合开头的overview,可以知道还需要配置前面的prescaler和mux开关来产生特定的时钟源,再通过你自己配置的TCNT、TCNTB、TCMPB来输出特定的波形。
关于prescaler和mux开关的寄存器,在手册timer里面的pwm-timer里面的register map看到是由TCFG0和TCFG1分别对应设置的。
总结
需要配置的寄存器有
TCFG0
TCFG1
TCON -------控制定时器开关的,忘记说了
TCNTB
TCMPB
蜂鸣器这边呢?
从底板图看到这块板子的蜂鸣器接在了核心板的PWMTOUT2引脚
然后追溯到开发板,对应的是GPD0_2
PWM定时器的初始化
void timer2_pwm_init(void)
{
// 设置GPD0_2引脚,将其配置为XpwmTOUT_2
rGPD0CON &= ~(0xf<<8); //先清零
rGPD0CON |= (2<<8); // 再赋值设置为TOUT2模式
// 设置PWM定时器的寄存器,使其工作
rTCFG0 &= ~(0xff<<8);
rTCFG0 |= (65<<8); // prescaler1 = 65, 预分频后频率为1MHz
rTCFG1 &= ~(0x0f<<8);
rTCFG1 |= (1<<8); // MUX2设置为1/2,分频后时钟周期为500KHz
// 时钟设置好,我们的时钟频率是500KHz,对应的时钟周期是2us。也就是说每隔2us
// 计一次数。如果要定的时间是x,则TCNTB中应该写入x/2us
rTCON |= (1<<15); // 使能auto-reload,反复定时才能发出PWM波形
//rTCNTB2 = 250; // 0.5ms/2us = 500us/2us = 250
//rTCMPB2 = 125; // duty = 50%
//rTCNTB2 = 50;
//rTCMPB2 = 25;
// 第一次需要手工将TCNTB中的值刷新到TCNT中去,以后就可以auto-reload了
//rTCON |= (1<<13); // 打开自动刷新功能
//rTCON &= ~(1<<13); // 关闭自动刷新功能
//rTCON |= (1<<12); // 打开自动刷新功能
//正常测试的话要把上面的注释号都去掉。
}
按照顺序来
800页左右 数据手册
1.设置蜂鸣器的GPIO口,设置为TOUT2模式
2.设置TCFG0,配置分频频率
设置分频的prescaler的值
3.设置TCFG1,设置mux开关,得到最终的分频频率
4.设置TCON寄存器,第15位是timer2的auto reload位,设置了之后TCNTB的值就会自动load到TCNT里面
5.设置TCNTB(设置定时时间)和TCMPB(设置占空比的)
关于这个定时时间
例如:这里上面经过prescaler和mux开关得到500KHz的时钟频率,然后我需要一个(do 256Hz频率的)值,那么我就要500/256个周期的500KHz的频率才能组合成一个256Hz的频率,所以TCNTB的值=500/256。
6.要设置TCON的第13位,因为第一次要手动把TCNTB和TCMPB的值load进去,后面才会自动reload
7.最后设置TCON的12位,开Timer。
关于这段程序代码
我就不自己写了,把课程的代码直接拿过来用,把它的define放在了pwm.h头文件里面,最后自己makefile加上pwm.o,在key.c的中断里面加上这个定时器,自己设置TCNTB和TCMPB的频率,就有do re mi fa so的声音了,虽然很水 做得。。。。。。