加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

STM32 printf函数详解

(2012-06-29 10:15:23)
标签:

杂谈

分类: STM32

本实验所用的硬件:STM32F103RTB6

实验所用的晶振: 8M

实验所用的ST官方库:3.5版

C语言中的标准库中所用的标准输出函数,默认的输出设备是显示器,要实现串口或LCD的输出,必须重新定义标准库函数里与输出函数相关的函数。

1.下面首先介绍怎么根据官方3.5库里面的标准例程“printf”修改成自己的“printf”工程:

下边是官方提供的例程:

//Includes ------------------------------------------------------------------
#include "stm32f10x.h"
#include "stm32_eval.h"
#include <stdio.h>

// @addtogroup STM32F10x_StdPeriph_Examples
// @{
//

//@addtogroup USART_Printf
//@{
//

// Private typedef -----------------------------------------------------------
// Private define ------------------------------------------------------------
// Private macro -------------------------------------------------------------
// Private variables ---------------------------------------------------------
USART_InitTypeDef USART_InitStructure;

//Private function prototypes -----------------------------------------------

#ifdef __GNUC__
  //With GCC/RAISONANCE, 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
  
// Private functions ---------------------------------------------------------


 // @brief  Main program
 //@param  None
 //@retval None


int main(void)
{
   // At this stage the microcontroller clock setting is already configured, 
   // this is done through SystemInit() function which is called from startup
   // file (startup_stm32f10x_xx.s) before to branch to application main.
   //To reconfigure the default setting of SystemInit() function, refer to
   //system_stm32f10x.c file


  //USARTx configured as follow:
  //     - BaudRate = 115200 baud  
  //    - Word Length = 8 Bits
  //   - One Stop Bit
  //   - No parity
  //  - Hardware flow control disabled (RTS and CTS signals)
  //  - Receive and transmit enabled
  USART_InitStructure.USART_BaudRate = 115200;
  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;

  STM_EVAL_COMInit(COM1, &USART_InitStructure);

  // Output a message on Hyperterminal using printf function 
  printf("\n\rUSART Printf Example: retarget the C library printf function to the USART\n\r");

  while (1)
  {
  }
}
  // @brief  Retargets the C library printf function to the USART.
  // @param  None
  //@retval None
  //
PUTCHAR_PROTOTYPE
{
  // Place your implementation of fputc here
  // e.g. write a character to the USART 
  USART_SendData(EVAL_COM1, (uint8_t) ch);

  // Loop until the end of transmission 
  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

#ifdef  USE_FULL_ASSERT

  //@brief  Reports the name of the source file and the source line number
  //        where the assert_param error has occurred.
  //@param  file: pointer to the source file name
  // @param  line: assert_param error line source number
  // @retval None
  //
void assert_failed(uint8_t* file, uint32_t line)

  //User can add his own implementation to report the file name and line number,
  //   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  // Infinite loop */
  while (1)
  {
  }
}

#endif

上边用红色字体标记出来的,表示是要修改的,首先#include "stm32_eval.h"是官方提供的测试板上的头文件,而咱们要移植到自己的实验板上,所以不能用,负责编译肯定出错误,在这里直接屏蔽就行了。STM_EVAL_COMInit(COM1, &USART_InitStructure);这个函数是官方为测试板写的一个标准初始化串口的函数,所以咱们也不能用,当然你可以把这个函数复制到自己的main函数里,加以修改,这样配置起串口也就相对方便了,在这里咱们就不这样做了。因为咱们是自己新建工程,所以不能调用官方测试板的初始化串口的函数,所以必须重新写一个函数,按下面的方法进行:

  USART_InitStructure.USART_BaudRate = 115200;
  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;

  STM_EVAL_COMInit(COM1, &USART_InitStructure);

这是标准例程里的,它实现了串口的初始化,下边是我自己写的函数,也是初始化串口,所以用下面的函数替换上面的函数就ok了,函数为:

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO, ENABLE);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出-TX
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入-RX
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 USART_InitStructure.USART_BaudRate = 115200;
 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_Cmd(USART1, ENABLE);

上面程序就完成了对stm32f103rbt6串口1的初始化。

接下来就是对USART_SendData(EVAL_COM1, (uint8_t) ch),while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)这两个函数的修改,其中EVAL_COM1是官方为自己的测试板写的库函数定义的USART1,所以这里咱们直接用USATT1替换EVAL_COM1就行了,做完这些后编译整个工程,整个工程就可以编译过去了,不会出现错误,接下来的任务就是下载到实验板上做测试了。

2.下载到自己的实验板上,做测试

根据上面的修改,工程编译过去了,也没有出现任何错误,但下载到实验板上后,发现printf函数根本打印不出来想要打印出来的信息,后来我把所有的printf函数都屏蔽了,然后自己调用USART_SendData()这个函数,看到底是配置有问题还是其他问题,结果在串口调试助手里正常的打印出了想要的字符,到这里,大家应该都能猜到不是程序的问题,而是软件的配置问题,经过在网上的各种搜索后终于找到了答案。的确是配置问题,打开keil软件的target

http://s9/middle/7cae47284c393ae27d078&690printf函数详解" TITLE="STM32 printf函数详解" />

看到上面用红线标出来的位置了吧,默认情况下,keil软件是没有把Use MicroLIB这个选项勾上的,咱们修改的程序之所以没有打印出东西,就是应该勾上这个选项,勾上后,在进行一次编译,然后下载到实验板上,一切就正确了。

3.对标准printf函数的修改如下:

// Private function prototypes -----------------------------------------------

#ifdef __GNUC__
  // With GCC/RAISONANCE, 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__ 


 // @brief  Retargets the C library printf function to the USART.
 //@param  None
 // @retval None
 //
PUTCHAR_PROTOTYPE
{
  //Place your implementation of fputc here
  // e.g. write a character to the USART 
  USART_SendData(USART1, (uint8_t) ch);

  // Loop until the end of transmission
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

这一段函数就是把printf函数输出到串口,需要将fputc输出给串口,也就是重新定义。

以上就是对printf函数在调试STM32配置成串口printf函数的这个过程,希望对大家有所帮助!

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有