Ⅰ 單片機串口中斷執行流程
流程是:(主程序中)發送數據―等待中斷―發送成功產生中斷―進入中斷清除TL,再次發送―中斷返回―等待中斷―發送成功產生中斷―進入中斷清除TL,再次發送。。。。循環而已。
Ⅱ 51單片機串口的原理和過程
單片機C51串口中斷接收和發送測試常式(含通信協議的實現)
通信協議:第1位元組,MSB為1,為第1位元組標志,第2位元組,MSB為0,為非第一位元組標志,其餘類推……,最後一個位元組為前幾個位元組後7位的異或校驗和。
測試方法:可以將串口調試助手的發送框寫上 95 10 20 25,並選上16進制發送,接收框選上16進制顯示,如果每發送一次就接收到95 10 20 25,說明測試成功。
//這是一個單片機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);
}
}
}
Ⅲ 單片機串口中斷問題
樓主的問題我覺得應該出在這里:該中斷函數是將接收的數據加一然後回顯,方法簡單明了,不錯。但是進入了死循環。
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
SBUF=i+1;}//中斷內再出中斷,打亂了中斷服務程序的返回。
if(TI)
{TI=0;}
}
修改的如下,希望樓主看完後明白這個是同步互斥的問題。
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
ES=0;//關串列中斷
SBUF=i+1;}//中斷內再出中斷,打亂了中斷服務程序的返回。
ES=1;//開穿行中斷
if(TI)
{TI=0;}
}
完整而完善的串口服務函數可以給樓主參考:
#include<reg51.h>
unsigned char UART_RX; //定義串口接收數據變數
unsigned char RX_flag; //定義穿行接收標記
/*********************************************************************************************
函數名:UART串口初始化函數
調 用:UART_init();
參 數:無
返回值:無
結 果:啟動UART串口接收中斷,允許串口接收,啟動T/C1產生波特率(佔用)
備 註:振盪晶體為11.0592MHz,PC串口端設置 [ 2400,8,無,1,無 ]
/**********************************************************************************************/
void UART_init (void){
EA = 1; //允許總中斷(如不使用中斷,可用//屏蔽)
ES = 1; //允許UART串口的中斷
TMOD = 0x20; //定時器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允許串口接收(SCON = 0x40 時禁止串口接收)
TH1 = 0xE8; //定時器初值高8位設置
TL1 = 0xE8; //定時器初值低8位設置
PCON = 0x80; //波特率倍頻(屏蔽本句波特率為1200)
TR1 = 1; //定時器啟動
}
/**********************************************************************************************/
/*********************************************************************************************
函數名:UART串口接收中斷處理函數
調 用:[SBUF收到數據後中斷處理]
參 數:無
返回值:無
結 果:UART串口接收到數據時產生中斷,用戶對數據進行處理(並發送回去)
備 註:過長的處理程序會影響後面數據的接收
/**********************************************************************************************/
void UART_R (void) interrupt 4 using 1{ //切換寄存器組到1
RI = 0; //令接收中斷標志位為0(軟體清零)
UART_RX = SBUF; //將接收到的數據送入變數 UART_data
RX_flag=1; //標記接收
//用戶函數內容(用戶可使用UART_data做數據處理)
//SBUF = UART_data; //將接收的數據發送回去(刪除//即生效)
//while(TI == 0); //檢查發送中斷標志位
//TI = 0; //令發送中斷標志位為0(軟體清零)
}
/**********************************************************************************************/
/*********************************************************************************************
函數名:UART串口發送函數
調 用:UART_T (?);
參 數:需要UART串口發送的數據(8位/1位元組)
返回值:無
結 果:將參數中的數據發送給UART串口,確認發送完成後退出,採用非中斷方式
備 註:
/**********************************************************************************************/
void UART_T (unsigned char UART_data){ //定義串口發送數據變數
ES=0; //禁止穿行中斷
SBUF = UART_data; //將接收的數據發送回去
while(TI == 0); //檢查發送中斷標志位
TI = 0; //令發送中斷標志位為0(軟體清零)
ES=1; //打開穿行中斷
}
/*********************************************************************************************
函數名:UART串口發送字元串函數
調 用:UART_S (?);
參 數:需要UART串口發送的數據(8位/1位元組)
返回值:無
結 果:將參數中的數據發送給UART串口,確認發送完成後退出,採用非中斷方式
備 註:
/**********************************************************************************************/
void UART_S(unsigned char *str)
{
while(1)
{
if(*str=='\0') break;
UART_T(*str++);
}
}
/*********************************************************************************************
函數名:主函數
調 用:main();
參 數:
返回值:無
結 果:
備 註:
/**********************************************************************************************/
void main()
{
unsigned char Buf_data[]={" welcome to MCU world. \n\r"};
UART_init();
UART_S(Buf_data);
while(1){
if(RX_flag==1)
{
UART_T(UART_RX);
RX_flag=0;
}
}
}
Ⅳ 51單片機串口通信不用設置IE開關嗎
你對51的串口部分了解還不夠透徹。51的串口默認是使用Timer1作為波特率發生器的,利用8位自動重載模式產生串口波特率的32或16倍頻。如果你開啟了Timer1中斷、又沒有修改串口波特率發生器的選擇,那麼由於Timer1不停進入中斷就會導致串口部分根本無法正常工作。
簡而言之,默認狀況下,串口要吃掉Timer1。牢記。
Ⅳ 怎麼用51單片機的一個串口實現與外設兩個串口通信
只有單串口的單片機如何實現與兩個串口模塊通信
--可以分時工作。
--分別和兩個串口外設,通信。
--但是,外部電路,需要好好設計。
Ⅵ 單片機 串口 中斷 C程序
void
ser_com1(void)
interrupt
5
using
3
串口中斷的優先順序雖然是
5
,但應用
interrupt
4~因為01234~~
這個與錯誤無關哈~
一般syntax
error都是標點有錯,不知你的回車處有沒有空格~~~
Ⅶ 51單片機串口通信中IE=0x90;是什麼意思
IE: EA X X ES ET1 EX1 ET0 EX0
EA:總允許位
ES:串口中斷允許位
ET1:定時計數器1中斷允許位
EX1:外部中斷1中斷允許位
ET0:定時計數器0中斷允許位
EX0:外部中斷0中斷允許位
IE化為二進制 就是 1001 0000 開總中斷和串口中斷
Ⅷ 單片機串口如何接收
在主程序中對接收到的數據串進行處理,查找幀頭、提取有效數據、進行業務判斷。
首先,要知道中斷應當盡量簡潔,所以中斷裡面只做數據接收和下標移動。
其次,要知道每幀的最大長度。幀長度要是毫無限制那緩沖區就不好開了,得採用適用性更強的緩沖技術,這里就不提了。舉例假定數據量最多10位元組,則最長幀為13位元組,可開辟16位元組緩沖區。
再次,要知道通信協議是怎麼樣的,傳輸速率如何(與單片機處理能力相比),每幀的數據之間有多少間隔,幀與幀之間有多少間隔。
間隔太短的話需要增加許多額外的處理,例如幀頭識別、幀分割,必要時又得用較大容量的循環緩沖區……這里也不提了。舉例假定幀間有足夠多的間隔時間。
Ⅸ 單片機串口通信需要用哪些寄存器
51單片機串口工作時,涉及到以下三個寄存器:
1.SCON:串列口工作寄存器
2.IE:中斷允許寄存器(如果用到中斷方式的話)
3.PCON:其中最高位SMOD與波特率有關
另外還有定時器T1在方式1,方式3時需要用到,以改變波特率。
Ⅹ 51單片機串口通信問題: 最近做一個溫度採集系統需要把採集到得溫度發送到VB上
#define UART_BUADRATE 19200//9600
#define OCS 11059200//12000000
void init_uart(void)
{
EA=0;
SCON = 0x50;
T2CON &= 0x3f; //TF2=0 EXF2=0
T2CON |= 0x30; //串口1選擇T2為波特率時鍾
T2CON &= 0xf7;//EXEN2=0
T2CON &= 0xfb;//TR2 = 0;//關閉定時器2
T2CON &= 0xfd;//定時器工作方式
T2CON &= 0xfe;//自動重載
PCON = PCON | 0x80;//SMOD=1
//baudrate = 9600;
//OCS = 22118400;
TH2 = (65536 - OCS/32/UART_BUADRATE)/256;
TL2 = (65536 - OCS/32/UART_BUADRATE)%256;
RCAP2H = (65536 - OCS/32/UART_BUADRATE)/256;
RCAP2L = (65536 - OCS/32/UART_BUADRATE)%256;
//ET2= 0;//禁止T2中斷
ES = 1;//啟動串口1
TR2 = 1;//啟動定時器2
EA=1;
}