673 lines
20 KiB
C
673 lines
20 KiB
C
/*************************** (C) COPYRIGHT 2017 CXHY ****************************
|
||
* 文件名 :RS485.c
|
||
* 描 述 :RS485通信处理函数,包含3部分:接收帧程序、发送帧程序及执行命令程序。
|
||
* 版 本 :V1.0
|
||
* 作 者 :XuZhongPing
|
||
* 日 期 :2017/02/10
|
||
*********************************************************************************/
|
||
#include "delay.h"
|
||
#include "sys.h"
|
||
#include "RS485.h"
|
||
// #include "usart5.h"
|
||
#include "usart.h"
|
||
#include "timer.h"
|
||
#include "message.h"
|
||
#include "device.h"
|
||
#include "data_typedef.h"
|
||
|
||
/*通讯变量定义*/
|
||
#define BaudRate 9600 //波特率
|
||
#define DATA_SIZE 32 //通讯缓存区长度
|
||
|
||
uint8_t Address = 0x00; //设备地址
|
||
uint8_t Serial_buf[DATA_SIZE]; //定义通讯缓存区
|
||
uint8_t RS485_RX_BUF[64]; //接收缓冲,最大64个字节
|
||
uint8_t RS485_TX_BUF[64]; //发送缓冲,最大64个字节
|
||
|
||
//主程序变量定义
|
||
uint8_t RS485_RX_STA = 0x00; //RS485接收状态标记
|
||
uint8_t RS485_CommunicationState; //RS485通讯成功与否标志
|
||
uint8_t radioCom = 0; //广播命令标志
|
||
uint8_t responseMark = 0; //主机应答标志
|
||
uint16_t RS485_serialNumber; //RS485通信流水号
|
||
uint8_t rxCmd; //从机返回的指令码
|
||
|
||
uint8_t slaveAddress = 0; //从机返回的地址
|
||
|
||
uint8_t getMCU2DataStatus; //取得MCU2的数据状态
|
||
uint8_t getMCU2DistanceStatus; //取得MCU2的测距数据状态
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_Init
|
||
* 功能说明: 初始化RS485接口
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_Init(void)
|
||
{
|
||
//GPIO端口设置
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOA时钟
|
||
|
||
|
||
//RS485_TX_EN RS485发送接收控制脚
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
|
||
GPIO_ResetBits(GPIOC, GPIO_Pin_2); //输出0,默认接收状态
|
||
|
||
USART5_Init(BaudRate); //RS485对应的串口初始化
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_ReceiveData
|
||
* 功能说明: RS485接收数据
|
||
* 形 参: rxData -> 接收到的数据
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_ReceiveData(uint8_t rxData)
|
||
{
|
||
static uint8_t RX_State = 0; //接收状态
|
||
static uint8_t CS = 0; //接收核验和
|
||
static uint8_t RX_Size = 0; //接收通讯数据长度
|
||
static uint8_t Byte_Count = 0; //接收数据字节计数
|
||
|
||
// printf("R = %x\r\n", rxData);
|
||
switch(RX_State)
|
||
{
|
||
case 0: //第一前导字节
|
||
if(rxData == 0xfe){
|
||
RX_State = 1;
|
||
}else{
|
||
RX_State = 0;
|
||
}
|
||
break;
|
||
case 1: //第二前导字节
|
||
if(rxData == 0xfe){
|
||
RX_State = 1; //转到接收帧头
|
||
}else{
|
||
if(rxData == 0x68)
|
||
{
|
||
RX_State = 3; //转到接收设备通讯地址
|
||
CS = 0x68;
|
||
}else{
|
||
RX_State = 0;
|
||
}
|
||
}
|
||
break;
|
||
case 2: //接收帧头
|
||
if(rxData == 0x68){
|
||
RX_State = 3; //转到接收设备通讯地址
|
||
CS = 0x68;
|
||
}else{
|
||
RX_State = 0;
|
||
}
|
||
break;
|
||
case 3: //接收设备通讯地址
|
||
RS485_RX_BUF[0] = rxData;
|
||
CS += rxData;
|
||
RX_State = 4;
|
||
break;
|
||
case 4: //接收帧头
|
||
if(rxData == 0x68){
|
||
RX_State = 5; //转到接收通讯命令
|
||
CS += 0x68;
|
||
}else{
|
||
RX_State = 0;
|
||
}
|
||
break;
|
||
case 5: //接收通讯命令
|
||
RS485_RX_BUF[1] = rxData;
|
||
CS += rxData;
|
||
RX_State = 6; //转到接收数据长度
|
||
break;
|
||
case 6: //接收通讯数据长度
|
||
RS485_RX_BUF[2] = rxData;
|
||
CS += rxData;
|
||
RX_Size = rxData; //接收的数据长度
|
||
if(RX_Size == 0x00){ //如果数据长度为0,则直接转到接收校验码
|
||
RX_State = 8;
|
||
}else{
|
||
RX_State = 7; //转到接收数据
|
||
}
|
||
break;
|
||
case 7: //接收N个字节数据
|
||
if(Byte_Count < RX_Size-1){
|
||
RS485_RX_BUF[Byte_Count + 3] = rxData;
|
||
CS += rxData;
|
||
Byte_Count++;
|
||
}else{
|
||
RS485_RX_BUF[Byte_Count + 3] = rxData;
|
||
CS += rxData;
|
||
Byte_Count = 0; //已完成N个字节的数据接收计数归0
|
||
RX_State = 8; //转到接收核验码
|
||
}
|
||
break;
|
||
case 8: //接收校验
|
||
if(CS != rxData){
|
||
RX_State = 0;
|
||
}else{
|
||
RX_State = 9; //转到接收帧尾码0x16
|
||
}
|
||
break;
|
||
case 9: //接收帧尾
|
||
if(rxData == 0x16){ //是帧尾吗?
|
||
RS485_RX_STA = 0xfd; //一帧接收成功,标记USART_RX_STA=0xfd通知主程序进行通讯处理
|
||
}
|
||
RX_State = 0;
|
||
break;
|
||
default: //其它
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: Receive_One
|
||
* 功能说明: 接收一帧通讯函数
|
||
* 形 参: 接收存取地址指针
|
||
* 返 回 值: 接收正确标志,1 为接收到一帧数据,0 未接收到数据
|
||
***********************************************************************
|
||
*/
|
||
// uint8_t Receive_One(uint8_t *s)
|
||
// {
|
||
// if(RS485_RX_STA == 0xfd)
|
||
// {
|
||
// return 1; //一帧接收成功,关闭接收通讯,处理一帧完后再打开
|
||
// }else{
|
||
// return 0;
|
||
// }
|
||
// }
|
||
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_SendData
|
||
* 功能说明: 发送一个字节数据
|
||
* 形 参: 发送数据
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_SendData(uint8_t Serial_data)
|
||
{
|
||
// CTRL485 = 1; //设置为发送模式
|
||
UART5_Send_Data(Serial_data);
|
||
// CTRL485 = 0; //恢复为接收模式
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_SendOne
|
||
* 功能说明: 通过RS485发送一帧数据
|
||
* 形 参: 发送数据帧地址指针
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_SendOne(uint8_t *s)
|
||
{
|
||
uint8_t i;
|
||
uint8_t CS = 0x68; //接收核验和
|
||
uint8_t TX_Size = 0; //接收通讯数据长度
|
||
|
||
printf("\r\nRS485 --> %x\r\n", *(s+1));
|
||
|
||
CTRL485 = 1; //RS-485 通讯,切换为发送状态
|
||
|
||
delay_ms(1);
|
||
RS485_SendData(0xfe); //发送前导字节
|
||
RS485_SendData(0xfe);
|
||
RS485_SendData(0xfe);
|
||
RS485_SendData(0xfe);
|
||
RS485_SendData(0x68); //发送帧头
|
||
RS485_SendData(*s); //发送地址
|
||
CS += *s;
|
||
RS485_SendData(0x68); //发送帧头
|
||
CS += 0x68;
|
||
RS485_SendData(*(s+1)); //发送帧命令
|
||
CS += *(s+1);
|
||
TX_Size = *(s+2); //取出通讯数据长度
|
||
RS485_SendData(TX_Size); //发送数据长度
|
||
CS += *(s+2);
|
||
for(i=0; i<TX_Size; i++) //发送数据
|
||
{
|
||
RS485_SendData(*(s+i+3));
|
||
CS += (*(s+i+3));
|
||
}
|
||
RS485_SendData(CS); //发送校验字节
|
||
RS485_SendData(0x16); //发送帧尾
|
||
|
||
delay_ms(1);
|
||
|
||
CTRL485 = 0; //一帧发送完毕,恢复信道切换功能
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: Serial_AddrxDatas
|
||
* 功能说明: 通讯地址判断
|
||
* 形 参: s 指向从通讯地址
|
||
* 返 回 值: 0x00 错误,0x01 正确,0x02 广播地址
|
||
***********************************************************************
|
||
*/
|
||
static uint8_t Serial_Address(uint8_t *s)
|
||
{
|
||
// printf("\r\n地址:%x\r\n", *s);
|
||
if(*s == 0x99)
|
||
{
|
||
// printf("\r\n收到广播指令\r\n");
|
||
return(0x02); //是广播地址
|
||
}
|
||
if(*s == Address)
|
||
{
|
||
// printf("\r\n地址匹配正确\r\n");
|
||
return(0x01); //地址匹配正确
|
||
}
|
||
// printf("\r\n地址匹配不正确\r\n");
|
||
return(0x00); //地址匹配不正确
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_CommandDecoding
|
||
* 功能说明: 执行通讯命令
|
||
* 形 参: s 发送数据帧地址指针
|
||
* 返 回 值: 0 错误,1 正确
|
||
***********************************************************************
|
||
*/
|
||
uint8_t RS485_CommandDecoding(uint8_t *pRxBuf, uint8_t *pTxBuf)
|
||
{
|
||
printf("\r\nRS485_%x <-- %x\r\n", *(pRxBuf+3), *(pRxBuf+1));
|
||
rxCmd = *(pRxBuf+1);
|
||
|
||
switch(Serial_Address(pRxBuf)) //判断地址是否正确
|
||
{
|
||
case 0x02: //广播地址0x99
|
||
switch(*(pRxBuf+1)) //通讯命令译码
|
||
{
|
||
case 0x20: //主机广播开门命令
|
||
printf("\r\n收到广播开门指令\r\n");
|
||
radioCom = 1;
|
||
isOpenDoor = 1;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case 0x01: //正常地址
|
||
slaveAddress = *(pRxBuf+3); //取出应答从机的地址
|
||
|
||
switch(*(pRxBuf+1)) //通讯命令译码
|
||
{
|
||
case 0x00: //应答命令
|
||
|
||
break;
|
||
|
||
case 0x01: //读取超声波测量值
|
||
|
||
break;
|
||
|
||
case 0x10: //开门指令
|
||
// switch(slaveAddress)
|
||
// {
|
||
// case 0x11: //从机1的分机1返回数据
|
||
// devRunningStatusNO_1 = 1;
|
||
// break;
|
||
//
|
||
// case 0x12: //从机1的分机2返回数据
|
||
// devRunningStatusNO_2 = 1;
|
||
// break;
|
||
//
|
||
// case 0x21: //从机2的分机1返回数据
|
||
// devRunningStatusNO_3 = 1;
|
||
// break;
|
||
//
|
||
// case 0x22: //从机2的分机2返回数据
|
||
// devRunningStatusNO_4 = 1;
|
||
// break;
|
||
//
|
||
// default:
|
||
// printf("\r\nError_0x10指令出错\r\n");
|
||
// break;
|
||
// }
|
||
|
||
break;
|
||
|
||
case 0x11: //获取开门控制运行状态指令
|
||
// switch(slaveAddress)
|
||
// {
|
||
// case 0x11: //从机1的分机1返回数据
|
||
// devRunningStatusNO_1 = *(pRxBuf+4);
|
||
// printf("\r\nRX_Data = 0x%02X\r\n", *(pRxBuf+4));
|
||
// break;
|
||
//
|
||
// case 0x12: //从机1的分机2返回数据
|
||
// devRunningStatusNO_2 = *(pRxBuf+4);
|
||
// printf("\r\nRX_Data = 0x%02X\r\n", *(pRxBuf+4));
|
||
// break;
|
||
//
|
||
// case 0x21: //从机2的分机1返回数据
|
||
// devRunningStatusNO_3 = *(pRxBuf+4);
|
||
// printf("\r\nRX_Data = 0x%02X\r\n", *(pRxBuf+4));
|
||
// break;
|
||
//
|
||
// case 0x22: //从机2的分机2返回数据
|
||
// devRunningStatusNO_4 = *(pRxBuf+4);
|
||
// printf("\r\nRX_Data = 0x%02X\r\n", *(pRxBuf+4));
|
||
// break;
|
||
//
|
||
// default:
|
||
// printf("\r\nError_0x10指令出错\r\n");
|
||
// break;
|
||
// }
|
||
break;
|
||
|
||
case 0x12: //获取从机测距数据指令
|
||
// switch(slaveAddress)
|
||
// {
|
||
// case 0x10:
|
||
// case 0x11:
|
||
// case 0x12:
|
||
// getDistance1 = *(pRxBuf+4); //玻璃
|
||
// getDistance2 = *(pRxBuf+5); //金属
|
||
// break;
|
||
//
|
||
// case 0x20:
|
||
// case 0x21:
|
||
// case 0x22:
|
||
// getDistance3 = *(pRxBuf+4); //瓶子
|
||
// getDistance4 = *(pRxBuf+5); //塑料
|
||
// break;
|
||
//
|
||
// }
|
||
// printf("\r\nRX_Data = %d, %d\r\n", *(pRxBuf+4), *(pRxBuf+5));
|
||
break;
|
||
|
||
case 0x13: //获取从机投放数据指令
|
||
// switch(slaveAddress)
|
||
// {
|
||
// case 0x11: //从机1的分机1返回数据(注意:此称重由第2路秤返回)
|
||
// getWeight4 = (uint16_t)(*(pRxBuf+4)) << 8; //取出重量高8位数据
|
||
// getWeight4 |= *(pRxBuf+5); //取出重量低8位数据
|
||
//
|
||
// getWeightBefore4 = (uint16_t)(*(pRxBuf+6)) << 8; //取出重量高8位数据
|
||
// getWeightBefore4 |= *(pRxBuf+7); //取出重量低8位数据
|
||
//
|
||
// getWeightAfter4 = (uint16_t)(*(pRxBuf+8)) << 8; //取出重量高8位数据
|
||
// getWeightAfter4 |= *(pRxBuf+9); //取出重量低8位数据
|
||
//
|
||
// getDistance1 = *(pRxBuf+10); //取出测距数据
|
||
//
|
||
// faultCodeNO_1 = *(pRxBuf+11); //取出设备故障码
|
||
//
|
||
// devRunningStatusNO_1 = 3;
|
||
// printf("\r\nRX_Data1 = %d, %d, %d, %d, %d\r\n", getWeight4, getWeightBefore4, getWeightAfter4, getDistance1, faultCodeNO_1);
|
||
// break;
|
||
//
|
||
// case 0x12: //从机1的分机2返回数据(注意:此称重由第3路秤返回)
|
||
// getWeight3 = (uint16_t)(*(pRxBuf+4)) << 8; //取出重量高8位数据
|
||
// getWeight3 |= *(pRxBuf+5); //取出重量低8位数据
|
||
//
|
||
// getWeightBefore3 = (uint16_t)(*(pRxBuf+6)) << 8; //取出重量高8位数据
|
||
// getWeightBefore3 |= *(pRxBuf+7); //取出重量低8位数据
|
||
//
|
||
// getWeightAfter3 = (uint16_t)(*(pRxBuf+8)) << 8; //取出重量高8位数据
|
||
// getWeightAfter3 |= *(pRxBuf+9); //取出重量低8位数据
|
||
//
|
||
// getDistance2 = *(pRxBuf+10); //取出测距数据
|
||
//
|
||
// faultCodeNO_2 = *(pRxBuf+11); //取出设备故障码
|
||
//
|
||
// devRunningStatusNO_2 = 3;
|
||
// printf("\r\nRX_Data2 = %d, %d, %d, %d, %d\r\n", getWeight3, getWeightBefore3, getWeightAfter3, getDistance2, faultCodeNO_2);
|
||
// break;
|
||
//
|
||
// case 0x21: //从机2的分机1返回数据(注意:此称重由第3路秤返回)
|
||
// getWeight2 = (uint16_t)(*(pRxBuf+4)) << 8; //取出重量高8位数据
|
||
// getWeight2 |= *(pRxBuf+5); //取出重量低8位数据
|
||
//
|
||
// getWeightBefore2 = (uint16_t)(*(pRxBuf+6)) << 8; //取出重量高8位数据
|
||
// getWeightBefore2 |= *(pRxBuf+7); //取出重量低8位数据
|
||
//
|
||
// getWeightAfter2 = (uint16_t)(*(pRxBuf+8)) << 8; //取出重量高8位数据
|
||
// getWeightAfter2 |= *(pRxBuf+9); //取出重量低8位数据
|
||
//
|
||
// getDistance3 = *(pRxBuf+10); //取出测距数据
|
||
//
|
||
// faultCodeNO_3 = *(pRxBuf+11); //取出设备故障码
|
||
//
|
||
// devRunningStatusNO_3 = 3;
|
||
// printf("\r\nRX_Data3 = %d, %d, %d, %d, %d\r\n", getWeight2, getWeightBefore2, getWeightAfter2, getDistance3, faultCodeNO_3);
|
||
// break;
|
||
//
|
||
// case 0x22: //从机2的分机2返回数据
|
||
// getWeight1 = (uint16_t)(*(pRxBuf+4)) << 8; //取出重量高8位数据
|
||
// getWeight1 |= *(pRxBuf+5); //取出重量低8位数据
|
||
//
|
||
// getWeightBefore1 = (uint16_t)(*(pRxBuf+6)) << 8; //取出重量高8位数据
|
||
// getWeightBefore1 |= *(pRxBuf+7); //取出重量低8位数据
|
||
//
|
||
// getWeightAfter1 = (uint16_t)(*(pRxBuf+8)) << 8; //取出重量高8位数据
|
||
// getWeightAfter1 |= *(pRxBuf+9); //取出重量低8位数据
|
||
//
|
||
// getDistance4 = *(pRxBuf+10); //取出测距数据
|
||
//
|
||
// faultCodeNO_4 = *(pRxBuf+11); //取出设备故障码
|
||
//
|
||
// devRunningStatusNO_4 = 3;
|
||
// printf("\r\nRX_Data4 = %d, %d, %d, %d, %d\r\n", getWeight1, getWeightBefore1, getWeightAfter1, getDistance4, faultCodeNO_4);
|
||
// break;
|
||
//
|
||
// default:
|
||
// printf("\r\nError_0x10指令出错\r\n");
|
||
// break;
|
||
// }
|
||
|
||
break;
|
||
|
||
case 0x14: //获取从机投放数据数据指令(这里只获取瓶子+塑料箱的数据)
|
||
|
||
// getWeight2 = (uint16_t)(*(pRxBuf+4)) << 8; //取出重量高8位数据
|
||
// getWeight2 |= *(pRxBuf+5); //取出重量低8位数据
|
||
//
|
||
// getWeightBefore2 = (uint16_t)(*(pRxBuf+6)) << 8; //取出重量高8位数据
|
||
// getWeightBefore2 |= *(pRxBuf+7); //取出重量低8位数据
|
||
//
|
||
// getWeightAfter2 = (uint16_t)(*(pRxBuf+8)) << 8; //取出重量高8位数据
|
||
// getWeightAfter2 |= *(pRxBuf+9); //取出重量低8位数据
|
||
//
|
||
// getDistance3 = *(pRxBuf+10); //取出测距数据
|
||
// faultCodeNO_3 = *(pRxBuf+11); //取出设备故障码
|
||
//
|
||
// devRunningStatusNO_3 = 3;
|
||
//
|
||
// getSmallBottleCount = (uint16_t)(*(pRxBuf+12)) << 8; //取出瓶子高8位数据
|
||
// getSmallBottleCount |= *(pRxBuf+13); //取出瓶子低8位数据
|
||
// getDistance5 = *(pRxBuf+14); //取出测距数据
|
||
|
||
// printf("\r\nRX_Data3 = %d, %d, %d, %d, %d\r\n", getWeight2, getWeightBefore2, getWeightAfter2, getDistance3, faultCodeNO_3);
|
||
//
|
||
break;
|
||
|
||
case 0x20: //获取从机设备的当前状态指令
|
||
// switch(slaveAddress)
|
||
// {
|
||
// case 0x11: //从机1的分机1返回数据
|
||
// deviceStatusNO_1 = *(pRxBuf+4);
|
||
// break;
|
||
//
|
||
// case 0x12: //从机1的分机2返回数据
|
||
// deviceStatusNO_2 = *(pRxBuf+4);
|
||
// break;
|
||
//
|
||
// case 0x21: //从机2的分机1返回数据
|
||
// deviceStatusNO_3 = *(pRxBuf+4);
|
||
// break;
|
||
//
|
||
// case 0x22: //从机2的分机2返回数据
|
||
// deviceStatusNO_4 = *(pRxBuf+4);
|
||
// break;
|
||
//
|
||
// default:
|
||
// printf("\r\nError_0x20指令出错\r\n");
|
||
// break;
|
||
// }
|
||
break;
|
||
|
||
case 0x30: //主机发送用户信息应答
|
||
break;
|
||
|
||
case 0x31: //主机发送用户投放奖励信息应答
|
||
break;
|
||
|
||
case 0x32: //主机发送退出显示界面应答
|
||
break;
|
||
|
||
case 0x39: //主机发送退出操作应答
|
||
break;
|
||
|
||
default: //其他命令
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case 0x00: //地址错误
|
||
return 0;
|
||
}
|
||
return 1; //帧执行正确,返回
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_PackSendProtocol
|
||
* 功能说明: 根据RS485消息打包发送命令帧
|
||
* 形 参: msg -> RS485发送消息
|
||
* (其中msg->msgType为指令,msg->msgData为要发送的从机地址)
|
||
* 0x01->读取超声波测量值;
|
||
* 0x02->读取重量值
|
||
* 0x03->读取温度值
|
||
* 0x10->读取温度、测距、水位、重量、身份信息的组合
|
||
* 0x20->主机广播开门指令
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_PackSendProtocol(Com_ProtocolMessage *msg)
|
||
{
|
||
RS485_TX_BUF[0] = msg->msgData; //设置从机通讯地址
|
||
RS485_TX_BUF[1] = msg->msgType; //存入指令码
|
||
RS485_TX_BUF[2] = 0; //存入数据长度
|
||
|
||
// switch(msg->msgType)
|
||
// {
|
||
// case 0x30:
|
||
// RS485_TX_BUF[2] = 27; //存入数据长度
|
||
//
|
||
// RS485_TX_BUF[3] = isAuth; //存入数据
|
||
// RS485_TX_BUF[4] = putInType;
|
||
// memcpy(&RS485_TX_BUF[5], icCardNumberBit, 17);
|
||
// RS485_TX_BUF[5+17] = (uint8_t)(accountNum >> 24);
|
||
// RS485_TX_BUF[6+17] = (uint8_t)(accountNum >> 16);
|
||
// RS485_TX_BUF[7+17] = (uint8_t)(accountNum >> 8);
|
||
// RS485_TX_BUF[8+17] = (uint8_t)accountNum;
|
||
//
|
||
// RS485_TX_BUF[9+17] = (uint8_t)(capital >> 24);
|
||
// RS485_TX_BUF[10+17] = (uint8_t)(capital >> 16);
|
||
// RS485_TX_BUF[11+17] = (uint8_t)(capital >> 8);
|
||
// RS485_TX_BUF[12+17] = (uint8_t)capital;
|
||
// break;
|
||
//
|
||
// case 0x31:
|
||
// RS485_TX_BUF[2] = 8; //存入数据长度
|
||
//
|
||
// RS485_TX_BUF[3] = (uint8_t)(capital >> 24);
|
||
// RS485_TX_BUF[4] = (uint8_t)(capital >> 16);
|
||
// RS485_TX_BUF[5] = (uint8_t)(capital >> 8);
|
||
// RS485_TX_BUF[6] = (uint8_t)capital;
|
||
//
|
||
// RS485_TX_BUF[7] = (uint8_t)(capitalAfter >> 24);
|
||
// RS485_TX_BUF[8] = (uint8_t)(capitalAfter >> 16);
|
||
// RS485_TX_BUF[9] = (uint8_t)(capitalAfter >> 8);
|
||
// RS485_TX_BUF[10] = (uint8_t)capitalAfter;
|
||
// break;
|
||
//
|
||
// default:
|
||
// break;
|
||
// }
|
||
}
|
||
|
||
/*
|
||
***********************************************************************
|
||
* 函 数 名: RS485_Task
|
||
* 功能说明: RS485通讯任务
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
***********************************************************************
|
||
*/
|
||
void RS485_Task(void)
|
||
{
|
||
uint8_t rs485succeedFlag = 0;
|
||
uint8_t timerOut = 0;
|
||
static Com_ProtocolMessage *pMsg;
|
||
static timer timer_01;
|
||
static uint8_t timer_ok = 0;
|
||
|
||
if(timer_ok == 0)
|
||
{
|
||
timer_ok = 1;
|
||
timer_set(&timer_01, 4); //创建1个定时器
|
||
}
|
||
|
||
pMsg = MessageGet(MSG_FIFO_RS485_PROTOCOL); //从消息对列中取出RS485通讯协议消息
|
||
if(pMsg)
|
||
{
|
||
// printf("\r\n----->RS485有数据要发送正在加载数据......\r\n");
|
||
// printf("\r\n----->RS485msgType = %x\r\n", pMsg->msgType);
|
||
// printf("\r\n----->RS485msgData = %x\r\n", pMsg->msgData);
|
||
|
||
RS485_PackSendProtocol(pMsg);
|
||
RS485_SendOne(RS485_TX_BUF); //给从机发送一帧数据
|
||
|
||
if(pMsg->msgData == 0x99) //广播地址无需等待应答
|
||
{
|
||
RS485_RX_STA = 0;
|
||
}else{
|
||
timer_restart(&timer_01);
|
||
while(!timerOut && !rs485succeedFlag)
|
||
{
|
||
if(timer_expired(&timer_01)) //超时未接收到数据
|
||
{
|
||
timerOut = 1; //超时返回初始状态
|
||
printf("\r\n----->RS485TimerOut\r\n");
|
||
RS485_RX_STA = 0;
|
||
}
|
||
if(RS485_RX_STA == 0xfd) //有接收到从机返回的数据,进行地址和数据验证
|
||
{
|
||
RS485_RX_STA = 0;
|
||
if(RS485_CommandDecoding(RS485_RX_BUF, RS485_TX_BUF)) //解释返回的数据
|
||
{
|
||
// printf("\r\nmsgType = %x, rxCmd = %x\r\n", pMsg->msgType, rxCmd);
|
||
if(pMsg->msgType == rxCmd)
|
||
{
|
||
rs485succeedFlag = 1;
|
||
RS485_CommunicationState = 1; //设置本次发送的命令帧成功
|
||
|
||
printf("\r\n----->RS485<--OK\r\n");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/******************** (C) COPYRIGHT 2017 YNHB *****END OF FILE*******************/
|