STM32之串口调试

时间:2022-02-15 02:16:20

前言:在串口调试过程中,usart1可以正常使用printf打印输出,根据usart1修改来的usart3却不能使用printf打印,最终找到原因,对比如下

//正确代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOB时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//使能USART3时钟

//错误代码
RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3|RCC_APB2Periph_GPIOB, ENABLE);    //使能USART3,GPIOB时钟

////
//由于没有考虑到总线的问题,导致以上错误

三、串口3调试成功(支持prinft函数)

 

//usart.c

/*—————————————————————————————————————————
|                文件名: usart.c                                                                                                                |
|             描述:串口调试,使用printf函数需要包含stdio.h头文件                                                |
|                        移植时需要重点关注数据总线时钟的设置                                                                    |
——————————————————————————————————————————
|更改记录:
|         作者                        时间                        更改描述
|        Yang.jx                2018.11.27                1.初稿
|
——————————————————————————————————————————*/
#include "usart.h"     

//加入以下代码,支持printf函数 
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
    int handle; 
}; 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
    while((USART3->SR&0X40)==0){}//循环发送,直到发送完毕   
    USART3->DR = (u8) ch;      
    return ch;
}
#endif 

u8 USART_RX_BUF[USART_REC_LEN];//接收缓冲
u16 USART_RX_STA=0;//接收状态标记

/******************************************************************************
函数名:USART3 初始化
******************************************************************************/
void usart_init(u32 bound)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
     
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//使能USART3 时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOB 时钟
    
  //USART3_TX   GPIOB.10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);
   
  //USART3_RX      GPIOB.11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);  

  //USART3 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
  NVIC_Init(&NVIC_InitStructure);
  
  //USART3 初始化设置
  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_Rx | USART_Mode_Tx;    //收发模式
  USART_Init(USART3, &USART_InitStructure);         //初始化USART3
    
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART3, ENABLE);                    //使能USART3 
}
/******************************************************************************
函数名:USART3 中断服务函数
******************************************************************************/
void USART3_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收中断
    {
        Res =USART_ReceiveData(USART3);    //读取接收到的数据
        if((USART_RX_STA&0x8000)==0)//接收未完成
        {
            if(USART_RX_STA&0x4000)//接收到了0x0d
            {
                if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
                else USART_RX_STA|=0x8000;    //接收完成了 
            }
            else //还没收到0X0D
            {    
                if(Res==0x0d)USART_RX_STA|=0x4000;
                else
                {
                    USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                    USART_RX_STA++;
                    if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收      
                }         
            }
        }            
    } 
}

 

//usart.h

#ifndef __USART_H
#define __USART_H
#include "sys.h" 

#define USART_REC_LEN      200  //定义最大接收字节数    
extern u8  USART_RX_BUF[200];//接收缓冲 
extern u16 USART_RX_STA;//接收状态标记    

void usart_init(u32 bound);//USART3 初始化

#endif