STM32串口向世界问好

本文介绍串口通信最基本也是最常用的用法,全双工、异步通讯方式。它只需要3根线连接即可,发送(TX)、接收(RX)及地(GND)。

配置串口通信,至少要设置以下几个参数:字长(一次传送的数据长度)、波特率(每秒传输的数据位数)、奇偶校验位、还有停止位。

对于STM32可有多达5个串口(3个通用同步异步收发器USART和2个通用异步收发器UART),从驱动库中也可以发现:

#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)
#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)
#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)
#define RCC_APB1Periph_UART5             ((uint32_t)0x00100000)



下面以最常用到的USART1为倒来说明,其发送端(TX)默认的为管脚PA9,接收端(RX)默认为PA10,利用库函数其初始化代码为:


/
**
  * @brief  初始化IO 串口1
  * @param  bound:波特率
  * @retval None
  */
void USART1_Debug_Init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    assert_param(bound > 0);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
    USART_DeInit(USART1);  //复位串口1
    //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
        //USART 初始化设置
    USART_InitStructure.USART_BaudRate = bound;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Tx;    //发送模式
    USART_Init(USART1, &USART_InitStructure); //初始化串口
    USART_Cmd(USART1, ENABLE);                 //使能串口
}

至此就可以进行发送了,需要调用USART_SendData函数。比如要发送"Hello" 
则要进行如下调用:

USART_SendData(USART1, 'H');
USART_SendData(USART1, 'e');
USART_SendData(USART1, 'l');
USART_SendData(USART1, 'l');
USART_SendData(USART1, 'o');
USART_SendData(USART1, '\n');

是不是感觉到很麻烦,能否像通用C语言中那样调用printf函数直接打印输出呢?
答案是肯定的,只需要进行简单的重定向就可以搞定,为了实现重定向printf()函数,我们需要重写 fputc() 这个c标准库函数,
因为printf()在 c标准库函数中实质是一个宏,最终是调用了 fputc()这个函数的。

/
**
  * @brief  重定义fputc函数
  * @param  int ch 要发送数据 , FILE *f 指向特定文件指针
  * @retval int ch
  */
int fputc(int ch, FILE *f)
{ 
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {
    }
    
    USART_SendData(USART1, (u8)ch);
    return ch;
}


另外要注意的是,需要在MDK下加选中如下图选项:


161205_aS4u_2243302.jpg
至此就可以轻松的向世界问好了,只需一句

printf("Hello World \n");


但有一点要注意的,利用这种技巧打印消息时会使嵌入式软件效率变低,我曾在调试软件时加入窗口看门狗,但系统总是莫名的复位,最后调试才发现是因主轮循中调用printf导致延时喂狗了。

转载于:https://my.oschina.net/oceanstack/blog/325760

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值