单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4330|回复: 8
打印 上一主题 下一主题
收起左侧

ATmega2560单片机12路PWM输出的程序 每路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单片机源程序:
  1. #include "kernel.h"

  2. unsigned int PWM_Buf[6];//6路PWM频率

  3. unsigned long timer0_ticks;
  4. unsigned long timer0_tickssec;
  5. unsigned long timer1_ticks;
  6. unsigned long timer1_ticksmin;
  7. unsigned long timer2_ticks;
  8. unsigned long timer2_tickssec;
  9. unsigned long timer3_ticks;
  10. unsigned long timer3_ticksmin;
  11. unsigned long timer4_ticks;
  12. unsigned long timer4_ticksmin;
  13. unsigned long timer5_ticks;
  14. unsigned long timer5_ticksmin;

  15. void Timer0_Init(void)
  16. {
  17.     timer0_ticks = 0;
  18.     timer0_tickssec = 0;

  19.     TCCR0A = 0x00;
  20.     TCCR0B = 0x00;
  21.     TCNT0 = 0x00;
  22.     OCR0A = F_CPU/(1024-1)/20;//频率F_PWM
  23.     OCR0B = OCR0A/2;//占空比50%
  24.     //TCCR0A = 0xA3;  //COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00
  25.     TCCR0B = 0xCD;  //FOC0A FOC0B – – WGM02 CS02 CS01 CS00
  26.     /*
  27.     TCCR0A = 0x00;
  28.     TCCR0B = 0x00;//stop
  29.     TCNT0  = 0xE7;//25us
  30.     OCR0A  = 0x18;
  31.     OCR0B  = 0x18;
  32.     TCCR0A = 0x03;
  33.     TCCR0B = 0x02;//start,clkT0S/8
  34.     TIMSK0|= 0x01;//enable 0verflow interrupt*/
  35. }

  36. void TC0_Set_PWM(unsigned int curF)
  37. {//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64
  38.     if(curF==0)
  39.     {
  40.         OCR0A = 0;
  41.         OCR0B = 0;
  42.         TCCR0A = 0;
  43.     }
  44.     else if((curF>=20)&&(curF<80))
  45.     {
  46.         OCR0A = F_CPU/(1024-1)/curF;
  47.         OCR0B = OCR0A/2;
  48.         TCCR0A = 0xA3;
  49.         TCCR0B = 0xCD;
  50.     }
  51.     else if((curF>=80)&&(curF<300))
  52.     {
  53.         OCR0A = F_CPU/(256-1)/curF;
  54.         OCR0B = OCR0A/2;
  55.         TCCR0A = 0xA3;
  56.         TCCR0B = 0xCC;
  57.     }
  58.     else if((curF>=300)&&(curF<=2000))
  59.     {
  60.         OCR0A = F_CPU/(64-1)/curF;
  61.         OCR0B = OCR0A/2;
  62.         TCCR0A = 0xA3;
  63.         TCCR0B = 0xCB;
  64.     }
  65. }

  66. void Timer1_Init(void)
  67. {
  68.     unsigned int temp;

  69.     timer1_ticks = 0;
  70.     timer1_ticksmin = 0;

  71.     TCCR1A = 0x00;
  72.     TCCR1B = 0x00;
  73.     TCCR1C = 0x00;
  74.     TCNT1H = 0x00;
  75.     TCNT1L = 0x00;
  76.     temp = F_CPU/16/20;
  77.     OCR1A=temp;
  78.     //temp = temp/2;
  79.     //OCR1B=temp;
  80.     //OCR1C=temp;
  81.     //TCCR1A=(0<<COM1A1)|(1<<COM1A0)|/*(1<<COM1B1)|(0<<COM1B0)|(1<<COM1C1)|(0<<COM1C0)|*/(1<<WGM11)|(1<<WGM10);
  82.     TCCR1B=(1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)/*|(1<<CS10)*/;
  83.     /*
  84.     TCCR1A = 0x00;//COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
  85.     TCCR1B = 0x00;//stop,ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
  86.     TCCR1C = 0x00;//FOC1A FOC1B FOC1C – – – – –
  87.     TCNT1H = 0xE3;
  88.     TCNT1L = 0xE0;
  89.     OCR1AH = 0x1C;
  90.     OCR1AL = 0x1F;
  91.     OCR1BH = 0x1C;
  92.     OCR1BL = 0x1F;
  93.     OCR1CH = 0x1C;
  94.     OCR1CL = 0x1F;
  95.     ICR1H  = 0x00;
  96.     ICR1L  = 0x00;
  97.     TCCR1B = 0x05;
  98. //    TIMSK |= 0x04;//enable 0verflow interrupt*/
  99. }

  100. void TC1_Set_PWM(unsigned int curF)
  101. {
  102.     unsigned int temp;

  103.     if(curF==0)
  104.     {
  105.         //OCR1A = 0;
  106.         //OCR1B = 0;
  107.         TCCR1A=0;
  108.     }
  109.     else if((curF>=20)&&(curF<=2000))
  110.     {
  111.         temp = F_CPU/16/curF;
  112.         OCR1A=temp;
  113.         TCCR1A=(0<<COM1A1)|(1<<COM1A0)|/*(1<<COM1B1)|(0<<COM1B0)|(1<<COM1C1)|(0<<COM1C0)|*/(1<<WGM11)|(1<<WGM10);
  114.     }
  115. }

  116. void Timer2_Init(void)
  117. {
  118.     timer2_ticks = 0;
  119.     timer2_tickssec = 0;

  120.     TCCR2A = 0x00;
  121.     TCCR2B = 0x00;
  122.     TCNT2 = 0x00;
  123.     OCR2A = F_CPU/(1024-1)/20;//频率F_PWM
  124.     OCR2B = OCR2A/2;//占空比50%
  125.     //TCCR2A = 0xA3;  //COM2A1 COM2A0 COM2B1 COM2B0 – – WGM21 WGM20
  126.     TCCR2B = 0xCF;  //FOC2A FOC2B – – WGM22 CS22 CS21 CS20

  127. //    TCCR2 = 0x00;//stop,FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
  128. //    TCNT2 = 0xB8;//set count 10ms
  129. //    OCR2  = 0x47;
  130. //    TCCR2 = 0x05;//start,clkT0S/1024
  131. //    TIMSK|= 0x40;//enable 0verflow interrupt
  132. }

  133. void TC2_Set_PWM(unsigned int curF)
  134. {//20~80为clkT0S/1024,80~300为clkT0S/256,300~2000为clkT0S/64
  135.     if(curF==0)
  136.     {
  137.         OCR2A = 0;
  138.         OCR2B = 0;
  139.         TCCR2A = 0;
  140.     }
  141.     else if((curF>=20)&&(curF<80))
  142.     {
  143.         OCR2A = F_CPU/(1024-1)/curF;
  144.         OCR2B = OCR2A/2;
  145.         TCCR2A = 0xA3;
  146.         TCCR2B = 0xCF;
  147.     }
  148.     else if((curF>=80)&&(curF<300))
  149.     {
  150.         OCR2A = F_CPU/(256-1)/curF;
  151.         OCR2B = OCR2A/2;
  152.         TCCR2A = 0xA3;
  153.         TCCR2B = 0xCE;
  154.     }
  155.     else if((curF>=300)&&(curF<=2000))
  156.     {
  157.         OCR2A = F_CPU/(64-1)/curF;
  158.         OCR2B = OCR2A/2;
  159.         TCCR2A = 0xA3;
  160.         TCCR2B = 0xCC;
  161.     }
  162. }

  163. void Timer3_Init(void)
  164. {
  165.     unsigned int temp;

  166.     timer3_ticks = 0;
  167.     timer3_ticksmin = 0;

  168.     TCCR3A = 0x00;
  169.     TCCR3B = 0x00;
  170.     TCCR3C = 0x00;
  171.     TCNT3H = 0x00;
  172.     TCNT3L = 0x00;
  173.     temp = F_CPU/16/20;
  174.     OCR3A=temp;
  175.     //temp = temp/2;
  176.     //OCR3B=temp;
  177.     //OCR3C=temp;
  178.     //TCCR3A=(0<<COM3A1)|(1<<COM3A0)|/*(1<<COM3B1)|(0<<COM3B0)|(1<<COM3C1)|(0<<COM3C0)|*/(1<<WGM31)|(1<<WGM30);
  179.     TCCR3B=(1<<WGM33)|(1<<WGM32)|(0<<CS32)|(1<<CS31)/*|(1<<CS30)*/;
  180.     /*
  181.     TCCR3A = 0x00;//COM3A1 COM3A0 COM3B1 COM3B0 COM3C1 COM3C0 WGM31 WGM30
  182.     TCCR3B = 0x00;//stop,ICNC3 ICES3 – WGM33 WGM32 CS32 CS31 CS30
  183.     TCCR3C = 0x00;//FOC3A FOC3B FOC3C – – – – –
  184.     TCNT3H = 0xE3;
  185.     TCNT3L = 0xE0;//set count 1s
  186.     OCR3AH = 0x1C;
  187.     OCR3AL = 0x1F;
  188.     OCR3BH = 0x1C;
  189.     OCR3BL = 0x1F;
  190.     OCR3CH = 0x1C;
  191.     OCR3CL = 0x1F;
  192.     ICR3H  = 0x00;
  193.     ICR3L  = 0x00;
  194.     TCCR3B = 0x05;//start,clkT0S/1024
  195. //    ETIMSK|= 0x04;//enable 0verflow interrupt*/
  196. }

  197. void TC3_Set_PWM(unsigned int curF)
  198. {
  199.     unsigned int temp;

  200.     if(curF==0)
  201.     {
  202.         //OCR3A = 0;
  203.         //OCR3B = 0;
  204.         TCCR3A=0;
  205.     }
  206.     else if((curF>=20)&&(curF<=2000))
  207.     {
  208.         temp = F_CPU/16/curF;
  209.         OCR3A=temp;
  210.         TCCR3A=(0<<COM3A1)|(1<<COM3A0)|/*(1<<COM3B1)|(0<<COM3B0)|(1<<COM3C1)|(0<<COM3C0)|*/(1<<WGM31)|(1<<WGM30);
  211.     }
  212. }

  213. void Timer4_Init(void)
  214. {
  215.     unsigned int temp;

  216.     timer4_ticks = 0;
  217.     timer4_ticksmin = 0;

  218.     TCCR4A = 0x00;
  219.     TCCR4B = 0x00;
  220.     TCCR4C = 0x00;
  221.     TCNT4H = 0x00;
  222.     TCNT4L = 0x00;
  223.     temp = F_CPU/16/20;
  224.     OCR4A=temp;
  225.     //temp = temp/2;
  226.     //OCR4B=temp;
  227.     //OCR4C=temp;
  228.     //TCCR4A=(0<<COM4A1)|(1<<COM4A0)|/*(1<<COM4B1)|(0<<COM4B0)|(1<<COM4C1)|(0<<COM4C0)|*/(1<<WGM41)|(1<<WGM40);
  229.     TCCR4B=(1<<WGM43)|(1<<WGM42)|(0<<CS42)|(1<<CS41)/*|(1<<CS40)*/;
  230. }

  231. void TC4_Set_PWM(unsigned int curF)
  232. {
  233.     unsigned int temp;

  234.     if(curF==0)
  235.     {
  236.         //OCR4A = 0;
  237.         //OCR4B = 0;
  238.         TCCR4A=0;
  239.     }
  240.     else if((curF>=20)&&(curF<=2000))
  241.     {
  242.         temp = F_CPU/16/curF;
  243.         OCR4A=temp;
  244.         TCCR4A=(0<<COM4A1)|(1<<COM4A0)|/*(1<<COM4B1)|(0<<COM4B0)|(1<<COM4C1)|(0<<COM4C0)|*/(1<<WGM41)|(1<<WGM40);
  245.     }
  246. }

  247. void Timer5_Init(void)
  248. {
  249.     unsigned int temp;

  250.     timer5_ticks = 0;
  251.     timer5_ticksmin = 0;

  252.     TCCR5A = 0x00;
  253.     TCCR5B = 0x00;
  254.     TCCR5C = 0x00;
  255.     TCNT5H = 0x00;
  256.     TCNT5L = 0x00;
  257.     temp = F_CPU/16/20;
  258.     OCR5A=temp;
  259.     //temp = temp/2;
  260.     //OCR5B=temp;
  261.     //OCR5C=temp;
  262.     //TCCR5A=(0<<COM5A1)|(1<<COM5A0)|/*(1<<COM5B1)|(0<<COM5B0)|(1<<COM5C1)|(0<<COM5C0)|*/(1<<WGM51)|(1<<WGM50);
  263.     TCCR5B=(1<<WGM53)|(1<<WGM52)|(0<<CS52)|(1<<CS51)/*|(1<<CS50)*/;
  264. }

  265. void TC5_Set_PWM(unsigned int curF)
  266. {
  267.     unsigned int temp;

  268.     if(curF==0)
  269.     {
  270.         //OCR5A = 0;
  271.         //OCR5B = 0;
  272.         TCCR5A=0;
  273.     }
  274.     else if((curF>=20)&&(curF<=2000))
  275.     {
  276.         temp = F_CPU/16/curF;
  277.         OCR5A=temp;
  278.         TCCR5A=(0<<COM5A1)|(1<<COM5A0)|/*(1<<COM5B1)|(0<<COM5B0)|(1<<COM5C1)|(0<<COM5C0)|*/(1<<WGM51)|(1<<WGM50);
  279.     }
  280. }

  281. /*******************************************************************************
  282. * Function Name  : TIMER0_OVF_vectFunc
  283. * Description    : 定时器0溢出中断程序
  284. * Input          : None
  285. * Output         : None
  286. * Return         : None
  287. *******************************************************************************/
  288. #pragma vector = TIMER0_OVF_vect
  289. __interrupt void TIMER0_OVF_vectFunc(void)
  290. {

  291. }

  292. /*******************************************************************************
  293. * Function Name  : TIMER1_OVF_vectFunc
  294. * Description    : 定时器1溢出中断程序
  295. * Input          : None
  296. * Output         : None
  297. * Return         : None
  298. *******************************************************************************/
  299. #pragma vector = TIMER1_OVF_vect
  300. __interrupt void TIMER1_OVF_vectFunc(void)
  301. {

  302. }

  303. /*******************************************************************************
  304. * Function Name  : TIMER2_OVF_vectFunc
  305. * Description    : 定时器2溢出中断程序
  306. * Input          : None
  307. * Output         : None
  308. * Return         : None
  309. *******************************************************************************/
  310. #pragma vector = TIMER2_OVF_vect
  311. __interrupt void TIMER2_OVF_vectFunc(void)
  312. {

  313. }

  314. /*******************************************************************************
  315. * Function Name  : TIMER3_OVF_vectFunc
  316. * Description    : 定时器3溢出中断程序
  317. * Input          : None
  318. * Output         : None
  319. * Return         : None
  320. *******************************************************************************/
  321. #pragma vector = TIMER3_OVF_vect
  322. __interrupt void TIMER3_OVF_vectFunc(void)
  323. {

  324. }
