『壹』 基於at89c51系列單片機的兩路互補SPWM波形實現,程序如何編寫要求頻率50hz
用定時器定時10ms,中斷程序里將兩個IO管腳狀態取反即可。但兩個管腳的原始狀態是相反的。
大致 程序如下:
主程序里
TMOD=0X01;
TH0=.......
TL0=......
EA=1;
ET0=1;
PWM1=0;//一個管腳置低
PWM2=1;//另一個管腳置高
TR0=1;
中斷程序中:
TH0=.......
TL0=......
PWM1=!PWM1;
PWM2=!PWM2;
『貳』 基於AT89C51單片機點亮16×16點陣的C語言程序
摘要 #include
『叄』 基於AT89C51單片機的6位數碼管顯示的簡易電子時鍾設計
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds1302_RST =P2^0;
sbit ds1302_IO =P2^1;
sbit ds1302_SCLK=P2^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit A1=P3^0;
sbit A2=P3^1;
sbit A3=P3^2;
sbit A4=P3^3;
sbit A5=P3^4;
sbit A6=P3^5;
sbit key1=P3^6;
sbit key2=P3^7;
uchar now_time[3],wei,d[3]={0,0,0};
uchar code s[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
void delay(uint x)
{
uchar i;
for(x;x>0;x--)
for(i=0;i<100;i++);
}
void disp()
{
P1=s[now_time[2]/16];
A1=d[2];
delay(5);
A1=1;
P1=s[now_time[2]%16];
A2=d[2];
delay(5);
A2=1;
P1=s[now_time[1]/16];
A3=d[1];
delay(5);
A3=1;
P1=s[now_time[1]%16];
A4=d[1];
delay(5);
A4=1;
P1=s[now_time[0]/16];
A5=d[0];
delay(5);
A5=1;
P1=s[now_time[0]%16];
A6=d[0];
delay(5);
A6=1;
}
/***********************************************************************/
uchar read_Byte()
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=ds1302_IO;
ds1302_SCLK=1;
ds1302_SCLK=0;
}
return(ACC);
}
void write_Byte(uchar tdata)
{
uchar i;
ACC=tdata;
for(i=8;i>0;i--)
{
ds1302_IO=ACC0;
ds1302_SCLK=1;
ds1302_SCLK=0;
ACC=ACC>>1;
}
}
/***********************************************************************************/
void write_data_ds1302(uchar taddr,uchar tdata)
{
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
write_Byte(tdata);
ds1302_RST=0;
ds1302_SCLK=1;
}
uchar read_data_ds1302(uchar taddr)
{
uchar tdata;
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
tdata=read_Byte();
ds1302_RST=0;
ds1302_SCLK=1;
return(tdata);
}
/***********************************************************************************/
void get_ds1302()
{
uchar k;
uchar taddr = 0x81;
for (k=0; k<3; k++)
{
now_time[k] = read_data_ds1302(taddr);
taddr+=2;
}
}
/***********************************************************************************/
void init_ds1302()
{
ds1302_RST=0;
ds1302_SCLK=0;
A1=1;
A2=1;
A3=1;
A4=1;
A5=1;
A6=1;
write_data_ds1302(0x80,0x00);
}
/***********************************************************************************/
void Time();
/***********************************************************************************/
main()
{
init_ds1302();
while(1)
{
disp();
get_ds1302();
if(key1==0);
{ delay(10);
if(key1==0)
Time();
}
}
}
void timer() interrupt 3
{
uchar i;i++;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
if(i==50)
{
d[wei]=1;
}
if(i==100)
{ i=0;
d[wei]=0;
}
}
/***********************************************************************************/
void Time()
{
uchar temp;
uint r=0,p=1;
wei=2;
TMOD=0x01;
EA=1;
ET1=1;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
TR1=1;
for(r=0;r<50;r++)
disp();
while( key1 )
{
wei=2;
disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[2]/16*10+now_time[2]%16;
temp++;
if(temp>=24)
temp=0;
now_time[2]=temp/10*16+temp%10;
write_data_ds1302(0x84,now_time[2]);
}
while(!key2);
}
}
wei=1;
d[2]=0;
for(r=0;r<50;r++)
disp();
while(key1 )
{ disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[1]/16*10+now_time[1]%16;
temp++;
if(temp>=60)
temp=0;
now_time[1]=temp/10*16+temp%10;
write_data_ds1302(0x82,now_time[1]);
}
while(!key2);
}
}
wei=0;
d[1]=0;
for(r=0;r<50;r++)
disp();
while(key1 )
{
disp();
if(key2==0)
{
now_time[0]=0;
write_data_ds1302(0x80,now_time[0]);
}
} TR1=0;
d[0]=0;
for(r=0;r<30;r++)
disp();
}
/*********************************************************************************/
『肆』 單片機AT89c51的特點
AT89C51 提供以下標准功能:4k位元組Flash閃速存儲器,256位元組片內數據存儲器(00H -7FH為片內RAM,80H-FFH為特殊功能寄存器SFR),32 個I/O 口線,兩個16位定時/計數器,一個5向量兩級中斷結構,一個全雙工串列通信口,片內振盪器及時鍾電路。
AT89C51可降至0Hz的靜態邏輯操作,並支持兩種軟體可選的節電工作模式。空閑方式停止CPU的工作,但允許RAM,定時/計數器,串列通信口及中斷系統繼續工作。掉電方式保存RAM中的內容,但振盪器停止工作並禁止其它所有部件工作直到下一個硬體復位。
(4)基於at89c51單片機擴展閱讀:
該器件採用ATMEL高密度非易失存儲器製造技術製造,與工業標準的MCS-51指令集和輸出管腳相兼容。由於將多功能8位CPU和閃速存儲器組合在單個晶元中,ATMEL的AT89C51是一種高效微控制器,AT89C051是它的一種精簡版本。AT89C51單片機為很多嵌入式控制系統提供了一種靈活性高且價廉的方案。
現在AT89S51/52已經取代了AT89C51/52。
『伍』 基於AT89C51單片機直流電機的控製程序
首先弄清楚pid是一種控制演算法!!!
1,「如果用單片機恆溫可以使溫度到達預定值就停止加熱,低了就加熱,用一個溫度感測器反饋,這樣算是一個自動控制嗎」你這是控制系統,但是效果會非常差,尤其是對於溫度控制這種大慣性系統,達到預定值就停止加熱,但是由於慣性,溫度肯定會繼續上升,電爐燒水的時候,水開了,斷電之後水還要沸騰一定時間的(沸騰是很消耗能量的,由此可見如果是加熱的話溫度上升更嚴重,你也可以自己用溫度計試試看);「低了就加熱」是同樣的道理。如果系統對控制精度有要求,你這樣做肯定達不到要求。pid是一種控制演算法,相對於其他控制演算法來說算是最簡單的了。pid能夠做到在溫度快要達到設定值的時候降低加熱功率,讓溫度上升速度變慢,最終穩定在設定值。如果用你的直接控制,溫度會在設定值上下振盪,永遠不會停在設定值。
2,一般的控制系統都需要加反饋,以構成閉環控制系統,相對的還有開環控制系統。開環控制系統,舉個例子,就是你加熱的時候事先計算好大約需要多少熱量,然後考慮一下環境影響,計算出加熱時間,然後控制加熱系統按照你這個時間加熱。你覺得這樣的系統能夠穩定工作嗎?環境稍稍有變動就掛了!開環控制系統的特點就是很容易受到環境的影響;閉環控制系統就穩定很多,你用1l水可用,2l水也行,500w電能用,1000w電爐也能用,這就是閉環的優點。
因此,大多數的控制系統都是閉環的,開環很少單獨使用,即使用到了也是有閉環的。開環其實也是有優點的,開環在控制系統裡面叫做前饋(跟反饋對應的),比如你的系統裡面電源電壓上升了,加熱速度肯定會變快,如果你對電源電壓采樣,將采樣的結果輸入到閉環裡面,對閉環做一個輕微的修正,控制的精度會更好,這就是開環的優勢,它是超前的,能夠預知結果(根據地源電壓提高就能知道需要降低輸出功率了)。
說完這些,你應該明白了,反饋是必需的(前饋也可以要,但是不是必需的),pid不能被取代(除非你用其它更復雜的控制演算法)。
『陸』 1、 基於AT89C51單片機,利用定時器設計一個兩位數碼管顯示電路。 設計要求:每隔2S顯示數字加1,顯示初值
這個我模擬過了是有用的,,,是從00開始顯示到了99會從新開始從00開始加
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharcodedisp[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
ucharcodebit_tab[]={0xfe,0xfd};
uchardisp_buf[2];
ucharshu;
ucharcount;
voiddelay(ucharx)
{
uchari,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
voidconv(ucharflag)
{
disp_buf[0]=flag/10;
disp_buf[1]=flag%10;
}
voiddisplay()
{
uchartem,wei;
P2=bit_tab[wei];
tem=disp_buf[wei];
P0=disp[tem];
wei++;
if(wei==2)
wei=0;
}
voidtime0(void)interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(++count==40)
{
count=0;
shu++;
if(shu==99)
shu=0;
}
}
voidtime1(void)interrupt3
{
TH1=(65536-5000)/256;
TL1=(65536-5000)%256;
display();
}
voidinit()
{
TMOD=0x11;
EA=1;
ET0=1;
ET1=1;
TR1=1;
TR0=1;
}
main()
{
init();
while(1)
{
conv(shu);
}
}
『柒』 單片機基於AT89C51,16盞彩燈控制器的設計,至少四種變換形態
單片機基於AT89C51,16盞彩燈控制器的設計可棒提供幫助的親,
『捌』 基於AT89C51的電飯煲控制系統設計
本設計主要由硬體電路設計和軟體編程兩大部分來實現, 以AT89C51單片機為核心,配備顯示模塊、定時信息等, 能通過數碼管進行顯示計時。備有按鍵,以便人工定時與修改當前時間。用戶可以通過按鍵修改時間,以便達到用戶所要實現的功能。軟體採用匯編語言程序設計實現程序控制和定點時間顯示。由於本系統採用了數碼管作為顯示器。以便實時觀察與調整。使用方便,減少了許多操作工序,實現其智能化,在未來的發展進程中,佔有重要的地位。
按照系統設計功能的要求,初步確定設計系統由主控模塊、時鍾模塊、顯示模塊、鍵盤介面模塊等組成,電路系統構成框圖如圖1所示。
根據設計要求,有如下方案:
方案1:使用模擬電路設計,許多功能都要求人與硬體一起來完成。電路結構圖復雜,需要大量的元器件,會大幅度的提高設計成本,智能化效果差,而且電路性能不夠穩定,降低實現效果,所以不宜選用。
方案2:使用單片機為核心設計,由於大部分功能可以用程序來實現,實現了工作智能化,節省了許多元器件,且性能更穩定,成本較低,實用性更強。
因此選用單片機作為核心部份,效果最佳,容易實現,確定設計方案如下:
(1) 系統顯示採用8位LED數碼管。LED數碼管段碼輸入由P0口產生、位碼輸入由P2口產生。
(2) 時間調整與定時時間的輸入通過接入鍵盤電路實現。5個按鍵定義為:
SET鍵(時間調整設置鍵):功能是當該鍵按下時,進入時間調整功能。
ALM鍵(定時時間設置鍵):其功能是當該鍵按下時,進入定時時間輸入功能。
+1鍵:其功能是當該鍵按下時,被調整位加一。
-1鍵:其功能是當該鍵按下時,被調整位減一。
RET鍵:其功能是當該鍵按下時,指向下一個要調整的位。
按鍵的接入方式
SET鍵:通過P3口P3.2(INT0)引腳接入,中斷工作方式。
ALM鍵:通過P3口P3.3(INT1)引腳接入,中斷工作方式。
+1鍵:通過P3口P3.0引腳接入,查詢工作方式。
-1鍵:通過P3口P3.1引腳接入,查詢工作方式。
RET鍵:通過P3口P3.4引腳接入,查詢工作方式。
(3) 報警聲響用蜂器產生,蜂鳴器接入P1口的P1.6腳。
(4) 報警指示採用發光二極體實現,發光二極體接入P1口的P1.0腳。
(5) 外部電器電源的通斷用一個繼電器來完成這個功能,繼電器觸點的斷開與接通,通過P2口的P2.6腳控制。
『玖』 基於AT89C51單片機的LED數字倒計時器
#include<reg51.h>
#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//0-9
unsigned char sec=0,min=0,hour=24,scanled;
unsigned char key,mode,time;
unsigned char disdat[8];
unsigned char alarm[3]={23,59,58},dly;
sbit keyhu=P1^0;
sbit keyhd=P1^1;
sbit keymu=P1^2;
sbit keymd=P1^3;
sbit keysu=P1^4;
sbit keysd=P1^5;
sbit keyst=P1^6;
sbit fmq=P3^0;
bit flag=0;
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void dischg()
{
disdat[0]=sec%10;
disdat[1]=sec/10;
disdat[2]=min%10;
disdat[3]=min/10;
disdat[4]=hour%10;
disdat[5]=hour/10;
}
void t0isr() interrupt 1//秒計時
{
TH0=0x3c;
TL0=0xb0;
time++;
switch(mode)
{
case 0:
if(time==20)
{
time=0;
sec++;
if(sec>59)
{
sec=0;
min++;
if(min>59)
{
min=0;
hour++;
if(hour>23)hour=0;
}
}
}
break;
case 1:
if(time==20)
{
time=0;
if(sec>0 && flag==0)sec--;
else if(min>0 && flag==0){sec=59;min--;}
else if(hour>0 && flag==0){sec=59;min=59;hour--;}
if((hour == alarm[0]) && (min == alarm[1]) && (sec == alarm[2])){fmq=1;flag=1;dly++;}
}
break;
}
if(dly>=2){fmq=0;flag=0;TR0=0;dly=0;}
dischg();
}
void t1isr() interrupt 3//顯示
{
TH1=0xec;
TL1=0x78;
switch(scanled)
{
case 0:
P2=0x20;
P0=~ledtab[disdat[5]];
break;
case 1:
P2=0x10;
P0=~ledtab[disdat[4]]&0x7f;
break;
case 2:
P2=0x08;
P0=~ledtab[disdat[3]];
break;
case 3:
P2=0x04;
P0=~ledtab[disdat[2]]&0x7f;
break;
case 4:
P2=0x02;
P0=~ledtab[disdat[1]];
break;
case 5:
P2=0x01;
P0=~ledtab[disdat[0]];
break;
default:break;
}
scanled++;
scanled%=6;
}
main()
{
TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
TH1=0xec;
TL1=0x78;
TR1=1;
TR0=0;
ET0=1;
ET1=1;
EA=1;
fmq=0;
scanled=0;
time=0;
mode=1;
dischg();
while(1)
{
if(keyhu==0)
{
while(keyhu==0);
TR0=0;
hour++;
hour%=24;
}
if(keyhd==0)
{
while(keyhd==0);
TR0=0;
if(hour>0)hour--;
if(hour==0)hour=23;
}
if(keymu==0)
{
while(keymu==0);
TR0=0;
min++;
min%=60;
}
if(keymd==0)
{
while(keymd==0);
TR0=0;
if(min>0)min--;
if(min==0)min=59;
}
if(keysu==0)
{
while(keysu==0);
TR0=0;
sec++;
sec%=60;
}
if(keysd==0)
{
while(keysd==0);
TR0=0;
if(sec>0)sec--;
if(sec==0)sec=59;
}
if(keyst==0)
{
while(keyst==0);
TR0=~TR0;
}
dischg();
}
}