This repository has been archived on 2024-12-31. You can view files and clone it, but cannot push or open issues or pull requests.
mfps/App/Src/Uart1.c

697 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include "main.h"
//#include "SC_Init.h" //MCU Init headerInclude all IC resource headers
//#include "SC_it.h"
//#include "..\Drivers\SCDriver_list.h"
//#include "HeadFiles\SysFunVarDefine.h"
#include "Uart1.h"
#include "usart.h"
#include "app.h"
//#include "Motor.h"
#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 motor_data[10];
//发送buff
uint8_t ttl_send_len = 0;
uint8_t ttl_send_buff[TTL_SEND_BUFF_LEN] = {0};
//接收buff
uint8_t ttl_receive_len = 0;
uint8_t ttl_receive_buff[TTL_RECEIVE_BUFF_LEN] = {0};
//接收超时
uint8_t ttl_receive_flag = 0;
uint8_t ttl_receive_cnt = 0;
uint8_t 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 SUR_DEVICE_ADDR = 0x00A1; //PC //0x00A1; //设备
uint16_t OBJ_DEVICE_ADDR = 0x00B1; //主板 //0x00B1; //PC群发 FFFF 0000
uint8_t order_flag = 0;
unsigned int checksum = 0, re_status = 0, rec_len = 0, data_len = 0, shouldaccept = 0;
//单独发送
void UART1_SendData(uint8_t dat)
{
//SSI_UART1_SendData8(dat);
HAL_UART_Transmit_IT(&huart1,&dat,1);
}
//发送数据
void UART1_Send_Char(uint8_t dat)
{
// SSI_UART1_SendData8(dat);
HAL_UART_Transmit_IT(&huart1,&dat,1);
}
//初始化
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 1
/*
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 xor_data = 0;
unsigned char PData[TTL_SEND_BUFF_LEN];
unsigned char 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 i = 0; //临时变量
uint8_t len = 0; //长度
uint8_t 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 : //
{
}
break;
//--------------------------------------------------------------------
//LED 控制
//--------------------------------------------------------------------
case 3 : //F111 05 00 0C 00 A1 00 C1 F1 01 05 03 50 87 1B
{
}
break;
//======================================================================
//
//======================================================================
case 4 : //
{
}
break;
//--------------------------------------------------------------------
//实时信息
//--------------------------------------------------------------------
case 5 : //
{
}
break;
case 6 : // 设置 地址 + 版本号 F1D3 05 00 0D 00 A1 00 00 F1 D3 00 C1 07 A9 1B
{
}
break;
case 7 : //更新程序
{
}
break;
//--------------------------------------------------------------------
//设备信息
//--------------------------------------------------------------------
case 10 : //F115 05 00 0A 00 C1 00 A1 F1 05 50 87 1B
{
}
break;
default :
{
}
break;
}
}
//清空数据
InitUart_Data();
}
}