|
STC15系列單片機(jī)RS-485通訊例程
單片機(jī)源程序如下:
- #include <uart.h>
- sbit bitCtrl_485Eable = P1^3;//
- sbit bitCtrl_485_2Eable = P7^3;//
- xdata unsigned char mod_comd[9]={0x01,0x04,0x75,0x31,0x02,0x00,0x00,0x08,0x09};
- unsigned char freq = 0;
-
- /****************************************************************************************/
- // unsigned char MyDeviceAddr _at_ 0x06000;
- // unsigned char PODeviceAddr _at_ 0x05999;
- unsigned char MyDeviceAddr;
- unsigned char PODeviceAddr;
- /*********************************
- 串口1變量定義
- **********************************/
- bit busy1 = 0;
- xdata unsigned char u8Uart1TxBuffer[USART1_TX_BUFFER_SIZE];
- xdata unsigned char u8Uart1RxBuffer[USART1_RX_BUFFER_SIZE];
- unsigned char u8Rx1Head = 0;
- unsigned char u8Rx1Tail = 0;
- unsigned char u8Tx1Head = 0;
- unsigned char u8Tx1Tail = 0;
- unsigned char mdbs1_stat = 0;
- unsigned char mdbs1_len = 0;
- unsigned char mdbs1_cnt = 0;
- unsigned char mdbs1_maxlen = 0;
- xdata unsigned char mdbs1_Rxbuf[16];
- xdata unsigned char mdbs1_Txbuf[16];
- unsigned char mdbs1_pos = 0;
- unsigned char mdbs1_timerflag = 0;
- unsigned char mdbs1_overtime = 0;
- unsigned char mdbs1_data_len = 0;
- /****************************************************************************************/
- /****************************************************************************************/
-
- /*********************************
- 串口2變量定義
- **********************************/
- bit busy2 = 0;
- xdata unsigned char u8Uart2TxBuffer[USART2_TX_BUFFER_SIZE];
- xdata unsigned char u8Uart2RxBuffer[USART2_RX_BUFFER_SIZE];
- unsigned char u8Rx2Head = 0;
- unsigned char u8Rx2Tail = 0;
- unsigned char u8Tx2Head = 0;
- unsigned char u8Tx2Tail = 0;
- unsigned char mdbs2_stat = 0;
- unsigned char mdbs2_len = 0;
- unsigned char mdbs2_cnt = 0;
- unsigned char mdbs2_maxlen = 0;
- xdata unsigned char mdbs2_Rxbuf[16];
- xdata unsigned char mdbs2_Txbuf[16];
- unsigned char mdbs2_pos = 0;
- unsigned char mdbs2_timerflag = 0;
- unsigned char mdbs2_overtime = 0;
- unsigned char mdbs2_data_len = 0;
- /****************************************************************************************/
- /*定時(shí)器0初始化,采用16位自動重裝技術(shù)模式*/
- void Timer0Init(void) //10毫秒@11.0592MHz //16位重裝計(jì)數(shù)器
- {
- AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
-
- TL0 = -(FOSC/12/100); //設(shè)置定時(shí)初值
- TH0 = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)初值
- // RL_TH0
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
- Timer0_InterruptFirst();
- ET0 = 1; //enable timer0 interrupt
- }
- /***定時(shí)器0中斷服務(wù)函數(shù)**/
- void tm0_isr() interrupt 1 using 1
- {
-
- TF0 = 0; //清除TF0標(biāo)志
- TL0 = -(FOSC/12/100); //設(shè)置定時(shí)初值
- TH0 = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)初值
-
- ++freq;
-
- }
- /************************************************************************/
- //8位數(shù)據(jù) 波特率可變 無奇偶檢驗(yàn)位 1位起始位 1位停止位
- //使用定時(shí)器1作為波特率發(fā)生器
- void Uart1Init(void) //9600bps@11.0592MHz
- {
- PCON &= 0x3F; //波特率不倍速
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR &= 0xBF; //定時(shí)器1時(shí)鐘為Fosc/12,即12T 傳統(tǒng)51速度
- AUXR &= 0xFE; //串口1選擇定時(shí)器1為波特率發(fā)生器
- // AUXR |=0X01; //串口1選擇定時(shí)器2為波特率發(fā)生器
- TMOD &= 0x0F; //清除定時(shí)器1模式位
- TMOD |= 0x20; //設(shè)定定時(shí)器1為8位自動重裝方式
- // TMOD &= 0xF0; //清除定時(shí)器2模式位
- // TMOD |= 0x02; //設(shè)定定時(shí)器2為8位自動重裝方式
- TL1 = -(FOSC/12/32/BAUD); //設(shè)定定時(shí)初值
- TH1 = -(FOSC/12/32/BAUD); //設(shè)定定時(shí)器重裝值
- /*****
-
- 定時(shí)器2工作方式為固定16位自動重裝載 裝在值需重新計(jì)算
- */
- // T2L = -(FOSC/12/32/BAUD); //設(shè)定定時(shí)初值
- // T2H = -(FOSC/12/32/BAUD); //設(shè)定定時(shí)器重裝值
- ET1 = 0; //禁止定時(shí)器1中斷
- TR1 = 1; //啟動定時(shí)器1
- // S1_USE_P36P37(); //定義串口1管腳
- UART1_InterruptFirst(); //中斷優(yōu)先級設(shè)定
- ES = 1; //????????
- bitCtrl_485Eable=0;
- }
- /****************** *****************************************************/
- /*************串口2初始化************/
- /************************************************************************/
- //#define S3_Int_en() IE2 |= 8
- void Uart2Init(void) //10毫秒@11.0592MHz
- {
- /*
- T2MOD = 0; //初始化模式寄存器
- T2CON = 0; //初始化控制寄存器
- TL2 = -(FOSC/12/100); //設(shè)置定時(shí)初值
- TH2 = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)初值
- RCAP2L = -(FOSC/12/100); //設(shè)置定時(shí)重載值
- RCAP2H = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)重載值
- TR2 = 1; //定時(shí)器2開始計(jì)時(shí)
- ET2 = 1; //enable timer2 interrupt
- */
-
- // Timer2_12T();
- // Timer2_AsTimer();
- // T2L = -(FOSC/12/100); //設(shè)置定時(shí)初值
- // T2H = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)初值
- // Timer2_Run();
- // Timer2_InterruptEnable();
- //Timer2_InterruptDisable();
-
- S2CON = 0x50;
- Timer2_12T();
- T2L = (65536-(FOSC/4/12/BAUD));
- T2H = (65536-(FOSC/4/12/BAUD))>> 8;
- Timer2_Run();
- Timer2_InterruptDisable();
- // S2_USE_P10P11();//使用默認(rèn)端口
- S2_Int_en(); //中斷允許
-
- // S3CON = 0x10;
- // Timer2_12T();
- // T2L = -(FOSC/12/4/BAUD);
- // T2H = -(FOSC/12/4/BAUD) >> 8;
- // Timer2_Run();
- // Timer2_InterruptDisable();
- // S3_USE_P50P51();
- // S3_Int_en();
- bitCtrl_485_2Eable = 0;
-
- InternalRAM_enable(); ////禁止外部XRAM,允許使用內(nèi)部1024RAM
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /**串口1中斷服務(wù)函數(shù)!。。。。。。。。。。。。!
- 。。。。。。。。。。!*/
- /*******************************
- 接收數(shù)據(jù)緩存區(qū)滿時(shí),丟棄接收到的數(shù)據(jù),數(shù)據(jù)處理后釋放數(shù)據(jù)緩存區(qū)
- ********************************/
- void Uart1_Isr() interrupt 4 using 2
- {
- // EA = 0;
- if (RI==1)
- {
- RI = 0; //Clear receive interrupt flag
-
- if(u8Rx1Head+1 != u8Rx1Tail)
- {
- u8Uart1RxBuffer[u8Rx1Head++] = SBUF;
- u8Rx1Head &= USART1_RX_BUFFER_MASK;
- }
- }
- if (TI==1)
- {
- TI=0; //Clear transmit interrupt flag
- busy1 = 0; //Clear transmit busy flag
- if(u8Tx1Head != u8Tx1Tail)
- {
- bitCtrl_485Eable =1;
- SBUF = u8Uart1TxBuffer[u8Tx1Tail++];
- u8Tx1Tail &= USART1_TX_BUFFER_MASK;
- }
- else
- {
- bitCtrl_485Eable =0;
- }
- }
- // EA = 1;
- }
- /********串口2中斷服務(wù)函數(shù)******/
- /*******************************
- 接收數(shù)據(jù)緩存區(qū)滿時(shí),丟棄接收到的數(shù)據(jù),數(shù)據(jù)處理后釋放數(shù)據(jù)緩存區(qū)
- ********************************/
- #define S2RI 0x01
- #define S2TI 0x02
- void Uart2_Isr() interrupt 8 using 2
- {
- // EA = 0;
- if (S2CON&S2RI)
- {
- S2CON &= ~S2RI; //Clear receive interrupt flag
-
- if(u8Rx2Head+1 != u8Rx2Tail)
- {
- u8Uart2RxBuffer[u8Rx2Head++] = S2BUF;
- u8Rx2Head &= USART2_RX_BUFFER_MASK;
- }
- }
- if (S2CON&S2TI)
- {
- S2CON &= ~S2TI; //Clear transmit interrupt flag
- busy2 = 0; //Clear transmit busy flag
- if(u8Tx2Head != u8Tx2Tail)
- {
- bitCtrl_485_2Eable = 1;
- S2BUF = u8Uart2TxBuffer[u8Tx2Tail++];
- u8Tx2Tail &= USART2_TX_BUFFER_MASK;
- }
- else
- {
- bitCtrl_485_2Eable = 0;
- }
- }
- // EA = 1;
- }
- /********************************************************************************************/
- /*******讀串口1緩沖區(qū)1字節(jié)函數(shù)********************************************************
- 讀取一個(gè)字節(jié)的接收緩存數(shù)據(jù) ,釋放一個(gè)字節(jié)的緩存空間 讀取的數(shù)據(jù)存放在*pdat
- 返回0,表示緩存區(qū)有未讀數(shù)據(jù)
- 返回-1,表示緩存區(qū)沒有未讀數(shù)據(jù)
- ****************************/
- BYTE Recv1Data(BYTE *pdat)
- {
- if(u8Rx1Head != u8Rx1Tail) //有未處理數(shù)據(jù)
- {
- *pdat = u8Uart1RxBuffer[u8Rx1Tail++];
- u8Rx1Tail &= USART1_RX_BUFFER_MASK;
- return 0;
- }
- return -1;
- }
- /****************************************************************************************/
- /********************************************************************************************/
- /**********讀串口2緩沖區(qū)1字節(jié)函數(shù)*****************************************************
- 讀取一個(gè)字節(jié)的接收緩存數(shù)據(jù) ,釋放一個(gè)字節(jié)的緩存空間 讀取的數(shù)據(jù)存放在*pdat
- 返回0,表示緩存區(qū)有未讀數(shù)據(jù)
- 返回-1,表示緩存區(qū)沒有未讀數(shù)據(jù)
- ****************************/
- BYTE Recv2Data(BYTE *pdat)
- {
- if(u8Rx2Head != u8Rx2Tail) //有未處理數(shù)據(jù)
- {
- *pdat = u8Uart2RxBuffer[u8Rx2Tail++];
- u8Rx2Tail &= USART2_RX_BUFFER_MASK;
- return 0;
- }
- return -1;
- }
- /****************************************************************************************/
- /* Send a byte data to UART
- Input: dat (data to be sent)
- Output:None
- 串口1發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
- u8UartTxBuffer 用于發(fā)送數(shù)據(jù)的緩存 防止數(shù)據(jù)未及時(shí)發(fā)送時(shí)的數(shù)據(jù)堆積
- ----------------------------*/
-
- BYTE Send1Data(BYTE dat)
- {
- if((u8Tx1Head == u8Tx1Tail) && (0 == busy1))
- {
- busy1 = 1;
- bitCtrl_485Eable =1;
-
- // S3BUF = dat;
- // S2BUF = dat;
- SBUF = dat;
- return 0;
- }
- if(u8Tx1Head+1 == u8Tx1Tail)
- {
- return -1; // full
- }
- u8Uart1TxBuffer[u8Tx1Head++] = dat; //如果發(fā)送繁忙 則數(shù)據(jù)保存在發(fā)送緩存區(qū)
- u8Tx1Head &= USART1_TX_BUFFER_MASK;
- return 1;
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /* Send a byte data to UART
- Input: dat (data to be sent)
- Output:None
- 串口2發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
- u8UartTxBuffer 用于發(fā)送數(shù)據(jù)的緩存 防止數(shù)據(jù)未及時(shí)發(fā)送時(shí)的數(shù)據(jù)堆積
- ----------------------------*/
- BYTE Send2Data(BYTE dat)
- {
- if((u8Tx2Head == u8Tx2Tail) && (0 == busy2))
- {
- busy2 = 1;
- bitCtrl_485_2Eable = 1;
- // S3BUF = dat;
- S2BUF = dat;
- // SBUF = dat;
- return 0;
- }
- if(u8Tx2Head+1 == u8Tx2Tail)
- {
- return -1; // full
- }
- u8Uart2TxBuffer[u8Tx2Head++] = dat; //如果發(fā)送繁忙 則數(shù)據(jù)保存在發(fā)送緩存區(qū)
- u8Tx2Head &= USART2_TX_BUFFER_MASK;
- return 1;
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /****************************************
- 從串口1數(shù)據(jù)緩存區(qū)讀取數(shù)據(jù)函數(shù)
- 讀取數(shù)據(jù)緩存區(qū)數(shù)據(jù),釋放緩存空間 讀取的數(shù)據(jù)保存在mdbs_Rxbuf中!
- 并判斷接收數(shù)據(jù) 的有效性 (本地地址校驗(yàn),讀寫位校驗(yàn),數(shù)據(jù)長度校驗(yàn),CRC校驗(yàn))
- 返回0,表示已接收完成一組有效數(shù)據(jù)
- 返回-1,表示,緩存區(qū)沒有數(shù)據(jù)或數(shù)據(jù)不完整! 或與本機(jī)地址不匹配
- !!!如果緩存中有數(shù)據(jù),單數(shù)據(jù)不完整,則把已有數(shù)據(jù)保存在 mdbs_Rxbuf中,下次進(jìn)入此函數(shù),數(shù)據(jù)繼續(xù)保存
- mdbs1_Rxbuf[] 接收數(shù)據(jù)存儲區(qū)
- mdbs1_len 接收數(shù)據(jù)長度
- mdbs1_maxlen 接收指令數(shù)據(jù)區(qū)的長度
- mdbs1_stat 接收狀態(tài)
- mdbs1_pos 數(shù)據(jù)存儲地址
- mdbs1_overtime 接收超時(shí)標(biāo)志
- mdbs1_timerflag 連續(xù)接收標(biāo)志
- freq 時(shí)鐘節(jié)拍
- 如果中間有數(shù)據(jù)錯(cuò)誤,則重新尋找數(shù)據(jù)開始位置!!
- ************************************************/
- unsigned char link_recv1_pkt(void)
- {
- unsigned char u8dat;
- if(mdbs1_timerflag)
- {
- if(freq - mdbs1_overtime >= 10)
- {
- Link1ClearState();
- }
- }
- while(0 == Recv1Data(&u8dat))//
- {
- switch(mdbs1_stat) //初次進(jìn)入 mdbs_stat=0
- {
- case 0:
- {
- if(u8dat > 256) //地址不能大于247? 255?
- {
- break;
- }
- if(PODeviceAddr!=u8dat) return -1; //不是目標(biāo)地址返回-1
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_stat = 1;
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
-
- } break;
- case 1: //功能碼
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- if((READ_INPUT == u8dat)||(WRITE_INPUT==u8dat))
- {
- mdbs1_stat = 2;
- //mdbs_cnt = 0;
- //mdbs_maxlen = 4;
-
- }
- else
- {
- Link1ClearState();
- break;
- }
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
- } break;
- case 2: //標(biāo)識碼高字節(jié),不做處理直接保存
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_stat = 3;
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
- } break;
- case 3: //標(biāo)識碼底字節(jié),不做處理直接保存
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_stat = 4;
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
-
- } break;
-
- case 4: //數(shù)據(jù)長度
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_cnt++;
- //if(mdbs_cnt >= mdbs_maxlen)
- //{
- mdbs1_stat = 5;
- mdbs1_cnt = 0;
- mdbs1_maxlen = u8dat;
- if(u8dat==0) //如果數(shù)據(jù)長度為0 只剩下CRC校驗(yàn)數(shù)據(jù)
- {
- mdbs1_stat = 100;
- mdbs1_cnt = 0;
- mdbs1_maxlen = 2;
- }
- //}
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
-
- } break;
- case 5: //數(shù)據(jù)長度不為0,繼續(xù)接收有效數(shù)據(jù)
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_cnt++;
- if(mdbs1_cnt >= mdbs1_maxlen)
- {
- mdbs1_stat = 100;
- mdbs1_cnt = 0;
- mdbs1_maxlen = 2;
- }
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
- } break;
-
- case 100: //CRC校驗(yàn)位
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_cnt++;
- if(mdbs1_cnt >= mdbs1_maxlen)
- {
- mdbs1_timerflag = 0;
- mdbs1_data_len = mdbs1_len;
- if((CRC16(mdbs1_Rxbuf, mdbs1_len) == 0) && (PODeviceAddr == mdbs1_Rxbuf[0]))
- {
- Link1ClearState();
- return 0;
- }
- Link1ClearState();
- }
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
- } break;
- default:
- Link1ClearState();
- break;
- }
- }
- return -1;
- }
- /****************************************************************************************/
- /****************************************
- 從串口2數(shù)據(jù)緩存區(qū)讀取數(shù)據(jù)函數(shù)
- 讀取數(shù)據(jù)緩存區(qū)數(shù)據(jù),釋放緩存空間 讀取的數(shù)據(jù)保存在mdbs2_Rxbuf中!!
- 并判斷接收數(shù)據(jù) 的有效性 (本地地址校驗(yàn),讀寫位校驗(yàn),數(shù)據(jù)長度校驗(yàn),CRC校驗(yàn))
- 返回0,表示已接收完成一組有效數(shù)據(jù)
- 返回-1,表示,緩存區(qū)沒有數(shù)據(jù)或數(shù)據(jù)不完整! 或與本機(jī)地址不匹配
- !!!如果緩存中有數(shù)據(jù),單數(shù)據(jù)不完整,則把已有數(shù)據(jù)保存在 mdbs_Rxbuf中,下次進(jìn)入此函數(shù),數(shù)據(jù)繼續(xù)保存
- mdbs2_Rxbuf[] 接收數(shù)據(jù)存儲區(qū)
- mdbs2_len 接收數(shù)據(jù)長度
- mdbs2_maxlen 接收指令數(shù)據(jù)區(qū)的長度
- mdbs2_stat 接收狀態(tài)
- mdbs2_pos 數(shù)據(jù)存儲地址
- mdbs2_overtime 接收超時(shí)標(biāo)志
- mdbs2_timerflag 連續(xù)接收標(biāo)志
- freq 時(shí)鐘節(jié)拍
- 如果中間有數(shù)據(jù)錯(cuò)誤,則重新尋找數(shù)據(jù)開始位置。!
- ************************************************/
- unsigned char link_recv2_pkt(void)
- {
- unsigned char u8dat;
- if(mdbs2_timerflag)
- {
- if(freq - mdbs2_overtime >= 10)
- {
- Link2ClearState();
- }
- }
- while(0 == Recv2Data(&u8dat))//
- {
- switch(mdbs2_stat) //初次進(jìn)入 mdbs_stat=0
- {
- case 0:
- {
- if(u8dat > 256) //地址不能大于247? 255?
- {
- break;
- }
- if(MyDeviceAddr!=u8dat) return -1; //不是目標(biāo)地址返回-1
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_stat = 1;
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 1: //功能碼
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- if((READ_INPUT == u8dat)||(WRITE_INPUT==u8dat))
- {
- mdbs2_stat = 2;
- //mdbs_cnt = 0;
- //mdbs_maxlen = 4;
- }
- else
- {
- Link2ClearState();
- break;
- }
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 2: //標(biāo)識碼高字節(jié),不做處理直接保存
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_stat = 3;
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 3: //標(biāo)識碼底字節(jié),不做處理直接保存
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_stat = 4;
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
-
- case 4: //數(shù)據(jù)長度
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_cnt++;
- //if(mdbs_cnt >= mdbs_maxlen)
- //{
- mdbs2_stat = 5;
- mdbs2_cnt = 0;
- mdbs2_maxlen = u8dat;
- if(u8dat==0) //如果數(shù)據(jù)長度為0 只剩下CRC校驗(yàn)數(shù)據(jù)
- {
- mdbs2_stat = 100;
- mdbs2_cnt = 0;
- mdbs2_maxlen = 2;
- }
- //}
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 5: //數(shù)據(jù)長度不為0,繼續(xù)接收有效數(shù)據(jù)
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_cnt++;
- if(mdbs2_cnt >= mdbs2_maxlen)
- {
- mdbs2_stat = 100;
- mdbs2_cnt = 0;
- mdbs2_maxlen = 2;
- }
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
-
- case 100: //CRC校驗(yàn)位
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_cnt++;
- if(mdbs2_cnt >= mdbs2_maxlen)
- {
- mdbs2_timerflag = 0;
- mdbs2_data_len = mdbs2_len;
- if((CRC16(mdbs2_Rxbuf, mdbs2_len) == 0) && (MyDeviceAddr == mdbs2_Rxbuf[0]))
- {
- Link2ClearState();
- return 0;
- }
- Link2ClearState();
- }
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- default:
- Link2ClearState();
- break;
- }
- }
- return -1;
- }
- /******************************/
- /**************************************************/
- /*****串口1發(fā)送數(shù)據(jù)函數(shù)***********/
- /*******發(fā)送指定長度的數(shù)據(jù)*****/
- void link1_send_pkt(unsigned char *buf, unsigned char len)
- {
- unsigned char i,k;
- for(i=0; i<len; i++)
- {
- k = Send1Data(buf[i]);
- }
- }
- /****************************************************************************************/
- /*****串口2發(fā)送數(shù)據(jù)函數(shù)***********/
- /*******發(fā)送指定長度的數(shù)據(jù)*****/
- void link2_send_pkt(unsigned char *buf, unsigned char len)
- {
- unsigned char i,k;
- for(i=0; i<len; i++)
- {
- k = Send2Data(buf[i]);
- }
- }
- /*****串口2發(fā)送數(shù)據(jù)函數(shù)
- 對指定長度的數(shù)據(jù)加CRC校驗(yàn),并發(fā)送
- *********//*(發(fā)送串口1接收的的數(shù)據(jù))*/
- void svr1_msg(unsigned char *command_buf,unsigned char sentlen)
- {
- unsigned int crc;
- if(sentlen < 4) //指令長度不應(yīng)小于4,否則是無效數(shù)據(jù)
- {
- return;
- }
- // if(0 == sentlen)return;
- crc = CRC16(command_buf,sentlen);
- command_buf[sentlen]=crc>>8;
- sentlen++;
- command_buf[sentlen]=crc;
- sentlen++;
- link1_send_pkt(command_buf,sentlen);
- }
- /******************************************************************************/
- /*****串口2發(fā)送數(shù)據(jù)函數(shù)
- 對指定長度的數(shù)據(jù)加CRC校驗(yàn),并發(fā)送
- *********//*(發(fā)送串口1接收的的數(shù)據(jù))*/
- void svr2_msg(unsigned char *command_buf,unsigned char sentlen)
- {
- unsigned int crc;
- if(sentlen < 4) //指令長度不應(yīng)小于4,否則是無效數(shù)據(jù)
- {
- return;
- }
- // if(0 == sentlen)return;
- crc = CRC16(command_buf,sentlen);
- command_buf[sentlen]=crc>>8;
- sentlen++;
- command_buf[sentlen]=crc;
- sentlen++;
- link2_send_pkt(command_buf,sentlen);
- }
- /*16位CRC校驗(yàn)表*/
- code const unsigned char auchCRCHi[]={
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40
- };
- code const unsigned char auchCRCLo[]={
- 0x00,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06,0x07,0xc7,0x05,0xc5,0xc4,0x04,
- 0xcc,0x0c,0x0d,0xcd,0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09,0x08,0xc8,
- 0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a,0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,
- 0x14,0xd4,0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3,0x11,0xd1,0xd0,0x10,
- 0xf0,0x30,0x31,0xf1,0x33,0xf3,0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4,
- 0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a,0x3b,0xfb,0x39,0xf9,0xf8,0x38,
- 0x28,0xe8,0xe9,0x29,0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed,0xec,0x2c,
- 0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26,0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,
- 0xa0,0x60,0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67,0xa5,0x65,0x64,0xa4,
- 0x6c,0xac,0xad,0x6d,0xaf,0x6f,0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68,
- 0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e,0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,
- 0xb4,0x74,0x75,0xb5,0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71,0x70,0xb0,
- 0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
- 0x9c,0x5c,0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b,0x99,0x59,0x58,0x98,
- 0x88,0x48,0x49,0x89,0x4b,0x8b,0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,
- 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40
- };
- /****************************************************************************************/
- /*----------------------------
- ***********************************************/
- /*LRC校驗(yàn)子程序
- unsigned char LRC(unsigned char *auchMsg, unsigned char usDataLen)
- {
- unsigned char uchLRC = 0;
- while (usDataLen--) { uchLRC += *auchMsg++ ; }
- // return ((uint8)(~uchLRC+1));
- return ((unsigned char)(-((char)uchLRC)));
- }*/
- /*16位CRC校驗(yàn)子程序*/
- unsigned int CRC16(unsigned char* puchMsg, unsigned char usDataLen)
- {
- unsigned char uchCRCHi=0xff;
- unsigned char uchCRCLo=0xff;
- unsigned char uIndex;
- while(usDataLen--)
- {
- uIndex=uchCRCHi^*(puchMsg++);
- uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
- uchCRCLo=auchCRCLo[uIndex];
- }
- return uchCRCHi<<8|uchCRCLo;
- }
- //
- //void Timer0Init(void) //10毫秒@11.0592MHz
- //{
- // AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
- // TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- // //TMOD |= 0x01; //設(shè)置定時(shí)器模式
- // TL0 = -(FOSC/12/100); //設(shè)置定時(shí)初值
- // TH0 = -(FOSC/12/100) >> 8; //設(shè)置定時(shí)初值
- // TF0 = 0; //清除TF0標(biāo)志
- // TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
- // Timer0_InterruptFirst();
- // ET0 = 1; //enable timer0 interrupt
- //}
- /********************************************\
- /****************************************************************************************/
- /****************************************************************************************/
- /*
- */
- unsigned char MODbus_flag=0;//接收到指令標(biāo)志
- unsigned long int MODbus_flag_time=0;
- unsigned long int MODbus_flag_Rtime=0;
- unsigned int MODbus_flag2=0;
- void Modbus_task(void)
- {
-
- unsigned int crc1;
- unsigned char i;
- if(0 == link_recv2_pkt()) //串口2接收到有效命令
- {
- for(i=0;i<16;i++)
- {
- mdbs1_Txbuf[i]=mdbs2_Rxbuf[i];
-
- }
- mdbs1_Txbuf[0]=PODeviceAddr; //本機(jī)地址改為目標(biāo)地址
- svr1_msg(mdbs1_Txbuf, mdbs2_data_len-2) ; //發(fā)送更改后的數(shù)據(jù) //svr1_msg只能發(fā)送1ci?
- MODbus_flag=1;
- }
- if(MODbus_flag==1)
- {
-
- MODbus_flag_time++;
- if(0==link_recv1_pkt()) //串口2接收應(yīng)答 進(jìn)行數(shù)據(jù)校驗(yàn) 存儲
- {
-
- for(i=0;i<16;i++)
- {
- mdbs2_Txbuf[i]=mdbs1_Rxbuf[i];
-
- }
- mdbs2_Txbuf[0]= MyDeviceAddr; //本機(jī)地址改為目標(biāo)地址
-
- svr2_msg(mdbs2_Txbuf, mdbs1_data_len-2) ; //發(fā)送更改后的數(shù)據(jù)
-
- MODbus_flag=0;
- MODbus_flag_time=0;
- }
- else if(MODbus_flag_time>50000)
- {
- svr1_msg(mdbs1_Txbuf, mdbs2_data_len-2) ;
- // svr2_msg(mdbs1_Rxbuf, mdbs1_data_len-2) ; //chongxin發(fā)送更改后的數(shù)據(jù)
- MODbus_flag_time=0;
- }
- }
- else
- {
- MODbus_flag_Rtime++;
- if(MODbus_flag_Rtime%500==0)
- {
- bitCtrl_485Eable = 1;
- mod_comd[0]=PODeviceAddr;
- crc1 = CRC16(mod_comd,7);
- mod_comd[7]=crc1>>8;
- mod_comd[8]=crc1;
- link1_send_pkt(mod_comd,9);
- MODbus_flag2=1;
- MODbus_flag_Rtime=0;
- }
- if(MODbus_flag2==1)
- {
- Delay_nMS(10);
- bitCtrl_485Eable = 0;
- delay(20);
- if(0==link_recv1_pkt())
- {
- // TM_CloseAllDisplay();
- DisplayTem(mdbs1_Rxbuf[5],mdbs1_Rxbuf[6]) ;//濕度
- DisplayRH(mdbs1_Rxbuf[7],mdbs1_Rxbuf[8]) ;//溫度
- MODbus_flag2=0;
- MODbus_flag_time=0;
- }
-
- else
- {
- MODbus_flag_time++;
- if(MODbus_flag_time>2000)
- {
- MODbus_flag_time=0;
- TM_OpenAllDisplay();
-
- }
- }
- }
- }
- }
- /*****************************************************************************************/
- /**根據(jù)modbus1接收區(qū)的數(shù)據(jù)指令,賦值modbus的發(fā)送區(qū)數(shù)據(jù)***/
- /**返回指令長度***/
- /*data_num接收區(qū)指令的數(shù)據(jù)長度
- ack_num 發(fā)送區(qū)的指令長度
- data_start 接收區(qū)標(biāo)識碼
- /****************************************************************************************/
- /*
- unsigned int modbus_data(unsigned char *command_buf, unsigned char *ack_buf)
- {
- unsigned int data_start;
- unsigned char data_num;
- unsigned char ack_num;
- unsigned char tempdata;
- switch(command_buf[1])
- {
- case READ_INPUT: //讀輸入寄存器值讀3區(qū)
- ack_buf[0]=command_buf[0];
- ack_buf[1]=command_buf[1];
- ack_buf[2]=command_buf[2];
- ack_buf[3]=command_buf[3];
- data_start=(command_buf[2]<<8)+command_buf[3]; //標(biāo)識碼
- //data_num=(command_buf[4]<<8)+command_buf[5];
- data_num = command_buf[4]; //數(shù)據(jù)長度
- if(data_num>2) data_num=2; //防止數(shù)據(jù)超界 //接收的指令數(shù)據(jù)長度要么是0要么是2
- //ack_buf[2]=data_num*2;
- ack_num=5; //應(yīng)答信號從ack_buf【5】數(shù)據(jù)開始, ack_buf【4】中要存放數(shù)據(jù)長度
- if(Addr_RH_Start == data_start)
- {
- ack_buf[ack_num]=Sensor_Data[0]; ack_num++;
- ack_buf[ack_num]=Sensor_Data[1]; ack_num++; //7???
- ack_buf[4] = 2; //應(yīng)答指令數(shù)據(jù)長度
- if(2 == data_num)
- {
- ack_buf[ack_num]=Sensor_Data[2]; ack_num++;
- ack_buf[ack_num]=Sensor_Data[3]; ack_num++;
- ack_buf[4] = 4; //應(yīng)答指令數(shù)據(jù)長度
- }
-
- }
- if(Addr_Temp_Start == data_start)
- {
- ack_buf[ack_num]=Sensor_Data[2]; ack_num++;
- ack_buf[ack_num]=Sensor_Data[3]; ack_num++;
- ack_buf[4] = 2;
- }
- //modify by cjt 2016-07-08
- if(Addr_RHSet_Start == data_start)
- {
- ack_buf[ack_num]=0; ack_num++;
- ack_buf[ack_num]=u8DefaultRH; ack_num++;
- ack_buf[4] = 2;
- }
- if(Addr_TempSet_Start == data_start)
- {
- ack_buf[ack_num]=0; ack_num++;
- ack_buf[ack_num]=u8DefaultTemp; ack_num++;
- ack_buf[4] = 2;
- }
- if(Addr_RDTemp_Start == data_start)
- {
- ack_buf[ack_num]=0; ack_num++;
- ack_buf[ack_num]=u8ds18b20_temp; ack_num++;
- ack_buf[4] = 2;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
RS-485.rar
(7.05 KB, 下載次數(shù): 621)
2018-8-23 15:36 上傳
點(diǎn)擊文件名下載附件
|
評分
-
查看全部評分
|