福建省网站建设方案书,有哪些可以免费推广的网站,软文写作平台,wordpress素材串口理论部分可看51部分#xff1a;链接
数据帧 帧头(2字节#xff0c;例如AA、BB) 数据长度#xff08;2字节#xff09; 数据 CRC16校验#xff08;2字节#xff09; 帧尾#xff08;2字节#xff09; 代码编写 串口一发送命令控制LED灯(PB5、PE5) LED灯、串口、…串口理论部分可看51部分链接
数据帧 帧头(2字节例如AA、BB) 数据长度2字节 数据 CRC16校验2字节 帧尾2字节 代码编写
串口一发送命令控制LED灯(PB5、PE5) LED灯、串口、串口打印浮点数据、串口重定向配置
LED灯配置请看链接
串口配置 配置中断NVIC(嵌套向量中断控制器) 配置DMA Cube IDE中串口打印浮点数据配置方法(参考)进入“Project→Properties”显示界面如下。按照图片中的设置完成即可 串口重定向配置
uint8_t u_buf[256]; //usart.c,24行#include stdio.h //usart.h,32行
extern uint8_t u_buf[256]; //usart.h38行
#define printf(...) HAL_UART_Transmit(huart1, (uint8_t *)u_buf, sprintf((char*)u_buf, __VA_ARGS__), 0xffff) //usart.h39行轮询方式
缺点 必须要等待数据发送完或者等待时间超时代码才会往下走 必须要等待数据接收到固定的字节长度超时代码才往下走 Cube IDE代码
mian.c
/* USER CODE BEGIN Includes */
#include string.h //26行
#include stdio.h //27
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint8_t UART_Recv[5]; //48行
char UART_Str[30]; //49行
/* USER CODE END PV *///参数1UART 模块的配置信息的指针,参数2数据缓冲区的指针参数3接收字节长度参数4接收超时时间(单位为毫秒)
HAL_UART_Receive(huart1, UART_Recv, 4, 1000); //接收数据函数
if(strcmp(LED1, (char *)UART_Recv) 0) //字符串比较函数
{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv,\0,5); //替换字符函数常用于清除指定空间
}if(!strcmp(LED2, (char *)UART_Recv)) //字符串比较函数
{HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);memset(UART_Recv,\0,5);
}sprintf(UART_Str, %f\n, 666.6);
//参数1UART 模块的配置信息的指针,参数2发送的字符串或字符数组参数3发送字节长度参数4接收超时时间(单位为毫秒)
HAL_UART_Transmit(huart1, (char *)UART_Str, strlen(UART_Str), 1000); //发送数据
printf(xinzai\n); //配置串口重定向后才可使用中断(IT)方式 Cube IDE代码 HAL_UART_RxCpltCallback(huart); //stm32f1xx_hal_uart.c,3660行//stm32f1xx_hal_uart.c,2619行
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //中断回调函数
main.c
/* USER CODE BEGIN Includes */
#include string.h //26行
#include stdio.h //27行
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint8_t UART_Recv_IT[5]; //48行
char UART_Str[30]; //49行
/* USER CODE END PV *//* USER CODE BEGIN 2 */
//参数1UART 模块的配置信息的指针,参数2数据缓冲区的指针参数3接收字节长度
HAL_UART_Receive_IT(huart1, UART_Recv_IT, 4); //串口中断接收函数95行
/* USER CODE END 2 *///while函数里
sprintf(UART_Str, %d\n, 666); //102
HAL_UART_Transmit_IT(huart1, UART_Str, strlen(UART_Str)); //串口中断发送函数,103
HAL_Delay(1000); //104//151行开始
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口中断接收触发函数
{if(huart huart1) //判断传进来的串口是哪个{if(strcmp(LED1, (char *)UART_Recv_IT) 0) //字符串比较函数{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv_IT,\0,5); //替换字符函数常用于清除指定空间}if(!strcmp(LED2, (char *)UART_Recv_IT)) //字符串比较函数{HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);memset(UART_Recv_IT,\0,5);}//因为只能接受一次串口中断所以在串口中断触发函数需要重新调用HAL_UART_Receive_IT(huart1, UART_Recv_IT, 4);}
}
/* USER CODE END 4 */空闲中断(IDLE) DMA
不受接收字符长度影响可以随意接收字符长度并判断
空闲状态在多个字节传输结束后通信线路将会维持高电平这个状态称为空闲状态没有数据传输时的空闲状态数据传输刚结束的空闲状态
空闲中断产生条件在数据传输过程中当CPU检测到通信线路处于空闲状态时且空闲状态的持续时间大于一个字节传输时间时空闲状态标志IDLE将由硬件置1产生空闲中断 Cube IDE代码
//stm32f1xx_hal_uart.h,2710行
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) //空闲中断接收回调函数main.c
/* USER CODE BEGIN Includes */
#include string.h //27行
/* USER CODE END Includes *//* USER CODE BEGIN PD */
#define RECV_Size 100 //37行
/* USER CODE END PD *//* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(huart1, UART_Recv_IDLE, RECV_Size); //空闲中断接收函数,94行
//数据接收RECV_Size一半时会重新触发中断需要关闭DMA接收中断使能
HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn); //96行
/* USER CODE END 2 *///150行
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) //空闲中断接收触发函数
{if(huart huart1) //判断传进来的串口是哪个{if(strcmp(LED1, (char *)UART_Recv_IDLE) 0) //字符串比较函数{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv_IDLE,\0,Size); //替换字符函数常用于清除指定空间}if(!strcmp(LED2ON, (char *)UART_Recv_IDLE)) //字符串比较函数{//HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0);memset(UART_Recv_IDLE,\0,Size);}else if(!strcmp(LED2OFF, (char *)UART_Recv_IDLE)){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1);memset(UART_Recv_IDLE,\0,Size);}//因为只能接受一次串口中断所以在串口中断触发函数需要重新调用HAL_UARTEx_ReceiveToIdle_DMA(huart1, UART_Recv_IDLE, RECV_Size);}}