?? serial.c
字號:
#include <reg52.h>
#define uchar unsigned char
bit receive; //接收標志
bit re_finish;//接收一串字符完成標志
sbit lck = P3^5;//HC574鎖存信號
sbit LED = P1^3;//串口通信指示
sbit addr0 = P1^4;//系統片選地址線0
sbit addr1 = P1^5;//系統片選地址線1
sbit addr2 = P1^6;//系統片選地址線2
sbit addr3 = P1^7;//系統片選地址線3
uchar i,buffer[8];//串口緩沖區
uchar cash[8]; //數碼管顯示緩沖區
uchar sbuffer,number;//發送字符個數
uchar sendFINS ; //發送完成標志
uchar copyOK , cmd_numb ;//發送緩沖區填充完成標志
//數碼管位掃描數據
uchar code scan[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//row0--row7
//數碼管數字碼表
uchar code table[18] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,//0,1,2,3,4,5
0x82,0xf8,0x80,0x90,0x88,0x83,//6,7,8,9,a,b
0xc6,0xa1,0x86,0x8e,0xbf,0xff};//c,d,e,f,-,空格
void delay(unsigned int loop); //延時函數聲明
/********************************系統初始化函數************************/
void initial(void)
{ uchar j;
SCON=0x50; //串口工作方式1,允許接收
PCON=0x80; //波特率翻倍
TCON=0;
TMOD=0x26; //T1用于串口波特率控制
TL1=0xfa; //初始化T1,波特率為9600(晶振11.0592M)
TH1=0xfa;
TR1=1; //開定時器
EA=1; //開總中斷
ES=1; //開串口中斷
copyOK = 0; //緩沖區準備好標志清零
receive = 0; //接收標志清零
re_finish = 0; //接受完成標志清零
cmd_numb = 0; //接受計數器清零
P1 = 0xb0; //RS485允許接收
for(j=0; j<8; j++) //串口緩沖區清空
buffer[j] = 17; //table[18]為空顯示
for(j=0; j<8; j++) //串口緩沖區清空
cash[j] = 17; //table[18]為空顯示
cash[0] = 15;
}
/************************向串口發送字符串*************************/
void send(void)
{
P1 = 0xf0;
if(copyOK) //串口準備好且緩沖區準備好
{
i = 0;
REN = 0; //發送過程中禁止接收數據
copyOK = 0; //清緩沖區準備好標志
SBUF = cash[i++]; //發送字符串首字符
number = 7; //置發送計數器
}
else
return; //沒準備好則返回
}
/*****************************串口中斷響應處理函數***********************/
void serial(void) interrupt 4
{ uchar k;
if(RI)//為接收中斷
{
RI=0; //清接收中斷標志
LED = ~LED; //閃串口指示LED
sbuffer = SBUF; //讀取串口緩沖區數據
if((sbuffer == 's') && (receive == 0)) //判斷是否為數據頭 ,是數據頭則準備接收
{
receive = 1; //開始接收標志
cmd_numb = 0; //清接收計數器
re_finish = 0; //清接收完成標志
}
else if(sbuffer == 'e') //判斷數據尾
{
if(cmd_numb<8)//接收到的字符少于8個
for(k=cmd_numb;k<8;k++)//則空位填空顯示
buffer[k] = 17;
re_finish = 1; //置接收完成標志
receive =0; //清接收標志
}
else if(receive){ //判斷當前是否處于接收狀態
buffer[cmd_numb++] = sbuffer-'0'; //當前字符送緩沖區
}
else //無效命令則返回
return;
}
else{
TI=0; //為單個字符發送完中斷
if(!number) //字符串發送完
{ REN = 1; //單片機允許接收
P1 = 0xbf; //RS485允許接收
}
else{ //字符串未發送完
SBUF = cash[i++]; //發送下一字符
number--; //發送字符數減一
}
}
}
/*****************************延時函數**********************/
void delay(unsigned int loop)
{ unsigned int i ; //loop 為執行空指令的次數,改變它可一改變延時時長
for(i=0;i<loop;i++); //循環執行空指令loop次,達到延時目的
}
/******************************數碼管顯示掃描*************************/
void ledscan()
{ uchar i;
for(i=0;i<8;i++){
P2 = 0xff;//關閉所有數碼管
addr3 = 0;
addr0 = 0;
addr1 = 1;
addr2 = 0;//開發板上U4(74HC574)的片選地址
P0 =table[cash[i]]; //取一行顯示數據
addr3 = 1;
addr3 = 0;//在U4的11腳(鎖存信號)產生上升沿
P2 = scan[i];//取row0--row7行掃描數據
delay(50); //延時50us
}
}
/********************************主函數****************************/
main()
{
initial();
while(1){//主循環
if(re_finish){//把串口緩沖區的內容送到顯示緩沖區
cash[0] = buffer[0];
cash[1] = buffer[1];
cash[2] = buffer[2];
cash[3] = buffer[3];
cash[4] = buffer[4];
cash[5] = buffer[5];
cash[6] = buffer[6];
cash[7] = buffer[7];
re_finish = 0;//接收完成標志
copyOK=1;//發送緩沖區填充完成標志
send(); //把顯示緩沖區的內容發送給電腦
}
ledscan(); //循環掃描數碼管
}
}
/**********************************結束****************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -