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)
|