⑴ 使用MCS-51單片機的串口按工作方式1進行數據通信c語言
#include<reg51.h>
#define uchar unsiged char
uchar dat;
main()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
ES=1;
SCON=0x50;
EA=1;
TI=0;
while(1);
}
void uart_int(void) interrupt 4
{
if(RI)
{
dat=SBUF;
SBUF=dat;
while(TI==0);
TI=0;
}
}
⑵ 51單片機與uart通信
//51串口通信基本設置我不講了,網上泛濫得很,基本通信調通的基礎上通過命令來控制單片機動作可以用以下的方法,很簡單。
//串口中斷處理,接收用數組RecCmd[],調試助手每次發送數據的最後兩個字元是'\r'和'\n'
//接收一個命令完成後將接收的內容放入緩沖RecCmdBuf[]
extern uchar idata RecCmd[10],RecCmdBuf[10]; //串口接收雙緩沖,最大接收9個有效位元組,第10個是』\r『
extern bit RecCmdFlag;
void ISR_SERIAL(void) interrupt 4 using 2
{
uchar i;
if(RI) //RI接受中斷標志
{
RI = 0; //清除RI接受中斷標志
i = SBUF; //SUBF接受/發送緩沖器
SBUF= i; //RecCmd[RecPtr]; Echo Back
unReadyToSend = 1; //與另一個非echo發送程序之間的互鎖信號
if('\n' == i) //收到『\n'字元表示調試助手已經發送完成
{
i = 0;
while(('\r' != (RecCmdBuf[i] = RecCmd[i])) && i<10)
{
i++; //已接收部分放入緩沖
}
if(i) //避免調試助手發空內容,即只發'\r'和'\n'
RecCmdFlag =1; //通知主程序命令接收完成
RecPtr = 0; //准備接收新命令
}
else
{
RecCmd[RecPtr++] = i;
if(RecPtr>9)
RecPtr = 0; //超長無效命令
}
}
if(TI)
{
TI = 0; //發送中斷響應
unReadyToSend = 0;
}
}
//命令處理部分可以放在主循環里調用,命令判斷的方式非常原始,但自己測試用就無所謂
void SerialCmdHandle(void)
{
if(RecCmdFlag)
{
if('m' == RecCmdBuf[0] && 'e' == RecCmdBuf[1] && 'n' == RecCmdBuf[2] && 'u' == RecCmdBuf[3] && '\r' == RecCmdBuf[4])
ShowMenu(); //command "menu"
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 's' == RecCmdBuf[5] && '\r' == RecCmdBuf[6])
{
LedShow = Serial; //command "show s"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 'a' == RecCmdBuf[5] && 'd' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Adc; //command "show ad"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'e' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = TempCov; //command "show te"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'i' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Time; //command "show ti"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'd' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Date; //command "show td"
}
if('s' == RecCmdBuf[0] && 't' == RecCmdBuf[1] && ' ' == RecCmdBuf[2] && '\r' == RecCmdBuf[9])
{
//command "st 000012" 改變ds1302的時間 ss:mm:hh //24hour |0x80
SetClockTime((((RecCmdBuf[3]-'0')<<4) | (RecCmdBuf[4]-'0')),(((RecCmdBuf[5]-'0')<<4) | (RecCmdBuf[6]-'0')),(((RecCmdBuf[7]-'0')<<4) | (RecCmdBuf[8]-'0')));
}
if('s' == RecCmdBuf[0] && 'd' == RecCmdBuf[1] && ' ' == RecCmdBuf[2] && '\r' == RecCmdBuf[9])
{
//command "sd 011299"改變ds1302的日期 dd:mm:yy
SetClockDate((((RecCmdBuf[3]-'0')<<4) | (RecCmdBuf[4]-'0')),(((RecCmdBuf[5]-'0')<<4) | (RecCmdBuf[6]-'0')),(((RecCmdBuf[7]-'0')<<4) | (RecCmdBuf[8]-'0')));
}
LedChangeFlag = 1;
//LcdChangeByteFlag = 0 + CHANGE + SERIAL;
RecCmdFlag = 0;
}
}
//下面是一個串口輸出的menu菜單,給你參考。
void SendOneByte(uchar ch)
{
//ES = 0; //禁止發送中斷
SBUF = ch;
unReadyToSend = 1; //互鎖信號
}
void UartSendST(uchar *st, uchar len)
{
while(len > 0)
{
while(unReadyToSend);
SendOneByte(*st++);
len--;
}
}
typedef struct _menu{
uchar *item;
uchar size;
} T_Menu;
T_Menu code MAINM = {"MENU\r\n",6}, \
MENU0 = {"_____________________________________\r\n",39}, \
MENU1 = {"menu-> list this menu\r\n",23}, \
MENU2 = {"show s/ad/te/ti/td-> \r\n",19}, \
MENU3 = {"serial/ad-da/temp/time/date\r\n",29}, \
MENU4 = {"led f num-> led flash time us\r\n",31}, \
MENU5 = {"st ssmmhh->set time\r\n",21}, \
MENU6 = {"sd ddmmyy->set date\r\n",21}, \
MENU7 = {"\r\n",2}, \
MENU8 = {"\r\n",2};
void ShowMenu(void)
{
UartSendST(MAINM.item,MAINM.size);
UartSendST(MENU0.item,MENU0.size);
UartSendST(MENU1.item,MENU1.size);
UartSendST(MENU2.item,MENU2.size);
UartSendST(MENU3.item,MENU3.size);
UartSendST(MENU4.item,MENU4.size);
UartSendST(MENU5.item,MENU5.size);
UartSendST(MENU6.item,MENU6.size);
UartSendST(MENU7.item,MENU7.size);
UartSendST(MENU8.item,MENU8.size);
}
⑶ 51單片機UART通信問題
定時器1工作在自動重裝模式時,不需要軟體加以干預,就可以為UART的波特率提供連續穩定的時鍾。之所以只能用定時器1作為UART的波特率時鍾,這是由單片機內部硬體所決定的。但並不是定時器1工作在自動重裝模式時才成為UART的波特率,定時器1工作在其它模式也可以為UART提供波特率時鍾,比如工作在模式1(16位定時/計數),UART在低速率運行時就可以採用這種定時器模式,但由於這種工作模式不能自動重裝計數初值,這就需要軟體的干預,在定時器計數溢出時,通過軟體指令裝填計數初值,使定時器執行新一輪計數循環,以便為UART的波特率提供連續時鍾。以上拙見僅供參考,希望對你有幫助。
⑷ 51單片機串口發送
//這是一個單片機C51串口接收(中斷)和發送常式,可以用來測試51單片機的中斷接收
//和查詢發送,另外我覺得發送沒有必要用中斷,因為程序的開銷是一樣的
//程序編寫: 龔建偉 [email protected]
//技術主頁:http://www.gjwtech.com
//您有這方面的問題可以和我討論
#include <reg51.h>
#include <string.h>
#define INBUF_LEN 4 //數據長度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag=0;
void init_serialcomm(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80; //SMOD=1;
TH1 = 0xF4; //Baud:4800 fosc=11.0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
// TI=1;
}
//向串口發送一個字元
void send_char_com(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
//向串口發送一個字元串,strlen為該字元串長度
void send_string_com(unsigned char *str,unsigned int strlen)
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
}
//串口接收中斷函數
void serial () interrupt 4 using 3
{
if(RI)
{
unsigned char ch;
RI = 0;
ch=SBUF;
if(ch>127)
{
count3=0;
inbuf1[count3]=ch;
checksum= ch-128;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if( (count3==(INBUF_LEN-1)) && (!checksum) )
{
read_flag=1; //如果串口接收的數據達到INBUF_LEN個,且校驗沒錯,
//就置位取數標志
}
}
}
}
main()
{
init_serialcomm(); //初始化串口
while(1)
{
if(read_flag) //如果取數標志已置位,就將讀到的數從串口發出
{
read_flag=0; //取數標志清0
send_string_com(inbuf1,INBUF_LEN);
}
}
}
⑸ 用程序如何實現C51單片機之間的UART通訊
兩塊兒單片機共地,3,.1和3.0交叉連接,用串口通訊中的方式1就能實現,波特率設置的越高,你中間的傳輸線就要越短,想要加長線的長度就要中間加驅動設備,比如兩塊兒MAX232,至於匯編程序嘛,隨便找本單片機教材,攢口通訊一般都是匯編的,而方式一也是最普遍的
⑹ 51單片機UART串口通信
51單片機是對所有兼容Intel 8031指令系統的單片機的統稱。該系列單片機的始祖是Intel的8004單片機,後來隨著Flash rom技術的發展,8004單片機取得了長足的進展,成為應用最廣泛的8位單片機之一,其代表型號是ATMEL公司的AT89系列,它廣泛應用於工業測控系統之中。很多公司都有51系列的兼容機型推出,今後很長的一段時間內將佔有大量市場。51單片機是基礎入門的一個單片機,還是應用最廣泛的一種。需要注意的是51系列的單片機一般不具備自編程能力。
⑺ 51單片機UART連續發送問題
在uart_send(i);後面加一個短延時看看。
再看一下你的晶振是不是11.0592MHz。
ES = 1;改成ES =0;
⑻ 51單片機通過串口實現數據的發送與接收程序
串口收發,要有通信協議。也就是什麼時候開始接收,接收到指令後,轉發什麼數據。這個要知道,才可以寫。而且使用不同的51單片機,其內部寄存器配置是不同的。
一般來說,過程如下:
1,配置串口參數、波特率等,開啟串口中斷;
void Init_UART()
{
}
2,中斷函數里寫中斷響應函數,根據接收的指令或者數據,執行相應的動作;
程序一般為:
void UART_ISR() interrupt x using y
{
;串口中斷處理函數
}
x - 單片機的C51中斷號
y - 指定使用的當前工作寄存器組號(0-3 PSW中的RS0,RS1組合)
3,主程序
int main(void)
{
Init_UART();
while(1)
{
;//數據發送函數
}
}
⑼ 51單片機和電腦的藍牙通信 ,用uart串口
1 電腦端買個藍牙適配器就可以了,注意要和你底層藍牙晶元的通信協議要一致;
2 買個藍牙晶元了, BC41B143A藍牙晶元,該晶元支持串口控制的,
要想與BC41B143A藍牙晶元通信了,購買的藍牙適配器必須是BT2.0+EDR
⑽ 51單片機內置uart硬體
51內置UART是硬體的,IO不能變化。如果你不想使用P3.0、P3.1,就只能在其它IO上通過程序來模擬UART了。