本帖最后由 TzMVP 于 2020-10-21 00:00 編輯
PWMPWM(脈沖寬度調制)對模擬信號電平進行數字編碼的方法,計算機只能輸出0或5V的數字電壓值而不能輸出模擬電壓,而我們如果想獲得一個模擬電壓值,則需通過使用高分辨率計數器,改變方波的占空比來對一個模擬信號的電平進行編碼。
51單片機的Timer控制PWM需要用到定時器來生成不同占空比的波形,采用定時器中斷的方式。 1.IE寄存器 2. TCON寄存器 3. TMOD寄存器
4. Timer0/1計數寄存器 TL1 TH1 而當TL0(TL1)和TH0(TH1)都滿了以后,此時如果定時中斷和總中斷都已經打開,那么就會發生溢出中斷,同時這兩個寄存器清零。 運用PWM完成呼吸燈硬件電路
程序設計:
- unsigned char PWM_COUNT; //計數
- unsigned int HUXI_COUNT; //占空比更新時間
- unsigned char PWM_VLAUE; //占空比比對值
- bit direc_flag; //占空比更新方向
- void timer0_init()
- {
- TMOD = 0x02; //模式設置,00010000,定時器0,工作于模式2(M1=1,M0=0)
- TH0 = 0x47; //定時器溢出值設置,每隔200us發起一次中斷。
- TL0 = 0X47;
- TR0 =1; //定時器0開始計時
- ET0 =1; //開定時器0中斷
- EA = 1; //開總中斷
- PWM_COUNT =0;
- }
- void time0() interrupt 1
- {
- PWM_COUNT++;
- HUXI_COUNT++;
- if(PWM_COUNT == PWM_VLAUE) //判斷是否到了點亮LED的時候
- LED = 1; //點亮LED
- if(PWM_COUNT == 10) //當前周期結束
- {
- LED = 0; //熄滅LED
- PWM_COUNT = 0; //重新計時
- }
- if((HUXI_COUNT == 600) && (direc_flag == 0))
- {
- //占空比增加10%
- HUXI_COUNT = 0;
- PWM_VLAUE++;
- if(PWM_VLAUE == 9) //占空比更改方向
- direc_flag = 1;
- }
- if((HUXI_COUNT == 600) && (direc_flag == 1))
- {
- //占空比減少10%
- HUXI_COUNT = 0;
- PWM_VLAUE--;
- IF(PWM_VLAUE == 1) //占空比更改方向
- DIREC_FLAG = 0;
- }
- }
- void main()
- {
- HUXI_COUNT = 0;
- PWM_COUNT = 0;
- PWM_VLAUE = 5;
- direc_flag = 0;
- LED = 1; //默認LED熄滅
- timer0_init(); //定時器0初始化
- while(1);
- }
復制代碼 |