❶ 基於51系列的單片機和DS1302時鍾晶元以及液晶顯示的lcd1602電子萬年歷畢業設計,萬分感謝。
#include<reg51.h>
#include"DS18B20_3.H"
#define uint unsigned int
#define uchar unsigned char
uchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp;
//flag用於讀取頭文件中的溫度值,和顯示溫度值
#define yh 0x80 //LCD第一行的初始位置,因為LCD1602字元地址首位D7恆定為1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因為第二行第一個字元位置地址是0x40)
//液晶屏的與C51之間的引腳連接定義(顯示數據線接C51的P0口)
sbit rs=P1^0;
sbit en=P1^2;
sbit rw=P1^1; //如果硬體上rw接地,就不用寫這句和後面的rw=0了
sbit led=P3^7; //LCD背光開關
//DS1302時鍾晶元與C51之間的引腳連接定義
sbit IO=P2^2;
sbit SCLK=P2^1;
sbit RST=P2^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H
ACC.0就是ACC的第0位。Acc可以位定址。
累加器ACC是一個8位的存儲單元,是用來放數據的。但是,這個存儲單元有其特殊的地位,
是單片機中一個非常關鍵的單元,很多運算都要通過ACC來進行。以後在學習指令時,
常用A來表示累加器。但有一些地方例外,比如在PUSH指令中,就必須用ACC這樣的名字。
一般的說法,A代表了累加器中的內容、而ACC代表的是累加器的地址。
***************************************************************/
//校時按鍵與C51的引腳連接定義
sbit key1=P2^4; //設置鍵
sbit key2=P2^5; //加鍵
sbit key3=P2^6; //減鍵
sbit buzzer=P2^0;//蜂鳴器,通過三極體9012驅動,埠低電平響
/**************************************************************/
uchar code tab1[]={"20 - - "}; //年顯示的固定字元
uchar code tab2[]={" : : "};//時間顯示的固定字元
//延時函數,後面經常調用
void delay(uint xms)//延時函數,有參函數
{
uint x,y;
for(x=xms;x>0;x--)
for(y=120;y>0;y--);
}
/********液晶寫入指令函數與寫入數據函數,以後可調用**************/
/*在這個程序中,液晶寫入有關函數會在DS1302的函數中調用,所以液晶程序要放在前面*/
write_1602com(uchar com)//****液晶寫入指令函數****
{
rs=0;//數據/指令選擇置為指令
rw=0; //讀寫選擇置為寫
P0=com;//送入數據
delay(1);
en=1;//拉高使能端,為製造有效的下降沿做准備
delay(1);
en=0;//en由高變低,產生下降沿,液晶執行命令
}
write_1602dat(uchar dat)//***液晶寫入數據函數****
{
rs=1;//數據/指令選擇置為數據
rw=0; //讀寫選擇置為寫
P0=dat;//送入數據
delay(1);
en=1; //en置高電平,為製造下降沿做准備
delay(1);
en=0; //en由高變低,產生下降沿,液晶執行命令
}
lcd_init()//***液晶初始化函數****
{
write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
write_1602com(0x0c);//開顯示不顯示游標
write_1602com(0x06);//整屏不移動,游標自動右移
write_1602com(0x01);//清顯示
write_1602com(yh+1);//日歷顯示固定符號從第一行第1個位置之後開始顯示
for(a=0;a<14;a++)
{
write_1602dat(tab1[a]);//向液晶屏寫日歷顯示的固定符號部分
//delay(3);
}
write_1602com(er+2);//時間顯示固定符號寫入位置,從第2個位置後開始顯示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號
//delay(3);
}
}
/*********************over***********************/
/***************DS1302有關子函數********************/
void write_byte(uchar dat)//寫一個位元組
{
ACC=dat;
RST=1;
for(a=8;a>0;a--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
uchar read_byte()//讀一個位元組
{
RST=1;
for(a=8;a>0;a--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return (ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)//向1302晶元寫函數,指定寫入地址,數據
{
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
uchar read_1302(uchar add)//從1302讀數據函數,指定讀取數據來源地址
{
uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD碼轉十進制函數,輸入BCD,返回十進制
{
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init() //1302晶元初始化子函數(2010-01-07,12:00:00,week4)
{
RST=0;
SCLK=0;
write_1302(0x8e,0x00); //允許寫,禁止防寫
write_1302(0x80,0x00); //向DS1302內寫秒寄存器80H寫入初始秒數據00
write_1302(0x82,0x00);//向DS1302內寫分寄存器82H寫入初始分數據00
write_1302(0x84,0x12);//向DS1302內寫小時寄存器84H寫入初始小時數據12
write_1302(0x8a,0x04);//向DS1302內寫周寄存器8aH寫入初始周數據4
write_1302(0x86,0x07);//向DS1302內寫日期寄存器86H寫入初始日期數據07
write_1302(0x88,0x01);//向DS1302內寫月份寄存器88H寫入初始月份數據01
write_1302(0x8c,0x10);//向DS1302內寫年份寄存器8cH寫入初始年份數據10
write_1302(0x8e,0x80); //打開防寫
}
//------------------------------------
//溫度顯示子函數
void write_temp(uchar add,uchar dat)//向LCD寫溫度數據,並指定顯示位置
{
uchar gw,sw;
gw=dat%10;//取得個位數字
sw=dat/10;//取得十位數字
write_1602com(er+add);//er是頭文件規定的值0x80+0x40
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0xdf);//顯示溫度的小圓圈符號,0xdf是液晶屏字元庫的該符號地址碼
write_1602dat(0x43); //顯示"C"符號,0x43是液晶屏字元庫里大寫C的地址碼
}
//------------------------------------
//時分秒顯示子函數
void write_sfm(uchar add,uchar dat)//向LCD寫時分秒,有顯示位置加、現示數據,兩個參數
{
uchar gw,sw;
gw=dat%10;//取得個位數字
sw=dat/10;//取得十位數字
write_1602com(er+add);//er是頭文件規定的值0x80+0x40
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
}
//-------------------------------------
//年月日顯示子函數
void write_nyr(uchar add,uchar dat)//向LCD寫年月日,有顯示位置加數、顯示數據,兩個參數
{
uchar gw,sw;
gw=dat%10;//取得個位數字
sw=dat/10;//取得十位數字
write_1602com(yh+add);//設定顯示位置為第一個位置+add
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
}
//-------------------------------------------
void write_week(uchar week)//寫星期函數
{
write_1602com(yh+0x0c);//星期字元的顯示位置
switch(week)
{
case 1:write_1602dat('M');//星期數為1時,顯示
write_1602dat('O');
write_1602dat('N');
break;
case 2:write_1602dat('T');//星期數據為2時顯示
write_1602dat('U');
write_1602dat('E');
break;
case 3:write_1602dat('W');//星期數據為3時顯示
write_1602dat('E');
write_1602dat('D');
break;
case 4:write_1602dat('T');//星期數據為4是顯示
write_1602dat('H');
write_1602dat('U');
break;
case 5:write_1602dat('F');//星期數據為5時顯示
write_1602dat('R');
write_1602dat('I');
break;
case 6:write_1602dat('S');//星期數據為6時顯示
write_1602dat('T');
write_1602dat('A');
break;
case 7:write_1602dat('S');//星期數據為7時顯示
write_1602dat('U');
write_1602dat('N');
break;
}
}
//****************鍵盤掃描有關函數**********************
void keyscan()
{
if(key1==0)//---------------key1為功能鍵(設置鍵)--------------------
{
delay(9);//延時,用於消抖動
if(key1==0)//延時後再次確認按鍵按下
{
buzzer=0;//蜂鳴器短響一次
delay(20);
buzzer=1;
while(!key1);
key1n++;
if(key1n==9)
key1n=1;//設置按鍵共有秒、分、時、星期、日、月、年、返回,8個功能循環
switch(key1n)
{
case 1: TR0=0;//關閉定時器
//TR1=0;
write_1602com(er+0x09);//設置按鍵按動一次,秒位置顯示游標
write_1602com(0x0f);//設置游標為閃爍
temp=(miao)/10*16+(miao)%10;//秒數據寫入DS1302
write_1302(0x8e,0x00);
write_1302(0x80,0x80|temp);//miao
write_1302(0x8e,0x80);
break;
case 2: write_1602com(er+6);//按2次fen位置顯示游標
//write_1602com(0x0f);
break;
case 3: write_1602com(er+3);//按動3次,shi
//write_1602com(0x0f);
break;
case 4: write_1602com(yh+0x0e);//按動4次,week
//write_1602com(0x0f);
break;
case 5: write_1602com(yh+0x0a);//按動5次,ri
//write_1602com(0x0f);
break;
case 6: write_1602com(yh+0x07);//按動6次,yue
//write_1602com(0x0f);
break;
case 7: write_1602com(yh+0x04);//按動7次,nian
//write_1602com(0x0f);
break;
case 8:
write_1602com(0x0c);//按動到第8次,設置游標不閃爍
TR0=1;//打開定時器
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x00|temp);//miao數據寫入DS1302
write_1302(0x8e,0x80);
break;
}
}
}
//------------------------------加鍵key2----------------------------
if(key1n!=0)//當key1按下以下。再按以下鍵才有效(按鍵次數不等於零)
{
if(key2==0) //上調鍵
{
delay(10);
if(key2==0)
{
buzzer=0;//蜂鳴器短響一次
delay(20);
buzzer=1;
while(!key2);
switch(key1n)
{
case 1:miao++;//設置鍵按動1次,調秒
if(miao==60)
miao=0;//秒超過59,再加1,就歸零
write_sfm(0x08,miao);//令LCD在正確位置顯示"加"設定好的秒數
temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00); //允許寫,禁止防寫
write_1302(0x80,temp); //向DS1302內寫秒寄存器80H寫入調整後的秒數據BCD碼
write_1302(0x8e,0x80); //打開防寫
write_1602com(er+0x09);//因為設置液晶的模式是寫入數據後,游標自動右移,所以要指定返回
//write_1602com(0x0b);
break;
case 2:fen++;
if(fen==60)
fen=0;
write_sfm(0x05,fen);//令LCD在正確位置顯示"加"設定好的分數據
temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整後的分數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(er+6);//因為設置液晶的模式是寫入數據後,指針自動加一,在這里是寫回原來的位置
break;
case 3:shi++;
if(shi==24)
shi=0;
write_sfm(2,shi);//令LCD在正確的位置顯示"加"設定好的小時數據
temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整後的小時數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(er+3);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 4:week++;
if(week==8)
week=1;
write_1602com(yh+0x0C);//指定'加'後的周數據顯示位置
write_week(week);//指定周數據顯示內容
temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整後的周數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 5:ri++;
if(ri==32)
ri=1;
write_nyr(9,ri);//令LCD在正確的位置顯示"加"設定好的日期數據
temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整後的日期數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+10);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 6:yue++;
if(yue==13)
yue=1;
write_nyr(6,yue);//令LCD在正確的位置顯示"加"設定好的月份數據
temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整後的月份數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+7);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 7:nian++;
if(nian==100)
nian=0;
write_nyr(3,nian);//令LCD在正確的位置顯示"加"設定好的年份數據
temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整後的年份數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+4);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
}
}
}
//------------------減鍵key3,各句功能參照'加鍵'注釋---------------
if(key3==0)
{
delay(10);//調延時,消抖動
if(key3==0)
{
buzzer=0;//蜂鳴器短響一次
delay(20);
buzzer=1;
while(!key3);
switch(key1n)
{
case 1:miao--;
if(miao==-1)
miao=59;//秒數據減到-1時自動變成59
write_sfm(0x08,miao);//在LCD的正確位置顯示改變後新的秒數
temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00); //允許寫,禁止防寫
write_1302(0x80,temp); //向DS1302內寫秒寄存器80H寫入調整後的秒數據BCD碼
write_1302(0x8e,0x80); //打開防寫
write_1602com(er+0x09);//因為設置液晶的模式是寫入數據後,指針自動加一,在這里是寫回原來的位置
//write_1602com(0x0b);
break;
case 2:fen--;
if(fen==-1)
fen=59;
write_sfm(5,fen);
temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整後的分數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(er+6);//因為設置液晶的模式是寫入數據後,指針自動加一,在這里是寫回原來的位置
break;
case 3:shi--;
if(shi==-1)
shi=23;
write_sfm(2,shi);
temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整後的小時數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(er+3);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 4:week--;
if(week==0)
week=7;
write_1602com(yh+0x0C);//指定'加'後的周數據顯示位置
write_week(week);//指定周數據顯示內容
temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整後的周數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 5:ri--;
if(ri==0)
ri=31;
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整後的日期數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+10);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 6:yue--;
if(yue==0)
yue=12;
write_nyr(6,yue);
temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整後的月份數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+7);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
case 7:nian--;
if(nian==-1)
nian=99;
write_nyr(3,nian);
temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼
write_1302(0x8e,0x00);//允許寫,禁止防寫
write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整後的年份數據BCD碼
write_1302(0x8e,0x80);//打開防寫
write_1602com(yh+4);//因為設置液晶的模式是寫入數據後,指針自動加一,所以需要游標回位
break;
}
}
}
}
}
//-------------------------------
void init() //定時器、計數器設置函數
{
TMOD=0x11; //指定定時/計數器的工作方式為3
TH0=0; //定時器T0的高四位=0
TL0=0; //定時器T0的低四位=0
EA=1; //系統允許有開放的中斷
ET0=1; //允許T0中斷
TR0=1; //開啟中斷,啟動定時器
}
//*******************主函數**************************
//***************************************************
void main()
{
lcd_init(); //調用液晶屏初始化子函數
ds1302_init(); //調用DS1302時鍾的初始化子函數
init(); //調用定時計數器的設置子函數
led=0; //打開LCD的背光電源
buzzer=0;//蜂鳴器長響一次
delay(80);
buzzer=1;
while(1) //無限循環下面的語句:
{
keyscan(); //調用鍵盤掃描子函數
}
}
void timer0() interrupt 1 //取得並顯示日歷和時間
{
//Init_DS18B20();//溫度感測器DS18b2初始化子函數,在頭文件中
flag=ReadTemperature();//將18b2頭文件運行返回的函數結果送到變數FLAG中,用於顯示
//讀取秒時分周日月年七個數據(DS1302的讀寄存器與寫寄存器不一樣):
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi = BCD_Decimal(read_1302(0x85));
ri = BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
week=BCD_Decimal(read_1302(0x8b));
//顯示溫度、秒、時、分數據:
write_temp(12,flag);//顯示溫度,從第二行第12個字元後開始顯示
write_sfm(8,miao);//秒,從第二行第8個字後開始顯示(調用時分秒顯示子函數)
write_sfm(5,fen);//分,從第二行第5個字元後開始顯示
write_sfm(2,shi);//小時,從第二行第2個字元後開始顯示
//顯示日、月、年數據:
write_nyr(9,ri);//日期,從第二行第9個字元後開始顯示
write_nyr(6,yue);//月份,從第二行第6個字元後開始顯示
write_nyr(3,nian);//年,從第二行第3個字元後開始顯示
write_week(week);
}
❷ C51單片機對位定址的原理和編程方法
原理:
位定址是一種使用單片機實現程序控制位邏輯操作的方法,通過一系列指令在單位元組的內存空間中的一個特定的位 (bit 位) 上進行操作。它用於控制亂拿只有兩狀態的I/O埠。
編程方法:
1. 用 ORL A, #data 命令將某個指定的位置位,即把單位元組內部某個指定的位置1。
2. 用 ANL A, #data 命令清除某個指定衡槐的位置位,即咐陪友把單位元組內部某個指定的位置0。
3. 用 CLR C 命令將某個指定的位置位清零,即把單位元組內指定的位置置零。
4. 用 MOV C, bit 命令將某個指定的位置位置1,即把單位元組內部某個指定的位置1。
❸ c51單片機是什麼
單片機,是典型的嵌入式微控制器,一般用在工業控制上,現在用的c51大都是AT89c51.
❹ 基於51單片機控制交通燈的電路圖與C語言程序
思路:
紅燈停,綠燈行,黃燈閃爍提示行人紅綠燈即將切換。四個方向各有一個紅、黃、綠顯示和兩個數碼管。
東西道為人行道(20秒),南北道為車行道(60秒),黃燈延時最後三秒時,閃爍並切換。
三、硬體電路設計
此電中路設計採用AT89C51單片機,74LS47(數碼管驅動)74LS373(數碼管驅動輸出鎖存),8個數碼管顯示其延時值,四個紅、黃、綠指示燈。硬體設計關鍵在於,延時顯示時,要考慮到當個位數字顯示時,要確保十位數字顯示輸出的不變。因此,可加輸出鎖存器。在延時最後三秒時,要讓黃燈進行閃爍,並同時顯示數字(這一步在軟體設計上很關鍵)。
四、軟體程序(C語言)
以下是整個設計的軟體程序,直接可以編譯成*。Hex代碼。通過以上電路,下載到單片機,可直接運行。
//*****************************//
//程序名:十字路口交通燈控制
//編寫人:黃庭劍
//初寫時間:2009年1月2日
//程序功能:南北為車行道,延時60秒;東西方向為人行道,延時20秒,且在最後3秒黃燈顯示2秒鍾再實現切換.
//CPU說明:AT89C51型單片機;24MHZ晶體振盪器
//完成時間:2009年1月6日
//*****************************//
#include<stdio.h>
#include<reg51.h>
#include<intrins.h>
sfrp0=0x80;
sfrp1=0x90;
sfrp2=0xA0;
sfrp3=0xb0;//這部分內容其實在「#include<reg51.h>」里已經有,但裡面定義的必須區分大小寫,在這里,因為我程序採用的是小寫,reg51.h里對各個埠與寄存器的定義都是大寫,所以在編譯連接時,會報錯,所以,在本設計程序里,我只用到了埠,在這里也就只定義了四個,而沒有去改reg51.h裡面的內容。其實兩者是一樣的。
sbitsw=p0^0;
sbitOE=P0^6;
sbitLE=P0^7;//74LS373鎖存器控制端定義
chardisplay[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};//p1口的數碼管時間顯示調用,利用74L74BCD碼,8位驅動輸出;
//函數聲明begin
voiddelay1(intcount);
voiddelay_long(intnumber1,intnumber2);
voidpeople_car_drive();
//函數聲明end
//***********************//延時子程序
voiddelay1(intcount)
{inti;
for(i=count;i>0;i--)
{;}
}
voiddelay_long(intnumber1,intnumber2)
{
inta,b;
for(a=number1;a>0;a--)
{
for(b=number2;b>0;b--)
{_nop_();}
}
}
//**********************//延時子程序
voidpeople_car_drive()
{
intp_1=2,i,j=9,p_2=6;//****************//行人通行時,延時20秒
p2=0x09;//南北紅燈亮
p3=0x24;//東西綠燈亮
while(p_1-->0)
{LE=1;
OE=0;
if(p_1==0){OE=1;}//當十位數減到0時,只顯示個位數
p1=display[p_1];
delay1(1000);
LE=0;
j=9;
for(i=10;i>0;i--)
{
if(p_1==0&&j==3)break;//減到3時退出循環,讓其黃燈閃爍顯示
p1=display[j--];
delay_long(16000,2);
if(sw==1)return;
}
}
//*******************************************************************************//
p2=0x12;//南北黃燈閃爍三秒,以提醒行人注意
p3=0x12;
p1=display[3];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);
p2=0x12;
p3=0x12;
p1=display[2];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);
p2=0x12;
p3=0x12;
p1=display[1];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);
//*****************以下是車輛通行時延時60秒//
p2=0x24;//南北綠燈亮
p3=0x09;//東西紅燈亮
while(p_2-->0)
{LE=1;
OE=0;
if(p_2==0){OE=1;}//當十位數減到0時,只顯示個位數
p1=display[p_2];
delay1(1000);
LE=0;
j=9;
for(i=10;i>0;i--)
{
if(p_2==0&&j==3)break;//減到2時退出循環
p1=display[j--];
delay_long(16000,2);
if(sw==1)return;
}
}
p2=0x12;//南北黃燈閃爍三秒,以提醒行人注意
p3=0x12;
p1=display[3];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);
p2=0x12;
p3=0x12;
p1=display[2];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);
p2=0x12;
p3=0x12;
p1=display[1];
delay_long(8000,1);
p2=0x00;
p3=0x00;
delay_long(14000,1);//南北黃燈閃爍三秒完畢
}
voidmain()//主函數入口處
{
p0=0x01;
p1=0x00;
p2=0x00;
p3=0x00;//初始化各埠
{while(1)
{
if(sw==0)
{people_car_drive();}
else
{
p2=0x00;
p3=0x00;//關閉所有交通燈
}
}
}
}
詳情訪問:http://hi..com/hjiannew/
❺ 基於51系列單片機的LED顯示屏開發技術的目錄
第1章51系列單片機系統結構概述
1.151單片機概述1
1.1.1單片機的分類1
1.1.28051單片機的應用3
1.1.38051單片機的開發3
1.1.48051單片機型號的選擇4
1.1.5單片機學習的要點4
1.251單片機基本系統結構4
1.2.151單片機的結構框圖及引腳4
1.2.2MCS51系列單片機主要功能部件6
1.2.3典型時鍾電路和復位電路7
1.2.48051單片機I/O結構7
1.351單片機存儲器結構8
1.3.1程序存儲器9
1.3.2外部數據存儲器10
1.3.3內部數據存儲器空間11
1.3.4MCS51單片機特殊功能寄存器13
1.3.5常用特殊功能寄存器14
1.451單片機的指令系統及匯編語言設計要點16
1.4.1指令格式16
1.4.2偽指令17
1.4.3定址方式19
1.4.4指令類型21
1.5匯編程序設計34
1.5.1三種基本的程序結構34
1.5.2匯編程序設計的要點35
1.651單片機主要擴展功能部件39
1.6.1MCS51單片機定時/計數器39
1.6.2中困橘搜斷系統47
1.6.3串列口54
第2章C51應用基礎
2.1KeilC51簡介62
2.2C51程序設計基礎知識63
2.2.1C語言的特點63
2.2.2一個簡單的C51例子63
2.2.3C51的基礎知識64
2.2.4存儲空間定義64
2.2.5C51數據類型65
2.2.6C51存儲空間的定義67
2.2.7C51的常量67
2.2.8C51常用運算符68
2.2.9C51表達式73
2.2.10C51的基本語句74
2.3C51的函數與數組80
2.3.1函數的定義81
2.3.2數組83
2.3.3結構(struct)86
2.3.4聯合(union)87
2.4C51基本應用伍吵90
2.4.1I/O口位元組操作應用90
2.4.2I/O口位操作應用90
2.4.3計數器應用91
2.4.4外部中斷應用91
2.4.5串列口中斷應用92
2.4.6鍵盤顯示程序93
第3章鐵電單片機VRS51L3074
3.1VRS51L3074概述104
3.1.1功能說明104
3.1.2引腳說明106
3.1.3指令系統109
3.2VRS51L3074的存儲器結構113
3.2.1內部數據存儲區114
3.2.2特殊功能寄存器區114
3.2.3外部數據存儲汪歷器組織120
3.2.4外部數據匯流排訪問123
3.2.5FRAM鐵電存儲器的使用127
3.3VRS51L3074晶元配置133
3.3.1系統時鍾配置133
3.3.2處理器工作模式控制135
3.3.3功能模塊使能控制136
3.3.4功能模塊I/O映射與優先順序137
3.4通用I/O口138
3.4.1I/O口結構139
3.4.2I/O口方向配置139
3.4.3I/O口輸入使能控制140
3.4.4I/O口鎖存器140
3.4.5I/O口驅動能力141
3.4.6I/O口狀態變化監控141
3.5定時/計數器142
3.5.1定時/計數器T0、T1143
3.5.2定時/計數器T2147
3.5.3定時器級聯150
3.5.4定時器應用常式151
3.6脈沖寬度計數器(PWC)151
3.6.1PWC模塊配置寄存器153
3.6.2PWC模塊配置操作155
3.6.3PWC模塊常式155
3.7串列口156
3.7.1串列口UART0157
3.7.2串列口UART1159
3.7.3串列通信波特率計算161
3.7.4UART0和UART1引腳映射162
3.7.5串列口常式163
3.8SPI介面166
3.8.1SPI運行控制167
3.8.2SPI配置和狀態監控168
3.8.3SPI傳輸字長171
3.8.4SPI數據寄存器172
3.8.5SPI數據輸入/輸出173
3.8.6可變位數據傳輸174
3.9I2C介面175
3.9.1I2C運行控制175
3.9.2I2C從機在線狀態檢查178
3.9.3從機ID設置與I2C高級配置180
3.9.4I2C常式181
3.10脈沖寬度調制器(PWMs)184
3.10.1PWM輸出波形控制185
3.10.2PWM模塊時鍾配置188
3.10.3PWM模塊常式188
3.10.4PWM模塊的定時器工作模式191
3.11增強型算術單元(AU)194
3.11.1算術單元控制寄存器195
3.11.2算術單元數據寄存器198
3.11.3桶式移位器200
3.11.4增強型算術單元整體結構201
3.11.5算術單元基本運算常式201
3.12看門狗定時器(WDT)202
3.12.1看門狗定時器的控制203
3.12.2採用外部時鍾的情況下WDT的復位控制204
3.12.3WDT基本配置常式204
3.13中斷系統205
3.13.1中斷系統概述205
3.13.2中斷允許控制207
3.13.3中斷源選擇208
3.13.4中斷優先順序209
3.13.5引腳變化中斷209
3.14VRS51L3074JTAG介面211
3.14.1激活JTAG介面對系統的影響211
3.14.2板級JTAG介面的實現212
3.14.3VRS51L3074調試器212
3.15Flash編程介面(FPI)212
3.15.1與FPI模塊相關的特殊功能寄存器212
3.15.2Flash存儲器讀操作215
3.15.3Flash存儲器擦除217
3.15.4Flash存儲器寫操作218
第4章LED顯示屏工作原理
4.1LED發光原理及其發展狀況、趨勢224
4.1.1LED發光原理224
4.1.2LED發展歷史及趨勢225
4.2LED顯示屏基本模塊介紹226
4.2.1光學和人眼視覺知識226
4.2.2LED器件主要參數227
4.2.3雙基色點陣LED模塊簡介228
4.3常用雙基色LED顯示屏基本控制單元229
4.3.1室內雙基色LED單元板結構介紹229
4.3.2驅動方式分析230
4.3.3室內雙基色單元板電路分析232
4.4LED顯示屏分類及亮度、灰度控制237
4.4.1LED顯示屏分類237
4.4.2LED顯示屏亮度及灰度控制理論238
4.5LED顯示屏工程應用及維護概述241
4.5.1LED顯示屏的方案設計241
4.5.2LED顯示屏的安裝243
4.5.3LED顯示屏的維修244
第5章LED顯示屏顯示數據的組織
5.1LED顯示屏控制系統對單片機的基本要求245
5.1.1LED顯示屏對單片機控制系統的基本要求245
5.1.2LED顯示屏對單片機數據處理方式的基本要求247
5.1.3指令優化對位元組處理時間的影響248
5.2LED顯示屏靜態顯示數據的組織251
5.2.1靜態顯示的LED顯示屏數據組織251
5.2.2靜態屏的滾動顯示255
5.3LED顯示屏動態顯示數據的組織258
5.3.1動態顯示的LED顯示屏數據組織258
5.3.2顯示區域中X、Y坐標與存儲單元位元組地址i、位地址j之間的關系261
5.4顯示效果與佔用顯示數據存儲器大小的關系263
5.4.1顯示效果與佔用顯示數據存儲器大小的關系263
5.4.2採用雙RAM並行輸出降低顯示數據存儲器的佔用267
5.4.3多RAM並行輸出時雙RAM並行輸出方式的擴展270
第6章基於51系列單片機的小型LED顯示屏控制系統
6.1單片機直接驅動LED顯示屏272
6.1.1顯示數據存儲在程序存儲器中272
6.1.2顯示數據存儲在擴展的外部並行數據存儲器中278
6.2利用單片機外部讀寫信號驅動LED顯示屏279
6.2.1單片機外部數據存儲器擴展279
6.2.2多個外部數據存儲器擴展280
6.3利用單片機SPI介面驅動LED顯示屏287
6.3.1SPI介面的特點287
6.3.2利用SPI介面驅動LED顯示屏288
6.4單片機直接驅動LED顯示屏應用實例291
第7章單片機擴展外部地址計數器驅動大型LED顯示屏
7.1單片機訪問外部數據存儲器時間上的限制297
7.2利用單片機多RAM技術驅動大型LED顯示屏301
7.2.1並行RAM方式301
7.2.2串列存儲器方式307
7.3利用LED顯示屏單元板排列方式驅動超長LED顯示屏308
7.3.1超長LED顯示屏面臨的問題308
7.3.2LED顯示屏的雙向排列方式308
7.3.3超長LED顯示屏的數據組織與硬體實現309
7.4利用多單片機系統驅動超大型LED顯示屏313
7.5基於DSP與FPGA的LED顯示屏控制系統的設計315
7.5.1DSP的特點及在LED顯示屏控制系統中的應用315
7.5.2基於FPGA的系統時序電路設計316
7.5.3顯示存儲器模塊設計317
7.5.4LED顯示屏分區317
7.5.5顯示存儲器掃描時序控制電路318
第8章LED顯示屏的系統軟體編程
8.1漢字字型檔的生成與使用320
8.1.1漢字編碼簡介321
8.1.2點陣漢字字型檔321
8.1.3在Windows環境下提取字模的工作原理322
8.1.4提取字模的程序設計322
8.2控制卡與PC機的協議制定324
8.2.1控制命令字約定325
8.2.2配置文本編輯326
8.2.3直接數據格式定義329
8.2.4存儲器地址位置331
8.2.5PC機端串列口通信模塊331
8.3漢字字形的提取及圖片的嵌入333
8.3.1漢字字形提取334
8.3.2圖片的嵌入339
8.4PC機對下載數據的預處理339
8.4.1LED屏顯示信息編輯及提取340
8.4.2LED顯示數據生成340
8.4.3INTER格式數據轉換342
第9章LED顯示屏單片機控制系統編程
9.1基於SPI的Flash存儲器讀寫346
9.1.1SST25系列串列Flash存儲器346
9.1.2基於51單片機SPI介面的串列Flash驅動程序350
9.2字元控制及處理程序設計359
9.2.1字元控制處理程序設計360
9.2.2字元點陣字模提取程序設計367
9.3顯示程序372
9.3.1顯示程序指令表372
9.3.2讀顯示程序指令表378
9.3.3執行顯示程序指令表381
9.3.4單場顯示程序設計384
9.4串列口通信模塊設計385
9.4.151單片機端串列口收發模塊385
9.4.251單片機端串列口擴展程序模塊388
9.5基於DS1302時鍾模塊程序設計391
9.5.1DS1302的結構及工作原理391
9.5.2DS1302的控制位元組說明391
9.5.3復位392
9.5.4數據輸入/輸出392
9.5.5DS1302的寄存器392
9.5.6DS1302在LED控制卡上的硬體電路及軟體設計393
9.6基於DS18B20溫度感測器的模塊設計395
9.6.1DS18B20的工作時序396
9.6.2DS18B20的程序設計397
第10章VRS51L3074在LED顯示屏控制系統中的應用
10.1VRS51L3074與標准51單片機的比較401
10.1.1VRS51L3074運行速度401
10.1.2VRS51L3074的高速增強型SPI介面402
10.1.3VRS51L3074的定時/計數器402
10.1.4VRS51L3074的增強型算術運算單元402
10.1.5VRS51L3074的其他部件403
10.2VRS51L3074的基本應用403
10.3VRS51L3074的RAM擴展應用407
10.4VRS51L3074擴展硬體地址計數器409
10.5VRS51L3074的擴展「雙埠」串列FRAM412
附錄AASCII碼表415
附錄BMCS51單片機常用資料416
附錄CC51中的關鍵字和常用函數425
附錄DKeilμVision3中高性能鐵電單片機(VRS51L2xxx/3xxx)的相關配置簡介435
附錄E常用晶元引腳圖440
E.1CPU440
E.2驅動晶元442
E.3其他444
附錄F非同步室內雙基色LED顯示屏故障排查簡明手冊449
附錄GLED雙基色單元板原理圖451
參考文獻455
❻ C51寫單片機程序如何插入匯編指令.
C51些單片機程序插入匯編指令的方法如下:
1、以#pragma asm開始,以#pragma endasm結束,
用pragma asm和#pragma endasm這兩個偽指令將匯編代碼包起來。
比如:
3、如果勾選橢圓圈中的兩項,這樣就可以了。