单片机学习小组
直播中

袁声瑜

7年用户 197经验值
私信 关注

ATmega2560单片机12路PWM输出的程序

PWM模块设计说明:

使用ATmega2560单片机开发一个12路PWM输出的程序,要求每路PWM可以独立控制。通过串口指令控制某路PWM输出某个频率值(具体通道受指令第一字节控制),每路PWM的频率范围能在20-2000HZ范围内变化(具体频率值受指令第二字节控制),同时,还能够随时停止某路的输出。


指令要求:

A1  XX   第一路PWM连续输出占空比为50%不变的方波。

XX00时,停止输出,为01~FF时,输出20~2000HZ频率值,其中重点关照1000HZ以下,以5HZ为步进;1000-2000HZ15HZ步进即可,以上要求的步进值并非十分严格,如果不易实现,可以稍微修改。)  

以下均相同要求:

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  


更多回帖

发帖
×
20
完善资料,
赚取积分