1.串口基础
2.串口发送
1)基本配置
注意:实现串口通信功能需在keil中设置打开Use Micro LIB,才能通过串口助手观察到串口信息
2)编辑代码
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint8_t msg[]="Hello World!\n";
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Transmit(&huart1,msg,sizeof(msg),HAL_MAX_DELAY);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
3)分析 ---关于重定向
huart1是一个串口句柄,定义在usart.c中
如果重定向printf或sprintf,只需要重定义fputc和fgetc()
#include<stdio.h>
int fputc(int ch,FILE *f){
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
int fgetc(FILE *f){
uint8_t ch;
HAL_UART_Receive(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
那么主函数可以如下实现::
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
printf("Hello World\t\n");
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
**吐槽一下,显示“%”只能用下面的方法
printf("%%");
printf("%c",'%');
3.串口接收与发送
1)进行基本配置
除了上述配置外,加入中断
2)编辑代码
触发中断时系统会调用定义于stm32f1xx_it.c的void USART1_IRQHandler(void)
可以看到该中断服务函数又调用 HAL_UART_IRQHandler(&huart1),该函数定义于stm32f1xx_hal_uart.c中:
在传输模式下,该函数调用 UART_Receive_IT(huart);该函数同样定义于stm32f1xx_hal_uart.c中,该函数调用可重定义函数 HAL_UART_RxCpltCallback(huart);并重定向printf及sprintf
#include<stdio.h>
int fputc(int ch,FILE *f){
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
int fgetc(FILE *f){
uint8_t ch;
HAL_UART_Receive(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
#define RX_BUFFER_SIZE 50
uint8_t rxBuffer[RX_BUFFER_SIZE];//发送缓冲区
uint8_t rxData; //单字节接收数据
uint8_t txBuffer[RX_BUFFER_SIZE+10];//发送还出去
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1) // 检查是否为 USART1
{
static uint16_t rxIndex = 0;
// 保存接收到的字节到缓冲区
if (rxIndex < RX_BUFFER_SIZE - 1) //确保不会写入超过缓冲区边界的位置
{
rxBuffer[rxIndex++] = rxData;
// 如果接收到换行符(表示消息结束)
if (rxData == '\n')
{
rxBuffer[rxIndex] = '\0'; // 添加字符串结束符
// 拼接前缀并发送数据
sprintf((char *)txBuffer, "STM32 Received: %s", rxBuffer);
printf("%s", txBuffer);
rxIndex = 0; // 重置接收缓冲区索引
}
}
// 继续接收下一个字节
HAL_UART_Receive_IT(&huart1, &rxData, 1);
}
}
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &rxData, 1); //开启接收中断 参数为串口句柄、数据存储地址、接收字节数
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
//uint8_t msg[]="Hello World!\t\n";
printf("Hello World!\t\n");
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
3)分析
HAL_UART_Receive_IT()很有趣?!不要忘了加!两处!