那些踩过的declared implicitly的坑

缺少头文件

我的本意是想做串口打印进行调试,于是我在usart.c中重写了这两个函数,这里顺便记录下如何串口打印
usart.c中

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
int fgetc(FILE * f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1,&ch, 1, 0xffff);
  return ch;
}

main函数之前

printf("Hello world!!!\n");

本来以为大功告成,结果出现了FILE没有定义,…/Core/Src/main.c(93): warning: #223-D: function “printf” declared implicitly 这些错误,本质上的原因是因为没有在uart.h 中声明 #include ,这主要是没有理解重定义函数的意义。
printf 定义在 头文件中,printf 函数根据 format 字符串给出的格式打印输出,stdout(标准输出)中,当然,printf 函数是不会一个字符一个字符去输出,它会调用更底层的 I/O 函数:fputc去逐个字符打印。fputc 也定义于头文件 中。

添加好头文件后,几个常用的示例:

  char str[20];
  uint8_t ch;
  /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  HAL_Init();
  /* 配置系统时钟 */
  SystemClock_Config();

  /* 初始化串口并配置串口中断优先级 */
  MX_DEBUG_USART_Init();
  
  /* 调用格式化输出函数打印输出数据 */
  printf("Hello world!!!\n");
  
  /* sprintf函数把格式化的数据写入某个字符串  */  
  sprintf(str,"今天是个好日子,20%02d-%02d-%02d",15,10,04);  
  /* 调用格式化输出函数打印输出数据 */
  printf("%s\n",str);
  /* 无限循环 */
  while (1)
  {
    ch=getchar();
    HAL_UART_Transmit(&huart1,&ch,1,0);
  }

重复定义

这个我遇到过两种:
1 我本来是想写一个新的bsp,于是我把bsp_led.c和.h分别进行复制,改了个名字,结果没有修改。
ifdef 的用法

复制代码
#define   KEY1_PA0

#ifdef    KEY1_PA0
-------------第一段-----------------
#define               macKEY1_GPIO_CLK                      RCC_APB2Periph_GPIOA
#define               macKEY1_GPIO_PORT                     GPIOA              
#define               macKEY1_GPIO_PIN                        GPIO_Pin_0

#else    //KEY2_PC13
-------------第二段-----------------
#define               macKEY1_GPIO_CLK                      RCC_APB2Periph_GPIOC
#define               macKEY1_GPIO_PORT                     GPIOC          
#define               macKEY1_GPIO_PIN                        GPIO_Pin_13

#endif
复制代码

如果定义过KEY1_PA0,则执行第一段代码,如果没有,执行第二段。
ifndef 用法

#ifndef __USART1_H
#define    __USART1_H

//statement.

#endif  // usart1.h

如果没有define过__USART1_H,就执行下面的语句;如果定义过,就不执行;
所以在一个.c文件里面,多次调用到该文件的时候,就相当于只调用一次。
这是头文件的常用写法!!由于我没有更改,就出现了两个相同的头文件定义。

2 这是关于extern的用法
当有一个变量需要在多个文件中用到时,不能定义在头文件中,可能会导致重复定义,要把该变量定义在某个.c文件中,另一个需要用到该变量的.c或者.h文件在该变量的声明前加extern
我们看一个示例:这是hal库定义的例子
usart.c中定义

UART_HandleTypeDef huart1

usart.h中

extern UART_HandleTypeDef huart1;

这是正确的,但如果UART_HandleTypeDef huart1定义在了.h文件中,在main函数里和uart.c中都使用用了usart.h,出现了重复的定义。

你可能感兴趣的:(STM32学习,stm32)