gaoyang9992006 发表于 2021-1-28 17:00

【AT-START-F407测评】+使用Printf函数注意事项

本帖最后由 gaoyang9992006 于 2021-1-28 19:14 编辑

https://bbs.21ic.com/icview-3068602-1-1.html
上一贴讲述了如何使用 串口发送字符,这一帖在上一贴基础上讲述如何使用stdio.h里的printf函数
大家都记得有个次叫:重定向
那么这次咱们就将printf映射到USART1端口上去。
将stdio.h包含进来,并打开观察,看看是哪个函数用于发送一个字符。

这里要使用的就是这个

int fputc(int /*c*/, FILE * /*stream*/)只需要重写该函数即可完成。我们可以利用库函数实现,
考虑到这个发送一个字符要完成什么呢?
1、发送1 个字符到USART1
2、判断是否发送完成,完成的话进入下一个字符发送。
查找库函数找到实现这两个功能的函数,如下
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, ch);
while ( USART_GetFlagStatus(USART1, USART_FLAG_TRAC) == RESET );   
return ch;
}
这样就可以了吗?
编译测试,发现不行啊,没反应,单片机像死机了一样,没反应,是什么问题呢?
要启用MicroLIB才行,勾选上保持,重新编译下载,OK了。

#include "at32f4xx_gpio.h"
#include "at32f4xx_usart.h"
#include "stdio.h"
/*delay variable*/
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
/*delay macros*/
#define STEP_DELAY_MS      50
void Delay_init()
{
/*Config Systick*/
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
fac_us = SystemCoreClock / (1000000U);
fac_ms = fac_us * (1000U);
}

void Delay_ms(u16 nms)
{
u32 temp;
while(nms)
{
    if(nms > STEP_DELAY_MS)
    {
      SysTick->LOAD = (u32)(STEP_DELAY_MS * fac_ms);
      nms -= STEP_DELAY_MS;
    }
    else
    {
      SysTick->LOAD = (u32)(nms * fac_ms);
      nms = 0;
    }
    SysTick->VAL = 0x00;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    do
    {
      temp = SysTick->CTRL;
    }while( (temp & 0x01) && !(temp & (1<<16)) );

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL = 0X00;
}
}
//串口初始化,根据原理图使用的是USART1,PA9为TX,PA10为RX
void UART1_Init(uint32_t bound)
{
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
      
      RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA,ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_USART1,ENABLE);
/* Configure the UART1 TX pin */
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_9;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
      
          /*Configure UART param*/
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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_Rx | USART_Mode_Tx;      

USART_Init(USART1, &USART_InitStructure);
USART_INTConfig(USART1, USART_INT_RDNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}


int fputc(int ch, FILE *f)
{
USART_SendData(USART1, ch);
while ( USART_GetFlagStatus(USART1, USART_FLAG_TRAC) == RESET );   
return ch;
}


int main(void)
{
//LED2管脚初始化
      GPIO_InitType GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOD, ENABLE);
      GPIO_StructInit(&GPIO_InitStructure);
      GPIO_InitStructure.GPIO_Pins =GPIO_Pins_13;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
      GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;      
      GPIO_Init(GPIOD,&GPIO_InitStructure);
      
      Delay_init();
      UART1_Init(115200);
      
      while(1)
      {
                GPIO_SetBits(GPIOD,GPIO_Pins_13);
                Delay_ms(200);
                GPIO_ResetBits(GPIOD,GPIO_Pins_13);               
                Delay_ms(200);
                USART_SendData(USART1,'A');
                printf("Hello\n");
      }
      
}


工程下载地址
https://bbs.21ic.com/icview-3068390-1-1.html

xuanhuanzi 发表于 2021-2-28 21:07

经验啊,我忘了勾选LIB就卡死了。s
页: [1]
查看完整版本: 【AT-START-F407测评】+使用Printf函数注意事项