#include #include"uart.h"
sbit pwmout = p1^0;
sbit led = p2^2;
sbit key1 = p1^2;
sbit key2 = p3^3;
unsigned char highrh = 0; //高電平過載值的高位元組
unsigned char highrl = 0; //高電平過載值的低位元組
unsigned char lowrh = 0; //低電平過載值的高位元組
unsigned char lowrl = 0; //低電平過載值的低位元組
unsigned int fr;
unsigned int k=0,t,i;
unsigned int s= 100;
unsigned char a[3];
unsigned int b=0;
void configpwm(unsigned int fr, unsigned char dc);
void configuart(unsigned int baud);
void delay(unsigned int n)
void main()
bit backup1 = 1;
bit backup2 = 1;
bit keybuf1 = 1; //按鍵值暫存,臨時儲存按鍵的掃瞄值
bit keybuf2 = 1; //按鍵值暫存,臨時儲存按鍵的掃瞄值
//keybuf1 = key1; //把當前掃瞄值暫存
ea=1;
led = 0;
configuart(9600); //配置波特率為9600
configpwm(100,50);
//timer1init();
while (1)
if(k==1)
k=0;
configpwm(s,50);
led = ~led;delay(2000);
keybuf1 = key1; //把當前掃瞄值暫存
if (keybuf1 != backup1) //當前值與前次值不相等說明此時按鍵有動作
delay(1000); //延時大約10ms
if (keybuf1 == key1) //判斷掃瞄值有沒有發生改變,即按鍵抖動
if (backup1 == 0) //如果前次值為0,則說明當前是彈起動作
s = s-50;
backup1 = keybuf1; //更新備份為當前值,以備進行下次比較
configpwm(s,50);
keybuf2 = key2; //把當前掃瞄值暫存
if (keybuf2 != backup2) //當前值與前次值不相等說明此時按鍵有動作
delay(1000); //延時大約10ms
if (keybuf2 == key2) //判斷掃瞄值有沒有發生改變,即按鍵抖動
if (backup2 == 0) //如果前次值為0,則說明當前是彈起動作
s = s+50;
backup2 = keybuf2; //更新備份為當前值,以備進行下次比較
configpwm(s,50);
void configuart(unsigned int baud)
scon = 0x50; //配置串列埠為模式1
tmod &= 0x0f; //清零t1的控制位
tmod |= 0x20; //配置t1為模式2
th1 = 256 - (11059200/12/32)/baud; //計算t1過載值
tl1 = th1; //初值等於過載值
et1 = 0;//中斷t1
es = 1;//串列埠中斷
tr1 = 1; //啟動t1
void configpwm(unsigned int fr, unsigned char dc)
unsigned int high, low;
unsigned long tmp;
tmp = (11059200/12)/fr; //計算乙個週期所需的計數值
high = (tmp*dc) / 100; //計算高電平所需的計數值
low = tmp - high; //計算低電平所需的計數值
high = 65536 - high + 12; //計算高電平的過載值並補償中斷延時
low = 65536 - low + 12; //計算低電平的過載值並補償中斷延時
highrh = (unsigned char)(high>>8); //高電平過載值拆分為高低位元組
highrl = (unsigned char)high;
lowrh = (unsigned char)(low>>8); //低電平過載值拆分為高低位元組
lowrl = (unsigned char)low;
tmod &= 0xf0; //清零 t0 的控制位
tmod |= 0x01; //配置 t0 為模式 1
th0 = highrh; //載入 t0 過載值
tl0 = highrl;
et0 = 1; //使能 t0 中斷
tr0 = 1; //啟動 t0
pwmout = 1; //輸出高電平
void interrupttimer0() interrupt 1
if (pwmout == 1) //當前輸出為高電平時,裝載低電平值並輸出低電平
th0 = lowrh;
tl0 = lowrl;
pwmout = 0;
else //當前輸出為低電平時,裝載高電平值並輸出高電平
th0 = highrh;
tl0 = highrl;
pwmout = 1;
/*void timer1init()
tmod|=0x10;//選擇為定時器1模式,工作方式1,僅用tr1開啟啟動。
th1=0xfc;//給定時器賦初值,定時1ms
tl1=0x18;
et1=1;//開啟定時器1中斷允許
ea=1;//開啟總中斷
tr1=1;//開啟定時器
void timer1() interrupt 3
static u16;
th1=0xfc;//給定時器賦初值,定時1ms
tl1=0x18;
i++;
if(i==1000)
i=0;
t++;
if(t%2==0)
sbuf=t/10;
sbuf=t%10;
void comint() interrupt 4 //中斷接收程式
if(ri) //判斷是否接收完,接收完成後,由硬體置ri位
ri=0;
//sbuf=sbuf;
a[b]=sbuf;
b++;
if(b==3)
/*if(a[0]=='a'&&a[1]=='b'&&a[2]=='c')
else
*/b=0;s=(a[0]-0x30)*100+(a[1]-0x30)*10+(a[2]-0x30);
k=1;
//sbuf = 't';
if(ti)
ti=0;
51微控制器 PWM
pwm,全稱pulse width modulation,譯為脈衝寬度調製。功能 改變脈衝寬度,實現不同效果。可用數碼訊號達到模擬訊號的效果 pwm在微控制器中應用廣泛,不同的應用場合意義不盡相同。先看一張圖 這是乙個週期為10ms,頻率為100hz的波形。每個週期內的高低電平脈衝寬度各不相同,這就...
51微控制器學習 PWM
pwm 脈衝寬度調調製,它是按一定規律改變脈衝序列的脈衝寬度,以調節輸出量和波形的一種調製方式。我們在控制系統中最常用的矩形pwm訊號,在控制時需要調節pwn波的占空比 指的是高電平持續時間在乙個週期時間內的百分比 當用微控制器io口輸出pwm訊號時,可採用下面三種方法 1 利用軟體延時。當高電平延...
基於51微控制器的pwm和串列埠通訊
此例程設定了按鍵可以調整100 1000hz的不同頻率 100的倍數 的方波,另外還加入了串列埠通訊,可以通過串列埠傳送來的數字來設定相對應的頻率 include include uart.h sbit pwmout p1 0 sbit led p2 2 sbit key1 p1 2 sbit ke...