单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ATMEGA16单片机Timer1的OC1A脚输出占空比可调的PWM信号

[复制链接]
跳转到指定楼层
楼主
     采用快速PWM方式,通过按键设置OCR1A的值,从而改变占空比;
     当数值超出界限时,以了LED和LCD
的方式报警;
     输出经过滤波可以得到直流信号,改变占空比,输出不一样。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #define MAIN_C
  2. #include "includes.h"
  3. /***************************/
  4. /*PWM*/
  5. /*晶振为4MHz*/
  6. /*利用Timer1的OC1A脚输出占空比可调的信号*/
  7. /*通过按键控制OCR1A的值*/
  8. /***************************/

  9. #define PwmOut     PD5     //A通道的PWM输出
  10. #define OCR        OCR1A
  11. #define KeyUp      PA0     //增大PWM值的按键
  12. #define KeyDown    PA1     //减小PWM值的按键
  13. #define Above      PA2     //设置位值过高指示
  14. #define Below      PA3     //设置位值过低指示
  15. #define STEP       64      //定义按键时的步进值
  16. int OcrReg = 1024;         //OCR1A初始值
  17. int Icr1Reg = 0x7ff;       //PWM的计数顶部值  Icr1Reg = 2047
  18. //unsigned char *show = "0000";
  19. unsigned char temp;

  20. void init(void)   //初始化函数
  21. {
  22.     //比较匹配时清零,计数到最大时置位OC1A
  23.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);  
  24.     //11位分辨率,快速PWM模式,使用系统时钟作为计数时钟
  25.     TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
  26.     ICR1   = Icr1Reg;  
  27.     OCR    = 0 ;
  28.     DDRD  |= (1<<PwmOut);          //置PWM为输出
  29.     DDRA  |= (1<<Above)|(1<<Below);      //指示灯定义为输出
  30.     DDRA  &= ~((1<<KeyUp)|(1<<KeyDown)); //按键定义为输入
  31.     PORTA |= (1<<KeyUp)|(1<<KeyDown);    //按键开启上拉
  32.     PORTA |= (1<<Above)|(1<<Below);      //关闭两个指示灯
  33.     //TIMSK |= (1<<OCIE1A);   //允许计数器比较匹配中断
  34.     //SREG  |= (1<<7);   //开全局中断
  35. }

  36. void  ShowValue(int value)
  37. {
  38.     unsigned char *temp = "0000";
  39.     temp[0] = value/1000 + 0x30;
  40.     value = value%1000;
  41.     temp[1] = value/100 +0x30;
  42.     value = value%100;
  43.     temp[2] = value/10 + 0x30;
  44.     value = value%10;
  45.     temp[3] = value + 0x30;  
  46.     ClearLine(2);
  47.     LCD_DisplayString(2,1,"OCR1A = ");
  48.     LCD_DisplayString(2,9,temp);  
  49. }

  50. void main(void)
  51. {
  52.     unsigned char i;
  53.     init();
  54.     Init_LCD();
  55.     OCR = OcrReg;
  56.     LCD_DisplayString(1,1,"PWM test");
  57.     LCD_DisplayString(2,1,"OCR1A = ");
  58.     ShowValue(OcrReg);
  59.     while(1)
  60.     {               
  61.         if(!(PINA&(1<<KeyUp)))
  62.         {
  63.             delay_nms(10);    //按键消抖
  64.             if(!(PINA&(1<<KeyUp)))
  65.             {
  66.                 while(!(PINA&(1<<KeyUp)));  //等待按键释放
  67.                 if(OcrReg >= (Icr1Reg+1))
  68.                 {
  69.                     for(i=0;i<5;i++)
  70.                     {
  71.                         PORTA ^= (1<<Above);
  72.                         delay_nms(200);
  73.                     }
  74.                     ClearLine(2);
  75.                     LCD_DisplayString(2,1,"Value MAX!");
  76.                 }
  77.                 else
  78.                 {
  79.                     PORTA |= (1<<Above);
  80.                     OcrReg += STEP;                    
  81.                     OCR = OcrReg;
  82.                     ShowValue(OcrReg);
  83.                 }
  84.             }
  85.         }
  86.         if(!(PINA&(1<<KeyDown)))
  87.         {
  88.             delay_nms(10);    //按键消抖
  89.             if(!(PINA&(1<<KeyDown)))
  90.             {
  91.                 while(!(PINA&(1<<KeyDown)));  //等待按键释放
  92.                 if(OcrReg <= 0)
  93.                 {
  94.                     for(i=0;i<5;i++)
  95.                     {
  96.                         PORTA ^= (1<<Below);
  97.                         delay_nms(200);
  98.                     }
  99.                      ClearLine(2);
  100.                     LCD_DisplayString(2,1,"Value MIN!");
  101.                 }
  102.                 else
  103.                 {
  104.                     PORTA |= (1<<Below);
  105.                     OcrReg -= STEP;
  106.                     OCR = OcrReg;
  107.                     ShowValue(OcrReg);
  108.                 }
  109.             }
  110.         }      
  111.     }
  112. }


  113. //比较中断子程序,可以用来产生正弦波
  114. /*#pragma vector = TIMER1_COMPA_vect
  115.     __interrupt void CompA_isr( void )
  116. {
  117.    
  118.     OcrReg =  st[j];
  119.     OCR = OcrReg;  
  120.     j++;  
  121.     if(j>88)
  122.     {
  123.         j = 0;
  124.     }
  125. }*/
复制代码

所有资料51hei提供下载:
PWM.rar (75.23 KB, 下载次数: 7)


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

使用道具 举报

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

本版积分规则

手机版|小黑屋|单片机论坛 |51黑电子论坛技术交流 QQ 管理员QQ:125739409;技术交流QQ群636986012

Powered by 单片机教程网

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