PWM模块设计说明:
使用ATmega2560 单片机开发一个12路PWM输出的程序,要求每路PWM可以独立控制。通过串口指令控制某路PWM输出某个频率值(具体通道受指令第一字节控制),每路PWM的频率范围能在20-2000HZ范围内变化(具体频率值受指令第二字节控制),同时,还能够随时停止某路的输出。
指令要求:
A1 XX 第一路PWM连续输出占空比为50%不变的方波。
(XX为00时,停止输出,为01~FF时,输出20~2000HZ频率值,其中重点关照1000HZ以下,以5HZ为步进;1000-2000HZ以15HZ步进即可,以上要求的步进值并非十分严格,如果不易实现,可以稍微修改。)
以下均相同要求:
A2 XX 第二路。。。。
A3 XX 第三路。。。。
...............
AC XX 第十二路。。。。
初始上电时,各路均不输出。
avr单片机源程序:
- #include "kernel.h"
- unsigned int PWM_Buf[6];//6路PWM频率
- unsigned long timer0_ticks;
- unsigned long timer0_tickssec;
- unsigned long timer1_ticks;
- unsigned long timer1_ticksmin;
- unsigned long timer2_ticks;
- unsigned long timer2_tickssec;
- unsigned long timer3_ticks;
- unsigned long timer3_ticksmin;
- unsigned long timer4_ticks;
- unsigned long timer4_ticksmin;
- unsigned long timer5_ticks;
- unsigned long timer5_ticksmin;
- void Timer0_Init(void)
- {
- timer0_ticks = 0;
- timer0_tickssec = 0;
- TCCR0A = 0x00;
- TCCR0B = 0x00;
- TCNT0 = 0x00;
- OCR0A = F_CPU/(1024-1)/20;//频率F_PWM
- OCR0B = OCR0A/2;//占空比50%
- //TCCR0A = 0xA3; //COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00
- TCCR0B = 0xCD; //FOC0A FOC0B – – WGM02 CS02 CS01 CS00
- /*
- TCCR0A = 0x00;
- TCCR0B = 0x00;//stop
- TCNT0 = 0xE7;//25us
- OCR0A = 0x18;
- OCR0B = 0x18;
- TCCR0A = 0x03;
- TCCR0B = 0x02;//start,clkT0S/8
- TIMSK0|= 0x01;//enable 0verflow interrupt*/
- }
- void TC0_Set_PWM(unsigned int curF)
- {//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64
- if(curF==0)
- {
- OCR0A = 0;
- OCR0B = 0;
- TCCR0A = 0;
- }
- else if((curF>=20)&&(curF<80))
- {
- OCR0A = F_CPU/(1024-1)/curF;
- OCR0B = OCR0A/2;
- TCCR0A = 0xA3;
- TCCR0B = 0xCD;
- }
- else if((curF>=80)&&(curF<300))
- {
- OCR0A = F_CPU/(256-1)/curF;
- OCR0B = OCR0A/2;
- TCCR0A = 0xA3;
- TCCR0B = 0xCC;
- }
- else if((curF>=300)&&(curF<=2000))
- {
- OCR0A = F_CPU/(64-1)/curF;
- OCR0B = OCR0A/2;
- TCCR0A = 0xA3;
- TCCR0B = 0xCB;
- }
- }
- void Timer1_Init(void)
- {
- unsigned int temp;
- timer1_ticks = 0;
- timer1_ticksmin = 0;
- TCCR1A = 0x00;
- TCCR1B = 0x00;
- TCCR1C = 0x00;
- TCNT1H = 0x00;
- TCNT1L = 0x00;
- temp = F_CPU/16/20;
- OCR1A=temp;
- //temp = temp/2;
- //OCR1B=temp;
- //OCR1C=temp;
- //TCCR1A=(0< TCCR1B=(1< /*
- TCCR1A = 0x00;//COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
- TCCR1B = 0x00;//stop,ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
- TCCR1C = 0x00;//FOC1A FOC1B FOC1C – – – – –
- TCNT1H = 0xE3;
- TCNT1L = 0xE0;
- OCR1AH = 0x1C;
- OCR1AL = 0x1F;
- OCR1BH = 0x1C;
- OCR1BL = 0x1F;
- OCR1CH = 0x1C;
- OCR1CL = 0x1F;
- ICR1H = 0x00;
- ICR1L = 0x00;
- TCCR1B = 0x05;
- // TIMSK |= 0x04;//enable 0verflow interrupt*/
- }
- void TC1_Set_PWM(unsigned int curF)
- {
- unsigned int temp;
- if(curF==0)
- {
- //OCR1A = 0;
- //OCR1B = 0;
- TCCR1A=0;
- }
- else if((curF>=20)&&(curF<=2000))
- {
- temp = F_CPU/16/curF;
- OCR1A=temp;
- TCCR1A=(0< }
- }
- void Timer2_Init(void)
- {
- timer2_ticks = 0;
- timer2_tickssec = 0;
- TCCR2A = 0x00;
- TCCR2B = 0x00;
- TCNT2 = 0x00;
- OCR2A = F_CPU/(1024-1)/20;//频率F_PWM
- OCR2B = OCR2A/2;//占空比50%
- //TCCR2A = 0xA3; //COM2A1 COM2A0 COM2B1 COM2B0 – – WGM21 WGM20
- TCCR2B = 0xCF; //FOC2A FOC2B – – WGM22 CS22 CS21 CS20
- // TCCR2 = 0x00;//stop,FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
- // TCNT2 = 0xB8;//set count 10ms
- // OCR2 = 0x47;
- // TCCR2 = 0x05;//start,clkT0S/1024
- // TIMSK|= 0x40;//enable 0verflow interrupt
- }
- void TC2_Set_PWM(unsigned int curF)
- {//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64
- if(curF==0)
- {
- OCR2A = 0;
- OCR2B = 0;
- TCCR2A = 0;
- }
- else if((curF>=20)&&(curF<80))
- {
- OCR2A = F_CPU/(1024-1)/curF;
- OCR2B = OCR2A/2;
- TCCR2A = 0xA3;
- TCCR2B = 0xCF;
- }
- else if((curF>=80)&&(curF<300))
- {
- OCR2A = F_CPU/(256-1)/curF;
- OCR2B = OCR2A/2;
- TCCR2A = 0xA3;
- TCCR2B = 0xCE;
- }
- else if((curF>=300)&&(curF<=2000))
- {
- OCR2A = F_CPU/(64-1)/curF;
- OCR2B = OCR2A/2;
- TCCR2A = 0xA3;
- TCCR2B = 0xCC;
- }
- }
- void Timer3_Init(void)
- {
- unsigned int temp;
- timer3_ticks = 0;
- timer3_ticksmin = 0;
- TCCR3A = 0x00;
- TCCR3B = 0x00;
- TCCR3C = 0x00;
- TCNT3H = 0x00;
- TCNT3L = 0x00;
- temp = F_CPU/16/20;
- OCR3A=temp;
- //temp = temp/2;
- //OCR3B=temp;
- //OCR3C=temp;
- //TCCR3A=(0< TCCR3B=(1< /*
- TCCR3A = 0x00;//COM3A1 COM3A0 COM3B1 COM3B0 COM3C1 COM3C0 WGM31 WGM30
- TCCR3B = 0x00;//stop,ICNC3 ICES3 – WGM33 WGM32 CS32 CS31 CS30
- TCCR3C = 0x00;//FOC3A FOC3B FOC3C – – – – –
- TCNT3H = 0xE3;
- TCNT3L = 0xE0;//set count 1s
- OCR3AH = 0x1C;
- OCR3AL = 0x1F;
- OCR3BH = 0x1C;
- OCR3BL = 0x1F;
- OCR3CH = 0x1C;
- OCR3CL = 0x1F;
- ICR3H = 0x00;
- ICR3L = 0x00;
- TCCR3B = 0x05;//start,clkT0S/1024
- // ETIMSK|= 0x04;//enable 0verflow interrupt*/
- }
- void TC3_Set_PWM(unsigned int curF)
- {
- unsigned int temp;
- if(curF==0)
- {
- //OCR3A = 0;
- //OCR3B = 0;
- TCCR3A=0;
- }
- else if((curF>=20)&&(curF<=2000))
- {
- temp = F_CPU/16/curF;
- OCR3A=temp;
- TCCR3A=(0< }
- }
- void Timer4_Init(void)
- {
- unsigned int temp;
- timer4_ticks = 0;
- timer4_ticksmin = 0;
- TCCR4A = 0x00;
- TCCR4B = 0x00;
- TCCR4C = 0x00;
- TCNT4H = 0x00;
- TCNT4L = 0x00;
- temp = F_CPU/16/20;
- OCR4A=temp;
- //temp = temp/2;
- //OCR4B=temp;
- //OCR4C=temp;
- //TCCR4A=(0< TCCR4B=(1<}
- void TC4_Set_PWM(unsigned int curF)
- {
- unsigned int temp;
- if(curF==0)
- {
- //OCR4A = 0;
- //OCR4B = 0;
- TCCR4A=0;
- }
- else if((curF>=20)&&(curF<=2000))
- {
- temp = F_CPU/16/curF;
- OCR4A=temp;
- TCCR4A=(0< }
- }
- void Timer5_Init(void)
- {
- unsigned int temp;
- timer5_ticks = 0;
- timer5_ticksmin = 0;
- TCCR5A = 0x00;
- TCCR5B = 0x00;
- TCCR5C = 0x00;
- TCNT5H = 0x00;
- TCNT5L = 0x00;
- temp = F_CPU/16/20;
- OCR5A=temp;
- //temp = temp/2;
- //OCR5B=temp;
- //OCR5C=temp;
- //TCCR5A=(0< TCCR5B=(1<}
- void TC5_Set_PWM(unsigned int curF)
- {
- unsigned int temp;
- if(curF==0)
- {
- //OCR5A = 0;
- //OCR5B = 0;
- TCCR5A=0;
- }
- else if((curF>=20)&&(curF<=2000))
- {
- temp = F_CPU/16/curF;
- OCR5A=temp;
- TCCR5A=(0< }
- }
- /*******************************************************************************
- * Function Name : TIMER0_OVF_vectFunc
- * Description : 定时器0溢出中断程序
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- #pragma vector = TIMER0_OVF_vect
- __interrupt void TIMER0_OVF_vectFunc(void)
- {
- }
- /*******************************************************************************
- * Function Name : TIMER1_OVF_vectFunc
- * Description : 定时器1溢出中断程序
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- #pragma vector = TIMER1_OVF_vect
- __interrupt void TIMER1_OVF_vectFunc(void)
- {
- }
- /*******************************************************************************
- * Function Name : TIMER2_OVF_vectFunc
- * Description : 定时器2溢出中断程序
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- #pragma vector = TIMER2_OVF_vect
- __interrupt void TIMER2_OVF_vectFunc(void)
- {
- }
- /*******************************************************************************
- * Function Name : TIMER3_OVF_vectFunc
- * Description : 定时器3溢出中断程序
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- #pragma vector = TIMER3_OVF_vect
- __interrupt void TIMER3_OVF_vectFunc(void)
- {
- }
完整源码下载:
ATMEGA2560-PWM USART.zip
|