STC15系列單片機RS-485通訊例程
單片機源程序如下:
- #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;
- /****************************************************************************************/
- /*定時器0初始化,采用16位自動重裝技術模式*/
- void Timer0Init(void) //10毫秒@11.0592MHz //16位重裝計數器
- {
- AUXR &= 0x7F; //定時器時鐘12T模式
- TMOD &= 0xF0; //設置定時器模式
-
- TL0 = -(FOSC/12/100); //設置定時初值
- TH0 = -(FOSC/12/100) >> 8; //設置定時初值
- // RL_TH0
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- Timer0_InterruptFirst();
- ET0 = 1; //enable timer0 interrupt
- }
- /***定時器0中斷服務函數**/
- void tm0_isr() interrupt 1 using 1
- {
-
- TF0 = 0; //清除TF0標志
- TL0 = -(FOSC/12/100); //設置定時初值
- TH0 = -(FOSC/12/100) >> 8; //設置定時初值
-
- ++freq;
-
- }
- /************************************************************************/
- //8位數據 波特率可變 無奇偶檢驗位 1位起始位 1位停止位
- //使用定時器1作為波特率發生器
- void Uart1Init(void) //9600bps@11.0592MHz
- {
- PCON &= 0x3F; //波特率不倍速
- SCON = 0x50; //8位數據,可變波特率
- AUXR &= 0xBF; //定時器1時鐘為Fosc/12,即12T 傳統51速度
- AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
- // AUXR |=0X01; //串口1選擇定時器2為波特率發生器
- TMOD &= 0x0F; //清除定時器1模式位
- TMOD |= 0x20; //設定定時器1為8位自動重裝方式
- // TMOD &= 0xF0; //清除定時器2模式位
- // TMOD |= 0x02; //設定定時器2為8位自動重裝方式
- TL1 = -(FOSC/12/32/BAUD); //設定定時初值
- TH1 = -(FOSC/12/32/BAUD); //設定定時器重裝值
- /*****
-
- 定時器2工作方式為固定16位自動重裝載 裝在值需重新計算
- */
- // T2L = -(FOSC/12/32/BAUD); //設定定時初值
- // T2H = -(FOSC/12/32/BAUD); //設定定時器重裝值
- ET1 = 0; //禁止定時器1中斷
- TR1 = 1; //啟動定時器1
- // S1_USE_P36P37(); //定義串口1管腳
- UART1_InterruptFirst(); //中斷優先級設定
- 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); //設置定時初值
- TH2 = -(FOSC/12/100) >> 8; //設置定時初值
- RCAP2L = -(FOSC/12/100); //設置定時重載值
- RCAP2H = -(FOSC/12/100) >> 8; //設置定時重載值
- TR2 = 1; //定時器2開始計時
- ET2 = 1; //enable timer2 interrupt
- */
-
- // Timer2_12T();
- // Timer2_AsTimer();
- // T2L = -(FOSC/12/100); //設置定時初值
- // T2H = -(FOSC/12/100) >> 8; //設置定時初值
- // 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();//使用默認端口
- 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,允許使用內部1024RAM
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /**串口1中斷服務函數!!!!!!!!!!!!!!!
- !!!!!!!!!!!!*/
- /*******************************
- 接收數據緩存區滿時,丟棄接收到的數據,數據處理后釋放數據緩存區
- ********************************/
- 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中斷服務函數******/
- /*******************************
- 接收數據緩存區滿時,丟棄接收到的數據,數據處理后釋放數據緩存區
- ********************************/
- #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緩沖區1字節函數********************************************************
- 讀取一個字節的接收緩存數據 ,釋放一個字節的緩存空間 讀取的數據存放在*pdat
- 返回0,表示緩存區有未讀數據
- 返回-1,表示緩存區沒有未讀數據
- ****************************/
- BYTE Recv1Data(BYTE *pdat)
- {
- if(u8Rx1Head != u8Rx1Tail) //有未處理數據
- {
- *pdat = u8Uart1RxBuffer[u8Rx1Tail++];
- u8Rx1Tail &= USART1_RX_BUFFER_MASK;
- return 0;
- }
- return -1;
- }
- /****************************************************************************************/
- /********************************************************************************************/
- /**********讀串口2緩沖區1字節函數*****************************************************
- 讀取一個字節的接收緩存數據 ,釋放一個字節的緩存空間 讀取的數據存放在*pdat
- 返回0,表示緩存區有未讀數據
- 返回-1,表示緩存區沒有未讀數據
- ****************************/
- BYTE Recv2Data(BYTE *pdat)
- {
- if(u8Rx2Head != u8Rx2Tail) //有未處理數據
- {
- *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發送一個字節的數據
- u8UartTxBuffer 用于發送數據的緩存 防止數據未及時發送時的數據堆積
- ----------------------------*/
-
- 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; //如果發送繁忙 則數據保存在發送緩存區
- u8Tx1Head &= USART1_TX_BUFFER_MASK;
- return 1;
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /* Send a byte data to UART
- Input: dat (data to be sent)
- Output:None
- 串口2發送一個字節的數據
- u8UartTxBuffer 用于發送數據的緩存 防止數據未及時發送時的數據堆積
- ----------------------------*/
- 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; //如果發送繁忙 則數據保存在發送緩存區
- u8Tx2Head &= USART2_TX_BUFFER_MASK;
- return 1;
- }
- /****************************************************************************************/
- /****************************************************************************************/
- /****************************************
- 從串口1數據緩存區讀取數據函數
- 讀取數據緩存區數據,釋放緩存空間 讀取的數據保存在mdbs_Rxbuf中!!
- 并判斷接收數據 的有效性 (本地地址校驗,讀寫位校驗,數據長度校驗,CRC校驗)
- 返回0,表示已接收完成一組有效數據
- 返回-1,表示,緩存區沒有數據或數據不完整! 或與本機地址不匹配
- !!!如果緩存中有數據,單數據不完整,則把已有數據保存在 mdbs_Rxbuf中,下次進入此函數,數據繼續保存
- mdbs1_Rxbuf[] 接收數據存儲區
- mdbs1_len 接收數據長度
- mdbs1_maxlen 接收指令數據區的長度
- mdbs1_stat 接收狀態
- mdbs1_pos 數據存儲地址
- mdbs1_overtime 接收超時標志
- mdbs1_timerflag 連續接收標志
- freq 時鐘節拍
- 如果中間有數據錯誤,則重新尋找數據開始位置!!!
- ************************************************/
- 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) //初次進入 mdbs_stat=0
- {
- case 0:
- {
- if(u8dat > 256) //地址不能大于247? 255?
- {
- break;
- }
- if(PODeviceAddr!=u8dat) return -1; //不是目標地址返回-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: //標識碼高字節,不做處理直接保存
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_stat = 3;
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
- } break;
- case 3: //標識碼底字節,不做處理直接保存
- {
- mdbs1_Rxbuf[mdbs1_pos++] = u8dat;
- mdbs1_len++;
- mdbs1_stat = 4;
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
-
- } break;
-
- case 4: //數據長度
- {
- 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) //如果數據長度為0 只剩下CRC校驗數據
- {
- mdbs1_stat = 100;
- mdbs1_cnt = 0;
- mdbs1_maxlen = 2;
- }
- //}
- freq=mdbs1_overtime;
- mdbs1_timerflag = 1;
-
- } break;
- case 5: //數據長度不為0,繼續接收有效數據
- {
- 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校驗位
- {
- 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數據緩存區讀取數據函數
- 讀取數據緩存區數據,釋放緩存空間 讀取的數據保存在mdbs2_Rxbuf中!!
- 并判斷接收數據 的有效性 (本地地址校驗,讀寫位校驗,數據長度校驗,CRC校驗)
- 返回0,表示已接收完成一組有效數據
- 返回-1,表示,緩存區沒有數據或數據不完整! 或與本機地址不匹配
- !!!如果緩存中有數據,單數據不完整,則把已有數據保存在 mdbs_Rxbuf中,下次進入此函數,數據繼續保存
- mdbs2_Rxbuf[] 接收數據存儲區
- mdbs2_len 接收數據長度
- mdbs2_maxlen 接收指令數據區的長度
- mdbs2_stat 接收狀態
- mdbs2_pos 數據存儲地址
- mdbs2_overtime 接收超時標志
- mdbs2_timerflag 連續接收標志
- freq 時鐘節拍
- 如果中間有數據錯誤,則重新尋找數據開始位置!!!
- ************************************************/
- 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) //初次進入 mdbs_stat=0
- {
- case 0:
- {
- if(u8dat > 256) //地址不能大于247? 255?
- {
- break;
- }
- if(MyDeviceAddr!=u8dat) return -1; //不是目標地址返回-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: //標識碼高字節,不做處理直接保存
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_stat = 3;
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 3: //標識碼底字節,不做處理直接保存
- {
- mdbs2_Rxbuf[mdbs2_pos++] = u8dat;
- mdbs2_len++;
- mdbs2_stat = 4;
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
-
- case 4: //數據長度
- {
- 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) //如果數據長度為0 只剩下CRC校驗數據
- {
- mdbs2_stat = 100;
- mdbs2_cnt = 0;
- mdbs2_maxlen = 2;
- }
- //}
- freq=mdbs2_overtime;
- mdbs2_timerflag = 1;
- } break;
- case 5: //數據長度不為0,繼續接收有效數據
- {
- 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校驗位
- {
- 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發送數據函數***********/
- /*******發送指定長度的數據*****/
- 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發送數據函數***********/
- /*******發送指定長度的數據*****/
- 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發送數據函數
- 對指定長度的數據加CRC校驗,并發送
- *********//*(發送串口1接收的的數據)*/
- void svr1_msg(unsigned char *command_buf,unsigned char sentlen)
- {
- unsigned int crc;
- if(sentlen < 4) //指令長度不應小于4,否則是無效數據
- {
- 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發送數據函數
- 對指定長度的數據加CRC校驗,并發送
- *********//*(發送串口1接收的的數據)*/
- void svr2_msg(unsigned char *command_buf,unsigned char sentlen)
- {
- unsigned int crc;
- if(sentlen < 4) //指令長度不應小于4,否則是無效數據
- {
- 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校驗表*/
- 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校驗子程序
- 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校驗子程序*/
- 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; //定時器時鐘12T模式
- // TMOD &= 0xF0; //設置定時器模式
- // //TMOD |= 0x01; //設置定時器模式
- // TL0 = -(FOSC/12/100); //設置定時初值
- // TH0 = -(FOSC/12/100) >> 8; //設置定時初值
- // TF0 = 0; //清除TF0標志
- // TR0 = 1; //定時器0開始計時
- // Timer0_InterruptFirst();
- // ET0 = 1; //enable timer0 interrupt
- //}
- /********************************************\
- /****************************************************************************************/
- /****************************************************************************************/
- /*
- */
- unsigned char MODbus_flag=0;//接收到指令標志
- 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; //本機地址改為目標地址
- svr1_msg(mdbs1_Txbuf, mdbs2_data_len-2) ; //發送更改后的數據 //svr1_msg只能發送1ci?
- MODbus_flag=1;
- }
- if(MODbus_flag==1)
- {
-
- MODbus_flag_time++;
- if(0==link_recv1_pkt()) //串口2接收應答 進行數據校驗 存儲
- {
-
- for(i=0;i<16;i++)
- {
- mdbs2_Txbuf[i]=mdbs1_Rxbuf[i];
-
- }
- mdbs2_Txbuf[0]= MyDeviceAddr; //本機地址改為目標地址
-
- svr2_msg(mdbs2_Txbuf, mdbs1_data_len-2) ; //發送更改后的數據
-
- 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發送更改后的數據
- 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();
-
- }
- }
- }
- }
- }
- /*****************************************************************************************/
- /**根據modbus1接收區的數據指令,賦值modbus的發送區數據***/
- /**返回指令長度***/
- /*data_num接收區指令的數據長度
- ack_num 發送區的指令長度
- data_start 接收區標識碼
- /****************************************************************************************/
- /*
- 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區
- 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]; //標識碼
- //data_num=(command_buf[4]<<8)+command_buf[5];
- data_num = command_buf[4]; //數據長度
- if(data_num>2) data_num=2; //防止數據超界 //接收的指令數據長度要么是0要么是2
- //ack_buf[2]=data_num*2;
- ack_num=5; //應答信號從ack_buf【5】數據開始, ack_buf【4】中要存放數據長度
- 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; //應答指令數據長度
- 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; //應答指令數據長度
- }
-
- }
- 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黑下載附件…………
復制代碼
所有資料51hei提供下載:
RS-485.rar
(7.05 KB, 下載次數: 621)
2018-8-23 15:36 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|