采用快速PWM方式,通過按鍵設置OCR1A的值,從而改變占空比;
當數值超出界限時,以了LED和LCD
的方式報警;
輸出經過濾波可以得到直流信號,改變占空比,輸出不一樣。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (13.38 KB, 下載次數: 79)
下載附件
2019-6-10 19:51 上傳
單片機源程序如下:
- #define MAIN_C
- #include "includes.h"
- /***************************/
- /*PWM*/
- /*晶振為4MHz*/
- /*利用Timer1的OC1A腳輸出占空比可調的信號*/
- /*通過按鍵控制OCR1A的值*/
- /***************************/
- #define PwmOut PD5 //A通道的PWM輸出
- #define OCR OCR1A
- #define KeyUp PA0 //增大PWM值的按鍵
- #define KeyDown PA1 //減小PWM值的按鍵
- #define Above PA2 //設置位值過高指示
- #define Below PA3 //設置位值過低指示
- #define STEP 64 //定義按鍵時的步進值
- int OcrReg = 1024; //OCR1A初始值
- int Icr1Reg = 0x7ff; //PWM的計數頂部值 Icr1Reg = 2047
- //unsigned char *show = "0000";
- unsigned char temp;
- void init(void) //初始化函數
- {
- //比較匹配時清零,計數到最大時置位OC1A
- TCCR1A |= (1<<COM1A1)|(1<<WGM11);
- //11位分辨率,快速PWM模式,使用系統時鐘作為計數時鐘
- TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
- ICR1 = Icr1Reg;
- OCR = 0 ;
- DDRD |= (1<<PwmOut); //置PWM為輸出
- DDRA |= (1<<Above)|(1<<Below); //指示燈定義為輸出
- DDRA &= ~((1<<KeyUp)|(1<<KeyDown)); //按鍵定義為輸入
- PORTA |= (1<<KeyUp)|(1<<KeyDown); //按鍵開啟上拉
- PORTA |= (1<<Above)|(1<<Below); //關閉兩個指示燈
- //TIMSK |= (1<<OCIE1A); //允許計數器比較匹配中斷
- //SREG |= (1<<7); //開全局中斷
- }
- void ShowValue(int value)
- {
- unsigned char *temp = "0000";
- temp[0] = value/1000 + 0x30;
- value = value%1000;
- temp[1] = value/100 +0x30;
- value = value%100;
- temp[2] = value/10 + 0x30;
- value = value%10;
- temp[3] = value + 0x30;
- ClearLine(2);
- LCD_DisplayString(2,1,"OCR1A = ");
- LCD_DisplayString(2,9,temp);
- }
-
- void main(void)
- {
- unsigned char i;
- init();
- Init_LCD();
- OCR = OcrReg;
- LCD_DisplayString(1,1,"PWM test");
- LCD_DisplayString(2,1,"OCR1A = ");
- ShowValue(OcrReg);
- while(1)
- {
- if(!(PINA&(1<<KeyUp)))
- {
- delay_nms(10); //按鍵消抖
- if(!(PINA&(1<<KeyUp)))
- {
- while(!(PINA&(1<<KeyUp))); //等待按鍵釋放
- if(OcrReg >= (Icr1Reg+1))
- {
- for(i=0;i<5;i++)
- {
- PORTA ^= (1<<Above);
- delay_nms(200);
- }
- ClearLine(2);
- LCD_DisplayString(2,1,"Value MAX!");
- }
- else
- {
- PORTA |= (1<<Above);
- OcrReg += STEP;
- OCR = OcrReg;
- ShowValue(OcrReg);
- }
- }
- }
- if(!(PINA&(1<<KeyDown)))
- {
- delay_nms(10); //按鍵消抖
- if(!(PINA&(1<<KeyDown)))
- {
- while(!(PINA&(1<<KeyDown))); //等待按鍵釋放
- if(OcrReg <= 0)
- {
- for(i=0;i<5;i++)
- {
- PORTA ^= (1<<Below);
- delay_nms(200);
- }
- ClearLine(2);
- LCD_DisplayString(2,1,"Value MIN!");
- }
- else
- {
- PORTA |= (1<<Below);
- OcrReg -= STEP;
- OCR = OcrReg;
- ShowValue(OcrReg);
- }
- }
- }
- }
- }
- //比較中斷子程序,可以用來產生正弦波
- /*#pragma vector = TIMER1_COMPA_vect
- __interrupt void CompA_isr( void )
- {
-
- OcrReg = st[j];
- OCR = OcrReg;
- j++;
- if(j>88)
- {
- j = 0;
- }
- }*/
復制代碼
所有資料51hei提供下載:
PWM.rar
(75.23 KB, 下載次數: 28)
2019-6-10 11:42 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|