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);
    }

实验现象

经验分享 程序员 微信小程序 职场和发展