复制代码

完整源码下载:
ATMEGA2560-PWM USART.zip (96.7 KB, 下载次数: 59)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 顶 踩
回复

使用道具 举报

沙发
成森林 发表于 2018-3-8 17:01 | 只看该作者
好东西我下载了,谢谢楼主。
回复

使用道具 举报

板凳
billtest36 发表于 2018-3-25 09:23 | 只看该作者
太好了  感謝分享
回复

使用道具 举报

地板
铭乐 发表于 2018-5-18 15:25 | 只看该作者
好东西我下载了,谢谢楼主。
回复

使用道具 举报

5#
huaishang 发表于 2018-6-22 22:59 | 只看该作者
好东西我下载了,谢谢楼主。
回复

使用道具 举报

6#
lany 发表于 2018-8-22 12:41 | 只看该作者
太好了  感謝分享
回复

使用道具 举报

7#
进击的生菜 发表于 2018-10-17 10:03 | 只看该作者
谢楼主   学习  66666666666666
回复

使用道具 举报

8#
huaishang 发表于 2018-10-21 18:08 | 只看该作者
太好了  感謝分享
回复

使用道具 举报

9#
lenjohn 发表于 2019-1-17 08:52 | 只看该作者
12个电机好做,15个pwm都做难,有可能吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51hei电子论坛2群 联系QQ:125739409;技术交流QQ群219535678

Powered by 单片机教程网

快速回复 返回顶部 返回列表