導航:首頁 > 操作系統 > 單片機定時器產生pwm

單片機定時器產生pwm

發布時間:2024-12-18 04:56:35

『壹』 用一個定時器能使單片機的兩個輸出口產生2個不同的pwm脈沖嗎懂得話給個程序。。占空比要可調的,,

提供一種思路,程序沒時間寫。
1、PWM需要周期,因此定時器必須得設置匹配值,達到周期計數時間後復位TC值;
2、兩個PWM波形需要產生可調的PWM,那麼就需要讓定時器知道什麼時刻該讓這個IO口輸出高低電平。可以讓兩個輸出提供參數,比如數值是多少後出現高電平,高電平持續多長數值?
3、最後就是關鍵點了,即將定時器TC值(周期值)細化,比如我脈寬周期設定TC值是3000時候復位,那麼我可以將這個定時器定時300時候出現一次中斷,600時候中斷一次,900時候出現一次中斷,一次類推,這樣就可以得到很多的時間片段,即標志位COUNT。
4、我希望IO口在周期內出現可調節脈寬那麼可以實現了,比如COUNT==IO1的時候讓其出現高電平,持續多長時間後出現低電平(中斷裡面完成);
簡單的示意程序:
void TIMER_HANDLE(void)
{
//判斷是否達到TC值,如果達到則復位(COUNT清零),否則執行匹配中斷
//在原有基礎上設置匹配值中斷,匹配值 +=300;
COUNT++;
if((COUNT == IO1_H_TIME)) //現在正好是需要高電平的時刻,因此值置高
{
//持續時間開啟(自減),是否為0?
//不是0,那麼繼續輸出高電平
//是0,關閉輸出,同時清除高電平時刻
}
}
估計精度不怎麼好。

『貳』 51單片機如何用一個按鍵和一個定時器來模擬PWM控制一個LED燈的亮度

使用定時器T0產生PWM方波,
用按鍵調整占空比,20級可調
控制led燈的亮度等級.
#include "my51.h"
#include "timer0.h"

#define grading 20 //亮度20級變化
sbit keyS3=P3^5; //按鍵調整占空比,PWM_keyChange++
sbit keyS4=P3^6; // PWM_keyChange--

u8 PWM_keyChange=10; //初值,按鍵調整在1~20之間變化
//占空比 PWM_keyChange/grading

void T0_work() //本函數由T0定時器中斷函數調用
{
if(timeMultiple1Flag)
{
led=off(7); //關閉7號燈
timeMultiple1Flag=0; //清定時器復用置位標志
}

if(timeMultiple2Flag)
{
led=on(7); //打開7號燈
timeMultiple2Flag=0; //清定時器復用置位標志
}
}

void main() //測試
{
u8 keyFlag=1; //程序中沒有消抖處理,只是簡易的按鍵進出自鎖標志
led0=ledon; //先打開0號燈,用於和7號燈對比亮度
initT0(1,10,grading); //1毫秒的基本定時,亮的時間1*10毫秒,暗1*(grading-10)毫秒
while(1)
{
if(0==keyS3)
{
if(keyFlag) //防止一次按鍵中多次執行
{
keyFlag=0; //清標志,類似同步鎖
if(++PWM_keyChange>grading)
{
PWM_keyChange=grading; //占空比最大100%
}
initT0(1,PWM_keyChange,grading);
}
}
else if(0==keyS4)
{
if(keyFlag)
{
keyFlag=0;
if(0==--PWM_keyChange) //占空比減小
{
PWM_keyChange=1; //最小占空比 1/20
}
initT0(1,PWM_keyChange,grading); //占空比減小
}
}
else
{
keyFlag=1; //按鍵鎖釋放標志,下一次按鍵時允許調整占空比
}
}
}

C代碼
#ifndef _MY51_H
#define _MY51_H
#include <reg52.h>
//#include <math.h>
#include <intrins.h>
#include <stdio.h>
#include "mytype.h"

#ifndef _51LED_
#define _51LED_
#define led P1 //P1匯流排連8個led燈,燈連573鎖存器,P1置低電平點亮
#define LED led
#define ON(x) P1&(~(1<<(x))) //打開某個燈,開多個燈用 ON(m) & ON(n)
#define OFF(x) P1|(1<<(x)) //關閉某個燈,關多個燈用 OFF(m)| OFF(n)
#define on(x) ON(x) //包含大小寫
#define off(x) OFF(x)

#define ledon 0 //某個燈,打開
#define ledoff 1 //某個燈,關閉

sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
sbit ledLock=P2^5; //鎖定當前8個led的狀態,0鎖定 ,1不鎖定

#endif

/*************二進制輸入宏****************************/
#ifndef _LongToBin_
#define LongToBin(n) \
( \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)
#define bin(n) LongToBin(0x##n##l)
#define BIN(n) bin(n)
#define B(n) bin(n)
#define b(n) bin(n)
#endif

