標(biāo)題: ATMEGA16單片機(jī)Timer1的OC1A腳輸出占空比可調(diào)的PWM信號(hào) [打印本頁]

作者: chenjh    時(shí)間: 2019-6-10 11:43
標(biāo)題: ATMEGA16單片機(jī)Timer1的OC1A腳輸出占空比可調(diào)的PWM信號(hào)
     采用快速PWM方式,通過按鍵設(shè)置OCR1A的值,從而改變占空比;
     當(dāng)數(shù)值超出界限時(shí),以了LED和LCD
的方式報(bào)警;
     輸出經(jīng)過濾波可以得到直流信號(hào),改變占空比,輸出不一樣。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #define MAIN_C
  2. #include "includes.h"
  3. /***************************/
  4. /*PWM*/
  5. /*晶振為4MHz*/
  6. /*利用Timer1的OC1A腳輸出占空比可調(diào)的信號(hào)*/
  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     //設(shè)置位值過高指示
  14. #define Below      PA3     //設(shè)置位值過低指示
  15. #define STEP       64      //定義按鍵時(shí)的步進(jìn)值
  16. int OcrReg = 1024;         //OCR1A初始值
  17. int Icr1Reg = 0x7ff;       //PWM的計(jì)數(shù)頂部值  Icr1Reg = 2047
  18. //unsigned char *show = "0000";
  19. unsigned char temp;

  20. void init(void)   //初始化函數(shù)
  21. {
  22.     //比較匹配時(shí)清零,計(jì)數(shù)到最大時(shí)置位OC1A
  23.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);  
  24.     //11位分辨率,快速PWM模式,使用系統(tǒng)時(shí)鐘作為計(jì)數(shù)時(shí)鐘
  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);      //關(guān)閉兩個(gè)指示燈
  33.     //TIMSK |= (1<<OCIE1A);   //允許計(jì)數(shù)器比較匹配中斷
  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. //比較中斷子程序,可以用來產(chǎn)生正弦波
  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. }*/
復(fù)制代碼

所有資料51hei提供下載:
PWM.rar (75.23 KB, 下載次數(shù): 28)







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1