欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
大家新年好,請教一個單片機串口通信問題
[打印本頁]
作者:
as252585425
時間:
2018-2-19 18:20
標題:
大家新年好,請教一個單片機串口通信問題
我現在寫出來一個,單片機接收1個字符,用串口調試助手軟件通過串口向單片機發送數據。當發送的數據為1到8時,P1口分別對應點亮相應的發光二極管。發送其他數據,蜂鳴器會響。 注意:波特率9600 。
1,現在我是想,如果我要一次接收3個字符,分別對應控制P0-P2口的LED燈。如何寫呢?10位通信,只能有8個位是數據。是串口通信,只能一個10位接一個10位的發。怎么區分第二個是對應P1口,第三個是對應P2口呢?
2,這個一次只能點亮1個LED燈,如果我想同時點亮多個LED燈,那該怎么寫呢?
最后祝大家,新年快樂,恭喜發財,萬事如意。
這個是我寫的代碼
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar buf;
sbit beep=P2^3;
void main(void)
{
SCON=0x50; //設定串口工作方式
PCON=0x00; //波特率不倍增
TMOD=0x20; //定時器1工作于8位自動重載模式, 用于產生波特率
EA=1;
ES = 1; //允許串口中斷
TL1=0xfd;
TH1=0xfd; //波特率9600
TR1=1;
while(1);
}
/*********************************************************
串行中斷服務函數
*********************************************************/
void serial() interrupt 4
{
ES = 0; //關閉串行中斷
RI = 0; //清除串行接受標志位
buf = SBUF; //從串口緩沖區取得數據
switch(buf)
{
case 0x31: P1=0xfe;beep=1;break; //接受到1,第一個LED亮
case 0x32: P1=0xfd;beep=1;break; //接受到2,第二個LED亮
case 0x33: P1=0xfb;beep=1;break; //接受到3,第三個LED亮
case 0x34: P1=0xf7;beep=1;break; //接受到4,第四個LED亮
case 0x35: P1=0xef;beep=1;break; //接受到5,第五個LED亮
case 0x36: P1=0xdf;beep=1;break; //接受到5,第六個LED亮
case 0x37: P1=0xbf;beep=1;break; //接受到5,第七個LED亮
case 0x38: P1=0x7f;beep=1;break; //接受到5,第八個LED亮
default: beep=0;P1=0xff;break; //接受到其它數據,蜂鳴器響
}
ES = 1; //允許串口中斷
}
作者:
wulin
時間:
2018-2-20 14:56
//利用串口傳輸控制信號不是簡單的發送一幀數據,而是需要多功能的數據串,也不要把控制程序放在中斷里。
//以下是依你的程序和要求改為串口信號多功能控制,供參考。自定義協議:以此為例 "AA 55 AA 5A 59"共五位數據
//AA是數據頭,55 AA 5A 是三位有效數據,59是數據尾,是三位有效數據和的余數,依此驗證數據傳輸是否正確
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar table0[] ="OK "; //用于串口助手返回驗證
uchar table1[]="ERROR ";//用于串口助手返回驗證
uchar rec_buf[5]; //數據緩存
bit flag=0; //接收完成標志
bit sign=0; //數據驗證標志
sbit beep=P2^3;
/**********串口發送函數*************/
void SendOneByte(uchar k)
{
SBUF = k; //發送數據
while(!TI); //等待發送完成
TI = 0; //發送中斷請求標志位清0
}
void main(void)
{
uchar i,j; //臨時變量
SCON=0x50; //設定串口工作方式
PCON=0x00; //波特率不倍增
TMOD=0x20; //定時器1工作于8位自動重載模式, 用于產生波特率
TL1=0xfd;
TH1=0xfd; //波特率9600
TR1=1;
EA=1;
ES = 1; //允許串口中斷
while(1)
{/************數據解析*************/
if(flag==1) //5位數據串接收完成
{
ES=0; //關串口中斷
flag=0; //接收完成標志清0
j=rec_buf[1]+rec_buf[2]+rec_buf[3];//三位有效數據的和,溢出部分舍棄
if(rec_buf[4]==j)//驗證數據和
{
for(i=0;i<3;i++)
SendOneByte(table0[i]);//返回串口助手字符"OK"
sign=1; //數據傳輸正確
}
else
{
for(i=0;i<6;i++)
SendOneByte(table1[i]);//返回串口助手字符"ERROR"
sign=0; //數據傳輸錯誤
}
ES=1; //開串口中斷
/******控制任務*******/
if(sign==1)
{
P0=rec_buf[1];
P1=rec_buf[2];
P2=rec_buf[3];
beep=1;
}
else
{
P0=0xff;
P1=0xff;
P2=0xff;
beep=0;
}
}
}
}
/*********************************************************
串口中斷服務函數
*********************************************************/
void serial() interrupt 4
{
static uchar num=0; //靜態計數變量
RI=0; //接收中斷請求標志位清0
rec_buf[num]=SBUF; //接收到的數據串保存在緩存數組
if(rec_buf[0]==0xAA) //驗證數據頭(起始位)
{
num++;
if(num>=5)
{
flag=1; //接收完成標志置1
num=0; //計數變量清0
}
}
}
作者:
999333
時間:
2018-2-20 15:12
一次接收3個是嗎,也就是說把這個分門別類就行,比如說接收到的數據是1,就寫p0=???;如果是2就寫p2=???;用case語句就足夠了
作者:
0x00,0xff
時間:
2018-2-21 17:31
如果只是控制兩個端口的16個等的話,而且是可以一次點亮多個,如果是三幀數據,可以對著三幀數據進行編碼,將解碼函數放在外部,不必放在串口中斷內,設置一個標志位,接收到數據后,標志位置1,主函數檢測到標志位時,關閉串口中斷以防下一幀數據影響到這一幀數據的處理,并進行數據的解碼以及置位標志位,解碼并執行開關完畢后打開串口中斷,準備接收下一幀數據。
舉個例子
收到三幀數據,00 fe 01
串口接收并存入數據緩沖區后,解碼函數對第一針數據解碼,00代表開燈操作,進入開燈的函數,在開燈函數內將收到的數據按位與進入P1端口,將第三幀數據按位或進入P2口,這時,第二第三針數據中對應的0位會使對應位輸出位零,
當收到第一幀數據為ff時,進入關燈程序,第二與第三幀要按位與進入對應的端口,否則會使某些燈關不掉。
當第一幀數據為其他時,蜂鳴器響。
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1