STM32 HAL库学习(四):串口中断
串口通信简介
-
物理层主要就是定义通信接口、电平标准这些东西 - 物理接口是指UART、USB、COM这类物理形式的硬件 -电平标准:根据使用的电平不同,串口通信可以分为TTL标准和RS-232标准 -TTL:理想状态下5V代表逻辑1,0V代表逻辑0 -RS-232:理想状态下-15V代表逻辑1,+15V代表逻辑0 协议层 主要规定了数据的格式,数据包由起始位、数据位、校验位以及停止位组成。通信双方的数据包格式必须一致才能正常接发数据。
用STM32CubeMX新建UART
stm32f1配备了3个USART,2个UART; USART:全称“通用同步异步收发器”; UART:是阉割版的USART,把同步的功能给去掉了,只能异步通信。 平时用的比较多的是UART。 注意:本工程使用USART1的异步通信功能
1. 新建工程
-
File->NewProject 芯片选型
3.配置RCC
-
配置USART1 Connectivity→USART1 模式选择:异步,Asynchronous 无硬件流控 波特率:115200;数据长度:8;奇偶校验位:无(None);停止位:1;数据方向:收发; 由于串口需要中断,所以要使能串口中断
5.配置系统时钟 6.配置工程
-
基本配置 代码配置 生成代码
编辑业务代码
-
自定义一个发送函数
void Usart_Sendstring(uint8_t *str)
{
unsigned int k = 0;
do
{
HAL_UART_Transmit(&huart1, (uint8_t *)(str + k), 1, 1000);
} while (*(str + k) != );
}
-
把C标准库的printf重定向到串口 不同交叉编译链对printf函数的重定向不一样;目前我使用过ARMCC和gcc-arm-eabi这两款编译链;armcc是mdk的编译链,下面分开说。 - 在mdk下的printf函数重定向:只需要重写fputc。
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口DEBUG_USART */
HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000);
return (ch);
}
- 在arm-gcc下的printf函数重定向:需要重写_write函数。 从STM32Cubemx官方提供的例程来看,需要引入这以下函数以及宏,可以把需要的函数以及宏复制到usart.c文件下边
#ifdef __GNUC__ /* With GCC, small printf (option LD Linker->Libraries->Small printf set to Yes) calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
//该函数可以在HAL库里找到
//STM32Cube_FW_F1_V1.8.0ProjectsSTM3210E_EVALExamplesUARTUART_PrintfSW4STM32
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}
-
主函数的代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
printf("这是重定向printf的输出
");
Usart_SendString((uint8_t *)"这是自定义函数输出
");
HAL_Delay(1000);
}
