Ⅰ C51單片機串口通信中斷的問題
對於51而言,每幀產生一次中斷。接收4個位元組是分4次中斷接收完成的。51的UART模塊從串列移位寄存器接收完成後是直接放入接收緩沖的,而且接收緩沖只有一個單元。
Ⅱ 單片機 用c語言編寫 modbus rtu 通訊怎麼寫啊 主要是crc 校驗部分不知道怎麼寫 怎麼把一竄字元進行CRC計算
我剛剛寫好.跟PLC連接測試過,可以的.
/***************************************************************
CRC計算方法
1.預置1個16位的寄存器為十六進制FFFF(即全為1);稱此寄存器為CRC寄存器;
2.把第一個8位二進制數據(既通訊信息幀的第一個位元組)與16位的CRC寄存器的低
8位相異或,把結果放於CRC寄存器;
3.把CRC寄存器的內容右移一位(朝低位)用0填補最高位,並檢查右移後的移出位;
4.如果移出位為0:重復第3步(再次右移一位);
如果移出位為1:CRC寄存器與多項式A001(1010 0000 0000 0001)進行異或;
5.重復步驟3和4,直到右移8次,這樣整個8位數據全部進行了處理;
6.重復步驟2到步驟5,進行通訊信息幀下一個位元組的處理;
7.將該通訊信息幀所有位元組按上述步驟計算完成後,得到的16位CRC;
*****************************************************************/
/****************************************************************************
名稱: UART_CRC16_Work()
說明: CRC16校驗程序
參數: *CRC_Buf:數據地址
CRC_Leni:數據長度
返回: CRC_Sumx:校驗值
*****************************************************************************/
unsigned int UART_CRC16_Work(unsigned char *CRC_Buf,unsigned char CRC_Leni)
{
unsigned char i,j;
unsigned int CRC_Sumx;
CRC_Sumx=0xFFFF;
for(i=0;i<CRC_Leni;i++)
{
CRC_Sumx^=*(CRC_Buf+i);//異或
for(j=0;j<8;j++)
{
if(CRC_Sumx & 0x01)
{
CRC_Sumx>>=1;
CRC_Sumx^=0xA001;
}
else
{
CRC_Sumx>>=1;
}
}
}
return (CRC_Sumx);
}
Ⅲ 通信工程的學c語言有什麼用,只是單片機用到嗎
單片機里每個存儲單元都有自己的地址,這一章都是為了解單片機的內部原理和下一步匯編編程和混合編程做准備的
Ⅳ C51單片機多機通信C語言
單片機a,b,c.a為主機,bc為從機。a上有一個外部中斷0輸入,按第一次a的兩個LED亮500ms,再按一下,b機的兩個LED燈亮500ms,第三次按下c機的兩個LED燈亮500ms,然後周而復始。兩個數碼管分別顯示0/1/2,和abc(bc由從機反饋)
/*
主從通信基本步驟:
1.主機從機初始化為方式2或者3,從機都置SM2=1,允許中斷
2.主機置TB8=1,發送從機地址
3.所有從機均接收主機發送要定址的從機地址
4.被定址的從機確認地址後,置本機SM2=0,向主機返回地址,供主機核對
5.核對無誤後,主機向被定址的從機發送命令,通知從機接受或者發送數據。
6.本次通信結束後,主從機重置SM2=1,主機可再對其他從機定址
*/
******************************************************************
主機a:
******************************************************************
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharleddata[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x00};
ucharMode;
sbitP10=P1^0;
sbitP13=P1^3;
sbitP17=P1^7;
sbitP20=P2^0;
sbitP21=P2^1;
voidUART_init()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0xd0;
ES=1;
EX0=1;
IT0=1;//INT0下跳觸發
EA=1;
TI=0;
}
voidDelayMs(intms)
{
uchari;
while(ms--)
for(i=0;i<120;i++);
}
voidputc_to_SerialPort(ucharc)
{
SBUF=c;
while(TI==0);
TI=0;
}
voidMasterControl(unsignedcharAddr,unsignedcharComd)
{
TB8=1;
putc_to_SerialPort(Addr);
DelayMs(50);
TB8=0;
putc_to_SerialPort(Comd);
DelayMs(50);
}
Ex0_int(void)interrupt0
{
P0=leddata[Mode];
P20=0;
if(Mode==0)
{
P2=leddata[10];
P10=0;
P13=0;
DelayMs(500);
P10=1;
P13=1;
//MasterControl('b','C');
//MasterControl('c','C');
}
elseif(Mode==1)
{
P10=1;
P13=1;
MasterControl('b','O');
//MasterControl('c','C');
}
elseif(Mode==2)
{
P10=1;
P13=1;
//MasterControl('b','C');
MasterControl('c','O');
}
Mode=(Mode+1)%3;
}
com_int(void)interrupt4
{
if(RI)
{
RI=0;
if(SBUF=='b')
{
P2=leddata[11];
}
if(SBUF=='c')
{
P2=leddata[12];
}
}
}
voidmain(void)
{
P0=0x00;
P1=0xff;
P2=0x00;
UART_init();
Mode=0;
while(1);
}
******************************************************************
從機b:
******************************************************************
#include<reg51.h>
#defineucharunsignedchar
ucharRecData;
sbitP10=P1^0;
sbitP13=P1^3;
voidUART_init()
{
TMOD=0x21;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0xf0;
ES=1;
PS=1;
EA=1;
}
voidDelayMs(intms)
{
uchari;
while(ms--)
for(i=0;i<120;i++);
}
voidputc_to_SerialPort(ucharc)
{
SBUF=c;
while(TI==0);
TI=0;
}
com_int(void)interrupt4
{
if(RI)
{
RecData=SBUF;
RI=0;
if(RB8==1)//地址
{
if(RecData=='b')//是自己的地址,置SM2=0,准備接受數據
{
SM2=0;
putc_to_SerialPort('b');
}
else//不是自己的地址
{
SM2=1;
}
}
if(RB8==0)//數據
{
if(RecData=='O')
{
P10=0;
P13=0;
DelayMs(500);
P10=1;
P13=1;
}
if(RecData=='C')
{
P10=1;
P13=1;
}
SM2=1;
}
}
}
voidmain(void)
{
P0=0xff;
P1=0xff;
UART_init();
while(1);
}
******************************************************************
從機c:
******************************************************************
#include<reg51.h>
#defineucharunsignedchar
ucharRecData;
sbitP10=P1^0;
sbitP13=P1^3;
voidUART_init()
{
TMOD=0x21;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0xf0;
ES=1;
PS=1;
EA=1;
}
voidDelayMs(intms)
{
uchari;
while(ms--)
for(i=0;i<120;i++);
}
voidputc_to_SerialPort(ucharc)
{
SBUF=c;
while(TI==0);
TI=0;
}
com_int(void)interrupt4
{
if(RI)
{
RecData=SBUF;
RI=0;
if(RB8==1)//地址
{
if(RecData=='c')//是自己的地址,置SM2=0,准備接受數據
{
SM2=0;
putc_to_SerialPort('c');
}
else//不是自己的地址
{
SM2=1;
}
}
if(RB8==0)//數據
{
if(RecData=='O')
{
P10=0;
P13=0;
DelayMs(500);
P10=1;
P13=1;
SM2=1;
}
if(RecData=='C')
{
P10=1;
P13=1;
SM2=1;
}
}
}
}
voidmain(void)
{
P0=0xff;
P1=0xff;
UART_init();
while(1);
}
Ⅳ C語言51單片機串口通信程序求教
串口通訊,首先設置波特率,再設置串口模式,之後就可以收發數據了。比如:
init()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0x50;
}
send(unsignedchardat)
{
SBUF=dat;
while(TI==0);
TI==0;
}
unsignedcharrecive()
{
unsignedchardd;
if(RI)
{
dd=SBUF;
RI=0;
}
return(dd);
}
Ⅵ 請大神幫忙編寫一個單片機C語言程序,串列通信的。
這是基於STC12C5A60S2 單片機編寫的程序,應該也兼容51單片機。這里只是串口的收發,和數碼管顯示,由於我的數碼可能和你的不一樣所以需要更改。
#include<stc.h>
#define uchar unsigned char
#define uint unsigned int
//unsigned char code dofly[16]={0,0x3f,0x79,0x5e,0x07,0x7f,0x6f,0x39,0x66,0x6d,0x7d,0x7c,0x06,0x5b,0x4f,0x77};
unsigned char code dofly[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit LED=P1^2;
sbit an=P1^0; //數碼管端碼使能端
sbit wei=P1^1;//數碼管位碼使能端
uchar flag,a;
void init();
void main()
{
an=0;
P0=0x55;
an=1;
wei=0;
init();
while(1)
{
if(flag==1)
{
ES=0; //當進入中斷後,把中斷關閉
flag=0; //把標記位清零
SBUF=a; //把A的值發送出去
while(!TI); //等待數據發送完,如果沒有發送完會一直等待。當收到或發送數據TI會由硬體自動置1。
TI=0; //把TI清零
ES=1; //打開串口
}
}
}
void init() //串口寄存器的設置
{
TMOD=0x20; //設置定時器1的工作模式2
TH1=0xfd; //波特率初值
TL1=0xfd; //波特率初值
TR1=1; //打開定時器
REN=1; //串口允許位
SM0=0; //通過設置SM0和SM1定義串口工作方式1
SM1=1; //通過設置SM0和SM1定義串口工作方式1
EA=1; //打開總定時器
ES=1; //打開串口中斷
ET1=0;
}
void ser() interrupt 4 //串口中斷
{
RI=0; //關閉中斷請求,軟體把中斷請求清零
a=SBUF; //A接收數據
P0=a; //讓數碼管顯示收到的數據
flag=1; //標記位
}
首先你想法是不正確的,AD的值不能直接給數組(uchar a[8])應該先賦給一個變數AD_ DATA
發送應該是SBUF=AD_DATA ,這條語句是把AD變數的值賦給SBUF串口寄存器。
建議你先把串口調試出來在作其他的。
Ⅶ 求一個51單片機C語言程序編程
實驗內容:單片機甲、乙進行雙機串列通信,甲機通過串口控制乙機LED閃爍(如下圖所示,要求利用晶元MAX232),雙方的晶振頻率均為11.0592MHz(波特率為9600kb/s)要求:甲機按開關K1一次,發送字元「A」給乙機,點亮燈D1與D2;按開關K1兩次,發送字元「B」給乙機,點亮燈D3與D4;按開關K1三次,發送字元「C」給乙機,全部點亮;按下第四次K1,燈全滅
#include<reg51.h> /*甲機*/
sbit k=P1^0;
sbit P00=P0^0;
sbit P03=P0^3;
unsignedchari,NO;
voidmain(void) /*主函數*/
{
SCON=0x40; /*方式1隻發送,不接收*/TMOD=0x20;
TH1=0xfd; /*給定時器T1賦初值,波特率為9600*/
TL1=0xfd;
TR1=1;
k=1;
NO=0;
while(1)
{
if(k==0)
{while(k==0);
NO=(NO+1)%4;
}
switch(NO)
{case0:P0=0xff;
break;
case1:P00=0;P03=1;
SBUF='A';
while(TI==0);
TI=0;
break;
case2:P00=1;
P03=0;
SBUF='B';
while(TI==0);
TI=0;
break;
case3:P00=0;
P03=0;
SBUF='C';
while(TI==0);
TI=0;
break;
}
}
for(i=250;i>0;i--){;} //延時
}
#include<reg51.h> /*乙機*/
sbit k=P1^0;
sbit P00=P0^0;
sbit P03=P0^3;
unsignedcharNO;
voidmain() /*主函數*/
{
SCON=0x50; /*設置串口為方式3,允許接收REN=1*/
TMOD=0x20;
TH1=0xfd; /*給定時器T1賦初值,波特率為9600*/
TL1=0xfd;
TR1=1;
P0=0xff;
while(RI==0);/*檢測接收中斷標志RI,RI=0,未接收完,則循環等待*/
{RI=0;
switch(SBUF)
{case'A':P00=0;P03=1;
break;
case'B':P00=1;P03=0;
break;
case'C':P00=P03=0;
break;
}
}
}