#include reg51.h
十年的新市網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都營銷網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整新市建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)公司從事“新市網(wǎng)站設(shè)計”,“新市網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
#include intrins.h
unsigned char key_s, key_v, tmp;
char code str[] = "welcome!??\n\r";
void send_str();
bit scan_key();
void proc_key();
void delayms(unsigned char ms);
void send_char(unsigned char txd);
sbit K1 = P1^4;
main()
{
TMOD = 0x20; // 定時器1工作于8位自動重載模式, 用于產(chǎn)生波特率
TH1 = 0xFD; // 波特率9600
TL1 = 0xFD;
SCON = 0x50; // 設(shè)定串行口工作方式
PCON = 0xef; // 波特率不倍增
TR1 = 1; // 啟動定時器1
IE = 0x0; // 禁止任何中斷
while(1)
{
if(scan_key()) // 掃描按鍵
{
delayms(10); // 延時去抖動
if(scan_key()) // 再次掃描
{
key_v = key_s; // 保存鍵值
proc_key(); // 鍵處理
}
}
if(RI) // 是否有數(shù)據(jù)到來
{
RI = 0;
tmp = SBUF; // 暫存接收到的數(shù)據(jù)
P0 = tmp; // 數(shù)據(jù)傳送到P0口
send_char(tmp); // 回傳接收到的數(shù)據(jù)
}
}
}
bit scan_key()
// 掃描按鍵
{
key_s = 0x00;
key_s |= K1;
return(key_s ^ key_v);
}
void proc_key()
// 鍵處理
{
if((key_v 0x01) == 0)
{ // K1按下
send_str(); // 傳送字串"welcome!...
}
}
void send_char(unsigned char txd)
// 傳送一個字符
{
SBUF = txd;
while(!TI); // 等特數(shù)據(jù)傳送
TI = 0; // 清除數(shù)據(jù)傳送標(biāo)志
}
void send_str()
// 傳送字串
{
unsigned char i = 0;
while(str[i] != '\0')
{
SBUF = str[i];
while(!TI); // 等特數(shù)據(jù)傳送
TI = 0; // 清除數(shù)據(jù)傳送標(biāo)志
i++; // 下一個字符
}
}
void delayms(unsigned char ms)
// 延時子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i 120; i++);
}
}
拓展資料
C語言是一門通用計算機編程語言,應(yīng)用廣泛。C語言的設(shè)計目標(biāo)是提供一種能以簡易的方式編譯、處理低級存儲器、產(chǎn)生少量的機器碼以及不需要任何運行環(huán)境支持便能運行的編程語言。
盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平臺的特性,以一個標(biāo)準(zhǔn)規(guī)格寫出的C語言程序可在許多電腦平臺上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業(yè)平臺。
二十世紀(jì)八十年代,為了避免各開發(fā)廠商用的C語言語法產(chǎn)生差異,由美國國家標(biāo)準(zhǔn)局為C語言制定了一套完整的美國國家標(biāo)準(zhǔn)語法,稱為ANSI C,作為C語言最初的標(biāo)準(zhǔn)。目前2011年12月8日,國際標(biāo)準(zhǔn)化組織(ISO)和國際電工委員會(IEC)發(fā)布的C11標(biāo)準(zhǔn)是C語言的第三個官方標(biāo)準(zhǔn),也是C語言的最新標(biāo)準(zhǔn),該標(biāo)準(zhǔn)更好的支持了漢字函數(shù)名和漢字標(biāo)識符,一定程度上實現(xiàn)了漢字編程。
/*???甲機串口程序:甲機向乙機發(fā)送控制命令字符,甲機同時接收乙機發(fā)送的數(shù)字,并顯示在數(shù)碼管上。*/
#includereg51.h
#define uchar unsigned char
#define uint unsigned int
sbit LED1=P1^0;
sbit LED2=P1^3;
sbit K1=P1^7;
uchar Operation_No=0;? //操作代碼
//數(shù)碼管代碼
uchar codeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//延時
void DelayMS(uint ms)
{
uchari;
while(ms--)for(i=0;i120;i++);
}
//向串口發(fā)送字符
void Putc_to_SerialPort(uchar c)
{
SBUF=c;
while(TI==0);
TI=0;
}
//主程序
void main()
{
LED1=LED2=1;
P0=0x00;
SCON=0x50;???????? //串口模式1,允許接收
TMOD=0x20;??????? //T1工作模式2
PCON=0x00;???????? //波特率不倍增
TH1=0xfd;
TL1=0xfd;
TI=RI=0;
TR1=1;
IE=0x90;??????? //允許串口中斷
while(1)
{
DelayMS(100);
if(K1==0)????? //按下K1時選擇操作代碼0,1,2,3
{
while(K1==0);
Operation_No=(Operation_No+1)%4;
switch(Operation_No)??? //根據(jù)操作代碼發(fā)送A/B/C或停止發(fā)送
{
case0:???? Putc_to_SerialPort('X');
LED1=LED2=1;
break;
case1:???? Putc_to_SerialPort('A');
LED1=~LED1;LED2=1;
break;
case2:???? Putc_to_SerialPort('B');
LED2=~LED2;LED1=1;
break;
case3:???? Putc_to_SerialPort('C');
LED1=~LED1;LED2=LED1;
break;
}
}
}
}
//甲機串口接收中斷函數(shù)
void Serial_INT() interrupt?? 4
{
if(RI)
{
RI=0;
if(SBUF=0SBUF=9)P0=DSY_CODE[SBUF];
elseP0=0x00;
}
}
/*?乙機程序接收甲機發(fā)送字符并完成相應(yīng)動作:乙機接收到甲機發(fā)送的信號后,根據(jù)相應(yīng)信號控制LED完成不同閃爍動作。*/
#includereg51.h
#define uchar unsigned char
#define uint unsigned int
sbit LED1=P1^0;
sbit LED2=P1^3;
sbit K2=P1^7;
uchar NumX=-1;
//延時
void DelayMS(uint ms)
{
uchari;
while(ms--)for(i=0;i120;i++);
}
//主程序
void main()
{
LED1=LED2=1;
SCON=0x50;???????? //串口模式1,允許接收
TMOD=0x20;??????? //T1工作模式2
TH1=0xfd;??????????? //波特率9600
TL1=0xfd;
PCON=0x00;???????? //波特率不倍增
RI=TI=0;
TR1=1;
IE=0x90;
while(1)
{
DelayMS(100);
if(K2==0)
{
while(K2==0);
NumX=++NumX%11;?? //產(chǎn)生0~10范圍內(nèi)的數(shù)字,其中10表示關(guān)閉
SBUF=NumX;
while(TI==0);
TI=0;
}
}
}
void Serial_INT() interrupt 4
{
if(RI)????? //如收到則LED則動作
{
RI=0;
switch(SBUF)//根據(jù)所收到的不同命令字符完成不同動作
{
case'X':?? LED1=LED2=1;break;????????? //全滅
case'A':?? LED1=0;LED2=1;break;?????? //LED1亮
case'B':?? LED2=0;LED1=1;break;?????? //LED2亮
case'C':?? LED1=LED2=0;????????????????? //全亮
}
}
}
1、51單片機串行口是獨立的硬件,對其設(shè)置完之后,它就獨立工作了。如果REN=1,它會自動檢測RXD,當(dāng)它收齊了一幀數(shù)據(jù),就自動將數(shù)據(jù)放到(接收)SBUF,然后在RI置一。 CPU的中斷系統(tǒng),如果已經(jīng)開放了串口中斷,CPU就會自動轉(zhuǎn)到0023H去執(zhí)行程序。
2、例程:
#include?AT89X51.H//單片機51頭文件,存放著單片機的寄存器
unsigned?char?dat;????????//用于存儲單片機接收發(fā)送緩沖寄存器SBUF里面的內(nèi)容
sbit?gewei=P2^2;??????????//個位選通定義
sbit?shiwei=P2^3;?????????//十位選通定義
unsigned?char?code?table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0x71};
//{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,};//?0,?1,?2,?3,?4,?5,?6,?7,?8,?9
void?Delay(unsigned?int?tc)?????//延時程序
{
while(?tc?!=?0?)
{unsigned?int?i;
for(i=0;?i100;?i++);
tc--;}
}
void?LED()????//LED顯示接收到的數(shù)據(jù)
{??
shiwei=0;?
P0=~table[dat/16];?
Delay(8);?
shiwei=1;
gewei=0;??
P0=~table[dat%16];?
Delay(5);?
gewei=1;
}
void?Init_Com(void)//功能:串口初始化,波特率9600,方式1
{
TMOD?=?0x20;
PCON?=?0x00;
SCON?=?0x50;
TH1?=?0xFd;
TL1?=?0xFd;
TR1?=?1;
}
void?main()//主程序功能:實現(xiàn)接收數(shù)據(jù)并把接收到的數(shù)據(jù)原樣發(fā)送回去///////
{
Init_Com();//串口初始化
//??P1=0xf0;
while(1)
{
if?(?RI?)??????//掃描判斷是否接收到數(shù)據(jù),
{
dat?=?SBUF;//接收數(shù)據(jù)SBUF賦與dat
RI=0;???????????//RI清零。
SBUF?=?dat;//在原樣把數(shù)據(jù)發(fā)送回去
}
LED();??//顯示接收到的數(shù)據(jù)
}
}
PIC的還真沒用過,不過從C的角度講 buffer 在沒有初始化的情況下貌似就被使用了,如果編譯器使用固定地址分配給局部變量 buffer 就會出事了。把
while(buffer != 'P')
{
buffer = RCREG;
}
改為
do
{
buffer = RCREG;
}
while(buffer != 'P');
可以避免這類BUG;但愿能有點幫助 :)
你好?。?/p>
給你一個完整的串口通訊例程,已經(jīng)調(diào)試通過的!
壓縮文件內(nèi),含有一個電腦用串口程序和單片機串口程序(源碼)
還有什么問題嗎,調(diào)試通了嗎,滿意請采納
void UART_init()
{
//初始化串行口和波特率發(fā)生器
SCON =0x64; //選擇串口工作方式,打開接收允許
TMOD =0x21; //定時器1工作在方式2,定時器0工作在方式1
TH1 =0xfd; //實現(xiàn)波特率115200(系統(tǒng)時鐘11.0592MHZ)
TR1 =1; //啟動定時器T1
ET2 =1; //允許T2中斷
ES=1; //允許串行口中斷
PS=1; //設(shè)計串行口中斷優(yōu)先級
EA =1; //單片機中斷允許
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: com_interrup()串口接收中斷處理函數(shù)
// 函數(shù)功能: 接收包括起始位'S'在內(nèi)的十位數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)
//--------------------------------------------------------------------------------------------------
com_interrupt(void) interrupt 4 using 3
{
unsigned char RECEIVR_buffer;
if(RI) //處理接收中斷
{
RI=0; //清除中斷標(biāo)志位
RECEIVR_buffer=SBUF; //接收串口數(shù)據(jù)
if(point==0) //如果還沒有接收到起始位
{
if(RECEIVR_buffer=='S') //判斷是否起始標(biāo)志位
point++; //是準(zhǔn)備接收下一位
else
point=0; //不是,繼續(xù)等待起始位
}
else if(point0point10) //判斷是否接收夠十位數(shù)據(jù)
buffer[point++]=RECEIVR_buffer; //不夠,把接收到的數(shù)據(jù)放入接收緩存區(qū)
else point=0; //緩沖區(qū)已滿,清除緩存區(qū)內(nèi)數(shù)據(jù)重新接收
}
If(TI) //處理發(fā)送中斷
{
TI=0;
}
}
//