前言
助力于快速使用串口功能,如果想了解串口协议等知识点等请自行搜索,
这里注明串口下功能实现常用的fputc、字符串发送函数、fgetc函数等函数写法。
实验了三个例子来展示printf函数、串口中断使用、串口基本使用。
一、使用cubemx进行串口基本配置
二、说明
一般配置好串口我们就可以实验使用串口向上位机发送内容了,即使用板子与PC端串口调试助手或者其他设备进行信息收发。
而进行信息发送一般使用HAL库自带的发送函数HAL_UART_Transmit 另一种方法便是调用C库中的printf打印函数,而该函数是依照fputc实现的,因此需要重写该函数才可以使用printf函数。而scanf函数是依靠fgetc完成的
下面常用函数详细说明这里不做赘述,喜欢自行查阅资料 重写fputc代码
int fputc(int ch,FILE * fp)
{
HAL_UART_Transmit(&huart1,(uint8_t * )&ch,1,0xffff);
return ch;
}
**重写fgetc实现程序可调用scanf及getchar等函数**
int fgetc(FILE *f)
{
int ch;
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}
注意:使用时别忘记勾选微库选项,否则printf 不起作用 注意:使用时别忘记勾选微库选项,否则printf 不起作用 注意:使用时别忘记勾选微库选项,否则printf 不起作用
字符串发送函数
void Usart1_String(char *str)
{
int k=0;
do
{
HAL_UART_Transmit(&huart1,(uint8_t * )(str+k),1,0xffff);
k++;
}
while(*(str+k)!='\0');
return;
}
接收中断回显服务函数(板级支持包,放入串口中断服务函数中使用)
void TEST_USART_IRQHandler(void)
{
uint8_t ch;
if (__HAL_UART_GET_FLAG( &huart1, UART_FLAG_RXNE ) != RESET)
{
ch=( uint16_t)READ_REG(huart1.Instance->DR);
WRITE_REG ( huart1.Instance->DR,ch);
}
}
三、实验内容
1.串口打印
由于cubemx已经将串口的基本配置完成,我们在该基础上进行添加即可。 当添加fputc重写函数报错时别忘了添加头文件#include "stdio.h" 总之当你需要在那个文件中使用printf时别忘记添加头文件#include "stdio.h" 在main函数中添加printf
2.串口中断实现回显
前面已经使用cubemx使能了串口中断,但是我们还未声明串口中断触发方式所以添加该语句: __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);接收中断触发,其他触发方式可以修改函数中的参数。
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();
}
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
}
其他设置不变,下一步则要调用中断服务函数,及串口中断触发的入口函数 在文件stm32f1xx_it.c中可以看见串口中断服务函数,该函数内已经嵌套了一个HAL库下写好的串口中断服务函数,但当你跳进去查看会发现内部很复杂且不易改动,似乎找不到用户自行定义中断程序的位置。
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
我们可以将上诉代码中的HAL_UART_IRQHandler(&huart1);屏蔽在USART1_IRQHandler(void)函数中写入自己的程序
void USART1_IRQHandler(void)
{
TEST_USART_IRQHandler();
}
3.串口接收选择回显内容
在进行该实验建议将中断使能,找到HAL_NVIC_EnableIRQ(IRQn_Type IRQn)语句替换为HAL_NVIC_DisableIRQ(IRQn_Type IRQn)可将使能修改为失能中断即可失效。 在main.c中增加该函数
void Get_LED_CMD(void)
{
ch=getchar();
printf("接收到字符:%c\n",ch);
switch (ch)
{
case '1':
printf("ch=%c\r\n",ch);
break;
case '2':
printf("ch=%c\r\n",ch);
break;
case '3':
printf("ch=%c\r\n",ch);
break;
case '4':
printf("ch=%c\r\n",ch);
break;
case '5':
printf("ch=%c\r\n",ch);
break;
case '6':
printf("ch=%c\r\n",ch);
break;
case '7':
printf("ch=%c\r\n",ch);
break;
case '8':
printf("ch=%c\r\n",ch);
break;
default:
printf("ch=err is %c",ch);
break;
}
}
将该函数调用在main函数中while中轮询(别忘记将该函数声明在main函数之前,否则报错找不到) 测试结果: 以上Get_LED_CMD(void)函数中可以将switch语句中各个case选项中的printf替换为其他功能即可实现选择各种自己想要的功能,如发送‘1’开1灯,发送‘2’关1灯等…脑洞
|