/********************************Copyright (c)**********************************\ ** ** (c) Copyright 2019, China, JS. ** All Rights Reserved ** ** **----------------------------------文件信息------------------------------------ ** 文件名称: ttl_usart.c ** 创建日期: 2022-05-11 ** 文档描述: ttl_usart ** **----------------------------------版本信息------------------------------------ ** 版本代号: V0.1 ** 版本说明: 初始版本 ** ********************************End of Head************************************/ /* Includes ------------------------------------------------------------------*/ /** * @file uart.c * @author Nations * @version v1.0.0 * * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved. */ #include #include "SC_Init.h" //MCU Init header,Include all IC resource headers #include "SC_it.h" #include "..\Drivers\SCDriver_list.h" #include "HeadFiles\SysFunVarDefine.h" #include "Uart1.h" #include "Motor.h" //微秒延时 void DelayUs(unsigned int delay) { unsigned int i = 0, j = 0; for(i = 0; i < delay; i++) { for(j = 0; j < 125; j++); } } //毫秒延时 void DelayMs(unsigned int delay) { unsigned int i = 0; for(i = 0; i < delay; i++) { DelayUs(1000); } } #define HD_VER 0001 //硬件版本 #define SW_VER 0001 //软件版本 #define TTL_SEND_BUFF_LEN 60 //发送数据长度 #define TTL_RECEIVE_BUFF_LEN 60 //接收数据长度 //---------------------------------------------------------------- //uart1用于接收usb转ttl的串口 //---------------------------------------------------------------- //存放发送的数据内容 uint8_t xdata motor_data[10]; //发送buff uint8_t xdata ttl_send_len = 0; uint8_t xdata ttl_send_buff[TTL_SEND_BUFF_LEN] = {0}; //接收buff uint8_t xdata ttl_receive_len = 0; uint8_t xdata ttl_receive_buff[TTL_RECEIVE_BUFF_LEN] = {0}; //接收超时 uint8_t xdata ttl_receive_flag = 0; uint8_t xdata ttl_receive_cnt = 0; uint8_t xdata ttl_receive_interval = 0; #define DATA_LEN TTL_RECEIVE_BUFF_LEN //一般数据长度 #define UART_ORDER_SOF 0x05 //起始字 #define UART_ORDER_END 0x1B //结束字 #define FIXED_LEN 0x0B //固定长度 //取消RW uint16_t xdata SUR_DEVICE_ADDR = 0x00A1; //PC //0x00A1; //设备 uint16_t xdata OBJ_DEVICE_ADDR = 0x00B1; //主板 //0x00B1; //PC群发 FFFF 0000 uint8_t xdata order_flag = 0; unsigned int xdata checksum = 0, re_status = 0, rec_len = 0, data_len = 0, shouldaccept = 0; //单独发送 void UART1_SendData(uint8_t dat) { SSI_UART1_SendData8(dat); } //发送数据 void UART1_Send_Char(uint8_t dat) { SSI_UART1_SendData8(dat); } //初始化 void InitUart_Data(void) { order_flag = 0; rec_len = 0; re_status = 0; shouldaccept = 0; ttl_receive_flag = 0; ttl_receive_cnt = 0; checksum = 0; for(data_len = 0; data_len < DATA_LEN; data_len++) { ttl_receive_buff[data_len] = 0; } data_len = 0; // UART_Send_Char(0xdd); } /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ //---------------------------------------------------------------- //接收串口1 //---------------------------------------------------------------- /**************************************************************************************************** * @brief Download a file via serial port * @param None * @retval None **************************************************************************************************/ void start_ttl_receive_timer(uint32_t ms) { if(ms == 0) { return; } ttl_receive_flag = 1; ttl_receive_cnt = 0; ttl_receive_interval = ms; } /**************************************************************************************************** * @brief Upload a file via serial port. * @param None * @retval None **************************************************************************************************/ void over_ttl_receive_timer(void) { ttl_receive_flag = 0; ttl_receive_cnt = 0; ttl_receive_interval = 0; InitUart_Data(); // UART2_Send_Char(0xed); } /**************************************************************************************************** * @brief Display the Main Menu on HyperTerminal * @param None * @retval None **************************************************************************************************/ void clear_ttl_receive_timer(void) { uint16_t i = 0; ttl_receive_len = 0; ttl_receive_flag = 0; ttl_receive_cnt = 0; ttl_receive_interval = 0; for(i = 0; i < TTL_RECEIVE_BUFF_LEN; i++) { ttl_receive_buff[i] = 0; } } //返回串口屏应答是否接收完成的结果 //0:没超时 1:超时 uint8_t judge_ttl_receive_timer(void) { if(ttl_receive_flag == 2) { return 1; } else { return 0; } } /**************************************************************************************************** * @brief Display the Main Menu on HyperTerminal * @param None * @retval None **************************************************************************************************/ //放在大循环中的计时器里 void process_ttl_receive_timer(void) { if(ttl_receive_flag == 1) { ttl_receive_cnt++; } if((ttl_receive_interval > 0) && (ttl_receive_cnt >= ttl_receive_interval)) { over_ttl_receive_timer(); } } #define TTL_OVER_TIME 10 /**************************************************************************************************** * @brief Display the Main Menu on HyperTerminal * @param None * @retval None **************************************************************************************************/ //放串口中断内,接收数据 void receive_ttl_data(uint8_t rx_data) { //不能超过数组的最大长度 if(ttl_receive_len < TTL_RECEIVE_BUFF_LEN) { //开始计时 start_ttl_receive_timer(TTL_OVER_TIME); //串口接收数据分析 Do_Receive_Uart_For_Module(rx_data); } else //超过上限则抛弃后面的数据 { //超时处理 over_ttl_receive_timer(); InitUart_Data(); //UART_Send_Char(0xcc); } } #define CRC_PRESET 0xFFFF #define CRC_POLYNOM 0x4204 /*--------------------------------------------------------------------------- 调用方式:unsigned int ModbusCRC16(unsigned char *data_value, unsigned char length) 函数说明:CRC校验 ---------------------------------------------------------------------------*/ unsigned int ModbusCRC16(unsigned char *data_value, unsigned char length) { unsigned int crc_value = CRC_PRESET; unsigned char i; data_value++; while(length-- != 0) {//ModbusCRC16(PData, Num + FIXED_LEN - 3); for(i = 0x01; i != 0; i <<= 1) { if((crc_value & 0x0001) != 0) { crc_value >>= 1; crc_value ^= CRC_POLYNOM; } else { crc_value >>= 1; } if((*data_value & i) != 0) { crc_value ^= CRC_POLYNOM; } } data_value++; } return(crc_value); } /*--------------------------------------------------------------------------- 调用方式:unsigned int VerfiyRC(unsigned char *data_value, unsigned char length) 函数说明:异或校验 除了头尾固定,不校验外,其他的校验 -----------------------------------------------------------------------------*/ unsigned char VerfiyRC(unsigned char data_value[], unsigned char length) //不用异或校验,用crc校验 { unsigned char i; unsigned char V_b = data_value[1]; for(i = 0x00; i < length; i++) { //异或校验 V_b ^= data_value[i]; } return(V_b); } //发送延时 void Uart_Send_Delay(unsigned int delay) { unsigned int i = 0, j = 0; for(i = 0; i < delay; i++) { for(j = 0; j < 125; j++); } } //校验 + 0X1B #define VERFIY_TYPE 0 /* SOF: 1个字节 0x05 起始字节 Len: 2个字节 长度 Fou_adr: 2个字节 源地址 Com_adr: 2个字节 目标地址,0ff为广播地址 Cmd16: 2个字节 命令字 Request-data: N字节 数据 XOR: 2个字节 校验 END: 0x1B 结束字节 */ //发送数据 void send_set_resp(unsigned int OrderNum, unsigned int addr, unsigned char Num, unsigned char sData[]) { unsigned int xdata xor_data = 0; unsigned char xdata PData[TTL_SEND_BUFF_LEN]; unsigned char xdata i = 0; PData[0] = UART_ORDER_SOF; //第一个字节 PData[1] = (Num + FIXED_LEN) / 0x100; //长度 高8位 PData[2] = (Num + FIXED_LEN) % 0x100; //长度 低8位 PData[3] = (addr >> 8) & 0xff; //源地址 PData[4] = addr & 0xff; //源地址 PData[5] = (SUR_DEVICE_ADDR >> 8) & 0xff; //目标地址 PData[6] = SUR_DEVICE_ADDR & 0xff; //目标地址 PData[7] = (OrderNum >> 8) & 0xff; //命令字 -1 PData[8] = OrderNum & 0xff; //命令字 -2 // PData[6] = RW_Flag; //读写标志 for(i = 0; i < Num; i++) //发送数据 { PData[FIXED_LEN - 2 + i] = sData[i]; //数据 } //校验 if(VERFIY_TYPE) //异或校验 + 末尾字节 2字节 { xor_data = VerfiyRC(PData, Num + FIXED_LEN - 2); PData[FIXED_LEN + Num - 2] = xor_data; PData[FIXED_LEN + Num - 1] = 00; } else //CRC校验 2字节 { xor_data = ModbusCRC16(PData, Num + FIXED_LEN - 3); PData[FIXED_LEN + Num - 2] = (xor_data) & 0xff; PData[FIXED_LEN + Num - 1] = (xor_data >> 8) & 0xff; } PData[FIXED_LEN + Num] = UART_ORDER_END; // 末尾字节 //全部发送 for(i = 0; i < (Num + FIXED_LEN + 1); i++) //一次性发送所有数据 { UART1_Send_Char(PData[i]); //增加延时 Uart_Send_Delay(50); } } //分析地址是否为本地址 uint8_t Check_Resive_Addr(uint16_t addr) { //确定是否为接收地址 if((OBJ_DEVICE_ADDR == addr) || (0xFFFF == addr) || (0x0000 == addr) || (0x00B1 == addr)) { return 1; } else { InitUart_Data(); //2清数据 return 0; } } //接收数据判断(放置串口接收数据内) void Do_Receive_Uart_For_Module(unsigned char ch) { switch(re_status) { case 0 : //0x05 1字节 起始字 { if(ch == UART_ORDER_SOF) { rec_len = 0; ttl_receive_buff[rec_len] = ch; re_status = 1; shouldaccept = 0; // UART2_Send_Char(0xaa); } } break; case 1: //长度 2字节 { rec_len++; ttl_receive_buff[rec_len] = ch; if(rec_len >= 2) { re_status = 2; shouldaccept = ttl_receive_buff[1] * 0x100 + ttl_receive_buff[2]; if(shouldaccept >= TTL_RECEIVE_BUFF_LEN - 1) { InitUart_Data(); return; } } } break; case 2: //命令字 2个字节 05 00 0B 00 C1 00 A1 F0 01 87 1B { rec_len++; if(rec_len >= TTL_RECEIVE_BUFF_LEN - 1) { InitUart_Data(); return; } ttl_receive_buff[rec_len] = ch; //接收 if(rec_len >= shouldaccept) //判断是否接收完成 { // uint8_t i = 0; // UART2_Send_Char(0x30); // UART2_Send_Char(rec_len); // UART2_Send_Char(shouldaccept); // UART2_Send_Char(FIXED_LEN - 1); // UART2_Send_Char(rec_len); // for( i = 0;i < shouldaccept;i++) UART2_Send_Char(ttl_receive_buff[i]); //等待处理分析,至少要大于固定长度 // if(rec_len >= FIXED_LEN - 1) // { //判断接收目标地址是否是自己 // int adr = ttl_receive_buff[3]; // adr = adr << 8; // adr |= ttl_receive_buff[4]; int adr = ttl_receive_buff[5]; adr = adr << 8; adr |= ttl_receive_buff[6]; //UART2_TxByte(0xAA); //UART2_TxByte(ttl_receive_buff[3]); //UART2_TxByte(ttl_receive_buff[4]); // if(Check_Resive_Addr(adr)) { //命令字 unsigned int order = 0; order = ttl_receive_buff[7]; order = order << 8; order += ttl_receive_buff[8]; // //目标地址 // OBJ_DEVICE_ADDR = ttl_receive_buff[3]; // OBJ_DEVICE_ADDR <<= 8; // OBJ_DEVICE_ADDR += ttl_receive_buff[4]; //UART2_Send_Char(order / 0x100); //UART2_Send_Char(order % 0x100); //UART2_TxByte(0xBB); //UART2_TxByte(ttl_receive_buff[7]); //UART2_TxByte(ttl_receive_buff[8]); switch(order) { //=================== =================================================== //设备接收数据 //====================================================================== case 0xF001 : //解析数据 { order_flag = 1; } break; case 0xF0C1 : //设置设备加密信息 { order_flag = 2; } break; //====================================================================== //设备信息 //====================================================================== case 0xF111 : //控制参数 { order_flag = 3; // UART2_Send_Char(0x33); } break; //====================================================================== //设备信息 //====================================================================== case 0xF112 : //读 状态与温度 { order_flag = 4; } break; case 0xF102 : //读 状态与温度 { order_flag = 4; } break; //====================================================================== // //====================================================================== default : { InitUart_Data(); } break; } } else { InitUart_Data(); return; } } // } } break; default : InitUart_Data(); break; } } //数据长度 uint8_t Get_Data_Len(void) { uint16_t Re_Len = 0; Re_Len = (ttl_receive_buff[1] * 0x100 + ttl_receive_buff[2]) - FIXED_LEN; return Re_Len; } //检查校验 unsigned char Check_VerfiyData(void) { return 1; //调试期间,不用验证 if(VERFIY_TYPE) //异或校验 + 末尾字节 { unsigned char v_A = 0; unsigned char v_B = 0; v_A = ttl_receive_buff[shouldaccept]; v_B = VerfiyRC(ttl_receive_buff, shouldaccept - 2); if(v_A == v_B) //数据的完整性 { //结尾数据相同 if(ttl_receive_buff[shouldaccept + 1] == UART_ORDER_END) { } else { return 0; } } else { return 0; } } else //判断CRC校验 { unsigned int CRC16 = 0; unsigned int Get_CRC16 = 0; CRC16 = ttl_receive_buff[shouldaccept]; CRC16 = CRC16 << 8; CRC16 += ttl_receive_buff[shouldaccept - 1]; Get_CRC16 = ModbusCRC16(ttl_receive_buff, shouldaccept - 2); if(CRC16 == Get_CRC16) //数据的完整性 { } else { InitUart_Data(); return 0; } } return 1; } //数据接收分析(放置大循环内) void Deal_Uart_Data_For_Module(void) { if(order_flag) //有接收的指令 { //校验 if(Check_VerfiyData() == 1) //测试 { switch(order_flag) { //-------------------------------------------------------------------- // //-------------------------------------------------------------------- case 1 : //数据解析 { uint8_t xdata i = 0; //临时变量 uint8_t xdata len = 0; //长度 uint8_t xdata temp[DATA_LEN]; //发送标志 send_flag = 0; //数据长度 len = Get_Data_Len(); //解析数据 for(i = 0; i < len; i++) { temp[i] = ttl_receive_buff[i + FIXED_LEN - 2]; } //角行程 、直行程 Travle_Flag = temp[0]; //0 直 1 角 Motor_Run = temp[1]; //0 停止 1 运行 2 运行到起始点 3 运行到结束点 Run_Mode = temp[2]; //0 点动 1 方案一 2 方案二 Run_Step = temp[3]; //电机运行多少圈为一个步长 Run_Step <<= 8; Run_Step += temp[4]; Run_Inter = temp[5]; //电机运行间隔时长 Run_Inter <<= 8; Run_Inter += temp[6]; Run_Stop = temp[7]; //到“结束点”后,停止时间 Run_Stop <<= 8; Run_Stop += temp[8]; ClrRunmotorStep();//清除电机标记 } break; case 2 : // { uint8_t i = 0; uint8_t len = 0; uint8_t temp[DATA_LEN]; send_set_resp(0xF0C1, OBJ_DEVICE_ADDR, len, temp); } break; //-------------------------------------------------------------------- //LED 控制 //-------------------------------------------------------------------- case 3 : //F111 05 00 0C 00 A1 00 C1 F1 01 05 03 50 87 1B { u8 addr = 0; addr = ttl_receive_buff[FIXED_LEN - 2]; if(addr == ((SUR_DEVICE_ADDR & 0xf0) == 0xC0)) { } } break; //====================================================================== // //====================================================================== case 4 : // { } break; //-------------------------------------------------------------------- //实时信息 //-------------------------------------------------------------------- case 5 : // { uint8_t len = 0; uint8_t temp[DATA_LEN]; temp[0] = (SUR_DEVICE_ADDR >> 8) & 0xff; temp[1] = (SUR_DEVICE_ADDR >> 0) & 0xff; // //版本号 4 temp[2] = HD_VER >> 8; //HD_VER 0101 //硬件版本号 temp[3] = HD_VER & 0xff; temp[4] = SW_VER >> 8; //SW_VER 0101 //软件版本号 temp[5] = SW_VER & 0xff; len = 6; send_set_resp(0xF113, OBJ_DEVICE_ADDR, len, temp); } break; case 6 : // 设置 地址 + 版本号 F1D3 05 00 0D 00 A1 00 00 F1 D3 00 C1 07 A9 1B { uint8_t i = 0; uint8_t len = 0; uint8_t temp[DATA_LEN]; //数据长度 len = Get_Data_Len(); for(i = 0; i < len; i++) { temp[i] = ttl_receive_buff[i + FIXED_LEN - 2]; } send_set_resp(0xF1C3, OBJ_DEVICE_ADDR, len, temp); } break; case 7 : //更新程序 { } break; //-------------------------------------------------------------------- //设备信息 //-------------------------------------------------------------------- case 10 : //F115 05 00 0A 00 C1 00 A1 F1 05 50 87 1B { } break; default : { } break; } } //清空数据 InitUart_Data(); } }