完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
USART框图 USART配置程序 /* USART1 init function */ static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } 中断回调程序和通信处理程序: //串口接收函数 void (* g_usartRxFunc)(uint8_t data,USART_TypeDef* USARTx); //串口接收函数配置 void USART_RxFuncConfig(void (* func)(uint8_t data,USART_TypeDef* USARTx)) { g_usartRxFunc = func; } void USART1_IRQHandler(void) { uint8_t bt; if(USART1->SR&(1<<5)) { bt = (USART1->DR&(uint8_t)0x00FF); g_usartRxFunc(bt,USART1); } } #define UART_COM_STAT '<' //串口通信开始字节 #define UART_COM_END '>' //串口通信结束字节 UartBufTypedef g_ComData[3]; //串口接收缓冲区 /* Receive -------------------------------------------------------------------*/ //串口字节流写入到缓冲区 void USART_RxToBuf(uint8_t data,USART_TypeDef* USARTx) { uint8_t cur = 0; //读取通信端口选择缓冲区 if(USARTx == USART1) { cur = 0; } else if(USARTx == USART2) { cur = 1; } else if(USARTx == USART3) { cur = 2; } //将数据写入 //上一次消息处理结束 if(g_ComData[cur].Over == 0) { //开始 if(data == UART_COM_STAT ) { //长度清零 g_ComData[cur].Len = 0; } //结束 else if(data == UART_COM_END) { //接收结束 g_ComData[cur].Over = 1; } //数据 else { //写入数据 g_ComData[cur].Buf[g_ComData[cur].Len] = data; //移动光标 g_ComData[cur].Len = (g_ComData[cur].Len + 1) % 100; } } } /* Handle --------------------------------------------------------------------*/ //设定电机速度 void setMotoSpeed(uint8_t * cmd) { //测试暂定协议 int16_t speed[2] = {0,0}; //左侧速度 speed[0] = (cmd[2] - 0x30) * 100 +(cmd[3] - 0x30) * 10 +(cmd[4] - 0x30); speed[0] = (cmd[1] == 'A') ? speed[0] : -speed[0]; //右侧速度 speed[1] = (cmd[6] - 0x30) * 100 +(cmd[7] - 0x30) * 10 +(cmd[8] - 0x30); speed[1] = (cmd[5] == 'A') ? speed[1] : -speed[1]; //设置速度 SetTargetSpeed(speed[0],speed[0],speed[1],speed[1]); } //ROS速度指令解析与速度发布 void ROS_SpeedDataSubscribe(uint8_t * cmd) { //通信协议 // //速度的分解与合成详见图解 //线速度 float vx = (cmd[2] - 0x30) * 100 +(cmd[3] - 0x30) * 10 +(cmd[4] - 0x30); vx = (cmd[1] == 'A') ? vx : -vx; //角速度 float w = (cmd[6] - 0x30) +(cmd[7] - 0x30) * 0.1 +(cmd[8] - 0x30) * 0.01 +(cmd[9] - 0x30) * 0.001; w = (cmd[5] == 'A') ? w : -w; //差分底盘合速度各个速度点的的速度分解 float va = (w * 187.833)/0.891749586; int16_t speed[4]; speed[0] = vx + va; speed[1] = vx + va; speed[2] = vx - va; speed[3] = vx - va; SetTargetSpeed(speed[1],speed[0],speed[3],speed[2]); } //发送电量信息 void sendBatteryVoltage(uint8_t * cmd) { uint8_t str[50]; float ctv = (cmd[1] - 0x30) * 10 + (cmd[2] - 0x30) + (cmd[3] - 0x30) * 0.1 + (cmd[4] - 0x30) * 0.01 ; float mtv = (cmd[5] - 0x30) * 10 + (cmd[6] - 0x30) + (cmd[7] - 0x30) * 0.1 + (cmd[8] - 0x30) * 0.01 ; sprintf((char*)str," cmd[1],cmd[2],cmd[3],cmd[4],cmd[5],cmd[6],cmd[7],cmd[8]); USART_SendString(USART3,str); } //发送检测请求 void sendBatteryVoltageMeasure(uint8_t * cmd) { USART_SendString(USART2,(uint8_t *)" } /* Analysis ------------------------------------------------------------------*/ //ROS数据接收处理 void ROS_RxBufAnalysis(UartBufTypedef * buf) { //完整性被使能 if(buf->Over == 1) { //通信协议 //开始 ‘<’ 结束 '>' //[0] 标识 [n] 数据 switch(buf->Buf[0]) { case 'M'://移动速度控制 { setMotoSpeed(buf->Buf); break; } case 'R'://线速度角速度控制模式 { ROS_SpeedDataSubscribe(buf->Buf); break; } case 'V'://发起电量检测请求 { sendBatteryVoltageMeasure(buf->Buf); break; } } //清除未完成标志位 buf->Over = 0; } } //控制器数据接收处理 void Ctrller_RxBufAnalysis(UartBufTypedef * buf) { //完整性被使能 if(buf->Over == 1) { //通信协议 //开始 ‘<’ 结束 '>' //[0] 标识 [n] 数据 switch(buf->Buf[0]) { case 'V'://电池组数据 { sendBatteryVoltage(buf->Buf); break; } } //清除未完成标志位 buf->Over = 0; } } /*Setup and Loop function ----------------------------------------------------*/ //通信处理初始化 void comHandleSetup(void) { //配置串口接收函数 USART_RxFuncConfig(USART_RxToBuf); } //通信处理循环 void comHandleLoop(void) { //接收缓冲区数据解析 ROS_RxBufAnalysis(&g_ComData[2]); ROS_RxBufAnalysis(&g_ComData[0]); Ctrller_RxBufAnalysis(&g_ComData[1]); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 04:44 , Processed in 0.672295 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号