嵌入式蓝桥杯 配置串口 调用固件库的方法 完整版本


嵌入式蓝桥杯 配置串口 调用固件库的方法


因为比赛时间要求的比较紧 所以调用固件库可以很快的节省时间
这里调用固件库配置串口发送分两次
一次是配置串口初始化
一次是使用printf打印的字符
串口初始化化路径
\STM32固件库v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Utilities\STM32_EVAL\STM3210B_EVAL
打开stm3210b_eval.c文件找到这个函数

void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct)

有一说一 这个函数复制上去
从配置过程上并没有节省多少时间
但是减少了思考的时间
也就是说 思维清晰的话直接写感觉还比较好一点

我们看看这个函数
如果我们要使用PA2PA3作为串口
我们只需要开启串口2时钟 和GPIOA的时钟就可以了
不用开启端口重映射 这些通通删去
原来的时钟代码

  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM] | RCC_APB2Periph_AFIO, ENABLE);

  if (COM == COM1)
  {
    
    
    RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE); 
  }
  else
  {
    
    
    /* Enable the USART2 Pins Software Remapping */
    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
    RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE);
  }

改成

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);

接着我们看GPIO
PA2是写 PA3是读 直接改Pin就好了

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* USART configuration */
  USART_Init(COM_USART[COM], USART_InitStruct);
    
  /* Enable USART */
  USART_Cmd(COM_USART[COM], ENABLE);

接下来是一个初始化 一个通道
这个我们改成USART2 就好了
接下来我们打开初始化的那个文件
路径如下
STM32固件库v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Printf
找到main.c
开头就是一段初始化配置串口的配置
然后我们复制她 同时对我们第一个复制函数做一些更改
就是一个函数包含另一个函数
代码贴出来 自己看吧

#include "uart.h"
void STM_EVAL_COMInit(USART_InitTypeDef* USART_InitStruct)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);

  /* Configure USART Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* USART configuration */
  USART_Init(USART2, USART_InitStruct);
    
  /* Enable USART */
  USART_Cmd(USART2, ENABLE);
}
void USART2_Init(void)	
{
    
    
	USART_InitTypeDef USART_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;

  STM_EVAL_COMInit(&USART_InitStructure);
}

然后我们配置中断及其中断处理函数

我们还是要找到相应的固件库 文集那
DMA_interrupt 的main.c
路径如下
STM32固件库v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\DMA_Interrupt
先找到中断配置代码

   NVIC_InitTypeDef NVIC_InitStructure;
	     /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USARTz_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

将配置通道改成串口2就好了

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

接下来使能要接收的中断
同样也是在文件中找 观看注释可以很快的找到那一句

  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

直接打开固件库里当前文件DMA_Interrupt中断配置的函数
就是那个stm32…it.c
轻松找到中断接收函数

void USART3_IRQHandler(void)
{
    
    
  if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  {
    
    
    /* Read one byte from the receive data register */
    RxBuffer2[RxCounter++] = USART_ReceiveData(USART3);

    if(RxCounter == NbrOfDataToRead)
    {
    
    
      /* Disable the USART3 Receive interrupt */
      USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
    }
  }
}

接着我们把里面内容清除 然后写一个清除标志位

void USART2_IRQHandler(void)
{
    
    
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
  {
    
    
    /* Read one byte from the receive data register */
	 USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  }
}

接着我们来配置printf的

嵌入式蓝桥杯的串口利用Printf输出

前面写了一篇是字符串输出 但是对于打印一些变量 需要将变量打印成字符类型
所以利用printf可以很轻松完成这些功能

首先 还是找到固件库里那个RTC里面第一个文件的main.c代码
路径如下
STM32固件库v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC\Calendar
然后找到void Time_Show(void)函数 就是开始复制时候的最后一个函数
然后紧接着就是我们需要的的函数

PUTCHAR_PROTOTYPE
{
    
    
  USART_SendData(EVAL_COM1, (uint8_t) ch);
   while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
   {
    
    }
    return ch;
}

我们把他复制到我们主文件中
然后我们找到前面定义这个文件的代码

#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__ */

然后我们只需要取其中 fputc(int ch, FILE *f) 直接替换掉PUTCHAR_PROTOTYPE
其实可以看出宏定义代码也是这个意思只是多了判断条件
改后的代码

int fputc(int ch, FILE *f)
{
    
    
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART2, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  {
    
    }

  return ch;
  }

最后编译的时候讲keil设置的C语言的微库带上(重要)
在这里插入图片描述
完整串口发送c语言代码

#include "usart.h"
void USART_Config()
{
    
    
	GPIO_InitTypeDef GPIO_InitStrure;
	USART_InitTypeDef USART_InitSture;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
  
		
	
	GPIO_InitStrure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStrure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStrure.GPIO_Pin=GPIO_Pin_2;
	GPIO_Init(GPIOA,&GPIO_InitStrure);	
	
	GPIO_InitStrure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStrure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStrure.GPIO_Pin=GPIO_Pin_3;
	GPIO_Init(GPIOA,&GPIO_InitStrure);	
	
	USART_InitSture.USART_BaudRate=115200;
	USART_InitSture.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitSture.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitSture.USART_Parity=USART_Parity_No;
	USART_InitSture.USART_StopBits=USART_StopBits_1;
	USART_InitSture.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART2,&USART_InitSture);
	
	USART_Cmd(USART2,ENABLE);
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	
}
void USART_SendString(int8_t *str)
{
    
    
	u8 index =0;//index 指数
	do
	{
    
    
		USART_SendData(USART2,str[index]);
		while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
		index++;
		
	}
		while(str[index]!=0);
}
void NVIC_USART_Config()
{
    
    
	NVIC_InitTypeDef NVIC_InitStrure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStrure.NVIC_IRQChannel=USART2_IRQn;
	NVIC_InitStrure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStrure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStrure.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStrure);
	
}
int fputc(int ch, FILE *f)
{
    
    
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART2, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  {
    
    }

  return ch;
}

串口头文件

#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "stdio.h"
void USART_Config(void);
void USART_SendString(int8_t *str);
void NVIC_USART_Config(void);
#endif



主函数使用

int main(void)
{
    
    
	u32 i=255;
	SysTick_Config(SystemCoreClock/1000);
	LED_Init();
	BEEP_Init();
	BEEP_Control(OPEN);
	Delay_Ms(100);
	BEEP_Control(CLOSE);
	USART_Config();
	NVIC_USART_Config();
	
	RTC_Configuration();
	Time_Adjust(23,55,55);
	while(1)
	{
    
    
   i++;
		if(i==20000)i=0;
    /* If 1s has been elapsed */
    if (TimeDisplay == 1)
    {
    
    
      /* Display current time */
      Time_Display(RTC_GetCounter());
      TimeDisplay = 0;
    }                  
  printf("i = %d ",i);
	}
}

猜你喜欢

转载自blog.csdn.net/m0_46179894/article/details/108218748