/*************單個數據位的置位宏*********************/
#ifndef _BIT_
#define BIT(n) (1<<n)
#define bit(n) BIT(n)
#endif

#define high 1 //高電平
#define low 0 //低電平

sbit beep=P2^3; //蜂鳴器

extern void delayms(u16 ms);
extern void delayXus(u8 us); //函數執行(8+6x)個機器周期, 即t=(8+6x)*1.085
/////////////////////////////////////////////////////////////////////////////

#endif

C代碼
#ifndef _TIMER0_H
#define _TIMER0_H
#include "my51.h"

extern u8 timeMultiple1Flag; //中斷時間復用置位標志,須手動清零
extern u8 timeMultiple2Flag; //中斷時間復用置位標志,須手動清零
extern void T0_work(); //該函數未實現,需外部實現
extern void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2) ; //定時器初始化

#endif

C代碼
#include "timer0.h"

u8 TH0Cout=0 ; //初值
u8 TL0Cout=0 ;
u16 T0IntCouts1=0; //中斷計數
u16 T0IntCouts2=0; //中斷計數
u16 timeMultiple1=0; //中斷復用時間的倍數
u16 timeMultiple2=0; //中斷復用時間的倍數
u8 timeMultiple1Flag=0; //中斷時間復用置位標志,須手動清零
u8 timeMultiple2Flag=0; //中斷時間復用置位標志,須手動清零

//開啟定時器,定時完成後需要手動關閉TR0,否則將循環定時
//參數一是定時的毫秒數,參數二和三是定時基時的倍率數(定時復用)
void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2) //定時器初始化設定,ms取值不超過65
{
u16 N=11059.2*ms/12; //定時器總計數值
TR0=STOP; //停掉定時器
ET0=CLOSE; //關定時器中斷

//對於110592晶振,ms為5的整數倍時沒有計算誤差,但ms最大不超過71毫秒
TH0Cout =(65536-N)/256; //裝入計時值零頭計數初值
TL0Cout =(65536-N)%256;
if(0==t_multiple1) //0倍的基準時間是不合理的,至少1倍
{
t_multiple1=1;
}
if(0==t_multiple2) //0倍的基準時間是不合理的,至少1倍
{
t_multiple2=1;
}
timeMultiple1=t_multiple1; //倍時
timeMultiple2=t_multiple2; //倍時
TMOD &= 0xf0; //清定時器0配置
TMOD |= 0x01; //配置定時器0的工作方式為1

EA =OPEN; //打開總中斷
ET0=OPEN; //打開定時器中斷

TH0=TH0Cout; //定時器裝入初值
TL0=TL0Cout;
TR0=START; //啟動定時器
}
void T0_times() interrupt 1 //T0定時器中斷函數
{
TH0=TH0Cout; //重裝初值
TL0=TL0Cout;
if(++T0IntCouts1==timeMultiple1) //判斷是否復用定時器
{
T0IntCouts1=0; //中斷次數清零,重新計時
timeMultiple1Flag=1; //復用定時器標志,須在T0_work()中手動清零
}
if(++T0IntCouts2==timeMultiple2) //判斷是否復用定時器
{
T0IntCouts1=0; //這個也要清,防止到達最小公倍數時亂掉
T0IntCouts2=0; //中斷次數清零,重新計時
timeMultiple2Flag=1; //復用定時器標志,須在T0_work()中手動清零
}
T0_work(); //調用工作函數
}

『叄』 STC89c52通過單片機定時器產生的PWM波,多大電壓

STC89C52是5V,所以輸出也就是 0-5V
89c52做pwm估計也就頂多能到二三十khz了
這個電路要是直接驅動P管的話,Vi必須小於5V才能勉強工作,
驅動電壓也僅有5V,,電流小還是勉強可以看看效果的。
建議換個帶PWM的片子(STC的很多很便宜)+mos驅動晶元,做好了

閱讀全文

與單片機定時器產生pwm相關的資料

熱點內容
網路為什麼顯示伺服器無響應 瀏覽:791
ios系統怎麼運行命令 瀏覽:22
幣圈程序員 瀏覽:677
phppdoblob 瀏覽:580
法語命令式否定 瀏覽:563
sprintf單片機 瀏覽:928
為什麼安卓手機要下載不了花唄 瀏覽:745
單片機匯流排共享 瀏覽:673
usb加密設備驅動程序無法安裝 瀏覽:976
up伺服器地址 瀏覽:734
怎麼取消哈啰app續費 瀏覽:60
搞單片機和plc哪個更有前途 瀏覽:609
程序員的年夜飯 瀏覽:857
安卓平板電腦的鍵盤是如何擺放 瀏覽:594
c編譯器能跨平台嗎 瀏覽:567
匯編基礎pdf 瀏覽:308
壓縮空氣氣壓檢測接線 瀏覽:336
攝影構圖與圖像語言pdf 瀏覽:886
程序員那麼可愛啃螃蟹 瀏覽:763
變頻壓縮機啟動但是沒有進氣排氣 瀏覽:79