STM32F1 串口初始化的整理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wekic/article/details/84751677

这个是初始化的头文件

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "stm32f10x.h"
#include "sys.h" 
//////////////////////////////////////////////////////////////////////////////////	 

#define debug  2

#if (debug==1) //库打印
#define  COM_Printf printf
#elif (debug==2)//自建打印
void COM_Printf(u8 type ,char *fmt, ...);
#else //无打印
void COM_Printf(u8 type char *fmt, ...);
#endif


#if 1
typedef enum
{
    COM1 = 0,
    COM2 = 1,
    COM3 = 2,
    COM4 = 3,
    COM5 = 4,
} COM_TypeDef;

void Uart1_init(u32 bound);

int fputc(int ch, FILE *f);
void Usart_Init(COM_TypeDef COMx, u32 Baud, u8 Priority1, u8 Priority2);
void Usart_SendByte(COM_TypeDef COMx, u8  Dat);
void Usart_SendString(COM_TypeDef COMx, u8 *  Dat,u16 len);
//==================宏开关============================================
//COM开关
#define COM1_OFFON  0
#if (COM1_OFFON == 1)
extern RingBuffType COM1Dat;
extern  COMnDealType COM1Deal;
#endif
#define COM2_OFFON  0
#if (COM2_OFFON == 1)
extern RingBuffType COM2Dat;
#endif
#define COM3_OFFON  0
#if (COM3_OFFON == 1)
extern RingBuffType COM3Dat;
#endif
#define COM4_OFFON  0
#if (COM4_OFFON == 1)
extern RingBuffType COM4Dat;
#endif
#define COM5_OFFON  0
#if (COM5_OFFON == 1)
extern RingBuffType COM5Dat;
#endif



//=======COM1=======
//默认: PA9 :Tx  PA10:Rx   (PA:APB2  Usart1:APB2)
//映射: PB6 :Tx  PB7 :Rx   (PA:APB2  Usart1:APB2)
#define Mapping_COM1OFFON  0

#define EVAL_COM1                        USART1
#define EVAL_COM1_CLK                    RCC_APB2Periph_USART1
#define EVAL_COM1_IRQn                   USART1_IRQn

#if (Mapping_COM1OFFON == 0) //默认
#define EVAL_COM1_TX_PIN                 GPIO_Pin_9
#define EVAL_COM1_TX_GPIO_PORT           GPIOA
#define EVAL_COM1_TX_GPIO_CLK            RCC_APB2Periph_GPIOA
#define EVAL_COM1_RX_PIN                 GPIO_Pin_10
#define EVAL_COM1_RX_GPIO_PORT           GPIOA
#define EVAL_COM1_RX_GPIO_CLK            RCC_APB2Periph_GPIOA
#elif (Mapping_COM1OFFON == 1)
#define EVAL_COM1_TX_PIN                 GPIO_Pin_6
#define EVAL_COM1_TX_GPIO_PORT           GPIOB
#define EVAL_COM1_TX_GPIO_CLK            RCC_APB2Periph_GPIOB
#define EVAL_COM1_RX_PIN                 GPIO_Pin_7
#define EVAL_COM1_RX_GPIO_PORT           GPIOB
#define EVAL_COM1_RX_GPIO_CLK            RCC_APB2Periph_GPIOB

#endif

//=======COM2=======
//默认: PA2 :Tx  PA3 :Rx (PA:APB2  Usart2:APB1)
//映射: PD5 :Tx  PD6 :Rx (PA:APB2  Usart2:APB1)
#define Mapping_COM2OFFON  0

#define EVAL_COM2                        USART2
#define EVAL_COM2_CLK                    RCC_APB1Periph_USART2
#define EVAL_COM2_IRQn                   USART2_IRQn

#if (Mapping_COM2OFFON == 0) //默认
#define EVAL_COM2_TX_PIN                 GPIO_Pin_2
#define EVAL_COM2_TX_GPIO_PORT           GPIOA
#define EVAL_COM2_TX_GPIO_CLK            RCC_APB2Periph_GPIOA
#define EVAL_COM2_RX_PIN                 GPIO_Pin_3
#define EVAL_COM2_RX_GPIO_PORT           GPIOA
#define EVAL_COM2_RX_GPIO_CLK            RCC_APB2Periph_GPIOA

#elif (Mapping_COM2OFFON == 1)

#define EVAL_COM2_TX_PIN                 GPIO_Pin_5
#define EVAL_COM2_TX_GPIO_PORT           GPIOD
#define EVAL_COM2_TX_GPIO_CLK            RCC_APB2Periph_GPIOD
#define EVAL_COM2_RX_PIN                 GPIO_Pin_6
#define EVAL_COM2_RX_GPIO_PORT           GPIOD
#define EVAL_COM2_RX_GPIO_CLK            RCC_APB2Periph_GPIOD

#endif

//=======COM3=======
//默认: PB10:Tx  PB11 :Rx (PA:APB2  Usart3:APB1) 0
//映射: PC10:Tx  PC11 :Rx (PA:APB2  Usart3:APB1) 1 //部分映射
//映射: PD8 :Tx  PD9  :Rx (PA:APB2  Usart3:APB1) 2 //全部映射
#define Mapping_COM3OFFON  0
/*            默认     部分映射   全部映射
USART3_RX  |  PB11    | PC11    |  PD9
USART3_TX  |  PB12    | PC12    |  PD10
USART3_CTS |      PB13          |  PD11
USART3_RTS |      PB14          |  PD12
*/
#define EVAL_COM3                        USART3
#define EVAL_COM3_CLK                    RCC_APB1Periph_USART3
#define EVAL_COM3_IRQn                   USART3_IRQn

#if  (Mapping_COM3OFFON==0) //默认

#define EVAL_COM3_TX_PIN                 GPIO_Pin_10
#define EVAL_COM3_TX_GPIO_PORT           GPIOB
#define EVAL_COM3_TX_GPIO_CLK            RCC_APB2Periph_GPIOB
#define EVAL_COM3_RX_PIN                 GPIO_Pin_11
#define EVAL_COM3_RX_GPIO_PORT           GPIOB
#define EVAL_COM3_RX_GPIO_CLK            RCC_APB2Periph_GPIOB

#elif (Mapping_COM3OFFON==1) //部分映射

#define EVAL_COM3_TX_PIN                 GPIO_Pin_10
#define EVAL_COM3_TX_GPIO_PORT           GPIOC
#define EVAL_COM3_TX_GPIO_CLK            RCC_APB2Periph_GPIOC
#define EVAL_COM3_RX_PIN                 GPIO_Pin_11
#define EVAL_COM3_RX_GPIO_PORT           GPIOC
#define EVAL_COM3_RX_GPIO_CLK            RCC_APB2Periph_GPIOC

#elif (Mapping_COM3OFFON==2)// 全部映射

#define EVAL_COM3_TX_PIN                 GPIO_Pin_8
#define EVAL_COM3_TX_GPIO_PORT           GPIOD
#define EVAL_COM3_TX_GPIO_CLK            RCC_APB2Periph_GPIOD
#define EVAL_COM3_RX_PIN                 GPIO_Pin_9
#define EVAL_COM3_RX_GPIO_PORT           GPIOD
#define EVAL_COM3_RX_GPIO_CLK            RCC_APB2Periph_GPIOD

#endif



//=======COM4=======
//默认: PC10:Tx  PC11 :Rx (PA:APB2  Uart4:APB1)
#define EVAL_COM4                        UART4
#define EVAL_COM4_CLK                    RCC_APB1Periph_UART4
#define EVAL_COM4_TX_PIN                 GPIO_Pin_10
#define EVAL_COM4_TX_GPIO_PORT           GPIOC
#define EVAL_COM4_TX_GPIO_CLK            RCC_APB2Periph_GPIOC
#define EVAL_COM4_RX_PIN                 GPIO_Pin_11
#define EVAL_COM4_RX_GPIO_PORT           GPIOC
#define EVAL_COM4_RX_GPIO_CLK            RCC_APB2Periph_GPIOC
#define EVAL_COM4_IRQn                   UART4_IRQn

//=======COM5=======
//默认: PC12:Tx  PD2 :Rx  (PA:APB2  Uart5:APB1)
#define EVAL_COM5                        UART5                //串口号
#define EVAL_COM5_CLK                    RCC_APB1Periph_UART5 //串口时钟

#define EVAL_COM5_TX_PIN                 GPIO_Pin_12          //发送管脚
#define EVAL_COM5_TX_GPIO_PORT           GPIOC                //发送管脚端
#define EVAL_COM5_TX_GPIO_CLK            RCC_APB2Periph_GPIOC //发送管脚时钟

#define EVAL_COM5_RX_PIN                 GPIO_Pin_2           //接收管脚
#define EVAL_COM5_RX_GPIO_PORT           GPIOD                //接收管脚端
#define EVAL_COM5_RX_GPIO_CLK            RCC_APB2Periph_GPIOD //接收管脚时钟

#define EVAL_COM5_IRQn                   UART5_IRQn           //串口中断号

#endif

#endif

这个是初始化的.c文件

#include "sys.h"
#include "usart.h"
#include "stdio.h"
//////////////////////////////////////////////////////////////////////////////////

#if 1

#define COMn

//===================串口中断列表=========================
//选择串口号
USART_TypeDef *COMn_USART[COMn]       = {EVAL_COM1, 			    EVAL_COM2,	 			 EVAL_COM3
#if STM32F10X_HD
                                         , 			    EVAL_COM4,              EVAL_COM5
#endif
                                        };
//串口中断号
const uint16_t COMn_IRQn[COMn]        = {EVAL_COM1_IRQn,  		EVAL_COM2_IRQn,  		EVAL_COM3_IRQn
#if STM32F10X_HD
                                         ,  		EVAL_COM4_IRQn,  		EVAL_COM5_IRQn
#endif
                                        };
//串口外设时钟
const uint32_t COMn_USART_CLK[COMn]   = {EVAL_COM1_CLK, 		  EVAL_COM2_CLK, 		 EVAL_COM3_CLK
#if STM32F10X_HD
                                         ,  		EVAL_COM4_CLK,  		EVAL_COM5_CLK
#endif
                                        };
//发送管脚时钟
const uint32_t COMn_TX_PORT_CLK[COMn] = {EVAL_COM1_TX_GPIO_CLK,  EVAL_COM2_TX_GPIO_CLK,  EVAL_COM3_TX_GPIO_CLK
#if STM32F10X_HD
                                         ,  		EVAL_COM4_TX_GPIO_CLK,  		EVAL_COM5_TX_GPIO_CLK
#endif
                                        };

//===================串口管脚列表==========================
//发送管脚端口
GPIO_TypeDef  *COMn_TX_PORT[COMn]     = {EVAL_COM1_TX_GPIO_PORT, EVAL_COM2_TX_GPIO_PORT, EVAL_COM3_TX_GPIO_PORT
#if STM32F10X_HD
                                         ,  		EVAL_COM4_TX_GPIO_PORT,  		EVAL_COM5_TX_GPIO_PORT
#endif
                                        };

//接受管脚端口
GPIO_TypeDef  *COMn_RX_PORT[COMn]     = {EVAL_COM1_RX_GPIO_PORT, EVAL_COM2_RX_GPIO_PORT, EVAL_COM3_RX_GPIO_PORT
#if STM32F10X_HD
                                         ,  		EVAL_COM4_RX_GPIO_PORT,  		EVAL_COM5_RX_GPIO_PORT
#endif
                                        };
//接受管脚时钟
const uint32_t COMn_RX_PORT_CLK[COMn] = {EVAL_COM1_RX_GPIO_CLK,  EVAL_COM2_RX_GPIO_CLK,  EVAL_COM3_RX_GPIO_CLK
#if STM32F10X_HD
                                         ,  		EVAL_COM4_RX_GPIO_CLK,  		EVAL_COM5_RX_GPIO_CLK
#endif
                                        };
//发送管脚
const uint16_t COMn_TX_PIN[COMn]      = {EVAL_COM1_TX_PIN,  	  EVAL_COM2_TX_PIN,       EVAL_COM3_TX_PIN
#if STM32F10X_HD
                                         ,  		EVAL_COM4_TX_PIN,  		EVAL_COM5_TX_PIN
#endif
                                        };
//接受管脚
const uint16_t COMn_RX_PIN[COMn]      = {EVAL_COM1_RX_PIN,  	  EVAL_COM2_RX_PIN, 	  EVAL_COM3_RX_PIN
#if STM32F10X_HD
                                         ,  		EVAL_COM4_RX_PIN,  		EVAL_COM4_RX_PIN
#endif
                                        };

//==================函数===================================================
//初始化函数 参数(串口号,波特率,抢占优先级,子优先级)
void Usart_Init(COM_TypeDef COMx, u32 Baud, u8 Priority1, u8 Priority2)
{
    //=======COM1=======
    //默认: PA9 :Tx  PA10:Rx (PA:APB2  Usart1:APB2)
    //映射: PB6 :Tx  PB7 :Rx (PA:APB2  Usart1:APB2)
    //=======COM2=======
    //默认: PA2 :Tx  PA3 :Rx (PA:APB2  Usart2:APB1)
    //映射: PD5 :Tx  PD6 :Rx (PA:APB2  Usart2:APB1)
    //=======COM3=======
    //默认: PB10:Tx  PB11 :Rx  (PA:APB2  Usart3:APB1)
    //映射: PD8 :Tx  PD9  :Rx  (PA:APB2  Usart3:APB1)
    //映射: PC10:Tx  PC11 :Rx  (PA:APB2  Usart3:APB1)
    //=======COM4=======
    //默认: PC10:Tx  PC11 :Rx  (PA:APB2  Usart4:APB1)
    //=======COM5=======
    //默认: PC12:Tx  PD2 :Rx   (PA:APB2  Usart5:APB1)
    GPIO_InitTypeDef GPIO_InitStructure;   //管脚配置
    USART_InitTypeDef USART_InitStructure; //串口配置
    NVIC_InitTypeDef NVIC_InitStructure;   //中断优先级配置

    //=====================外设时钟配置==========================================================================
    /* 使能管脚时钟 */
//    RCC_APB2PeriphClockCmd(COMn_TX_PORT_CLK[COMx] |  COMn_RX_PORT_CLK[COMx] |  RCC_APB2Periph_AFIO, ENABLE);


    /* 使能串口外设时钟 */
    if(COMx == COM1) {
#if (Mapping_COM1OFFON == 1)  //串口1开管脚重映射
        GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
#endif
        RCC_APB2PeriphClockCmd(COMn_USART_CLK[COMx], ENABLE);
    } else {
        /* 串口管脚软件重映射 */
        if(COMx == COM2) {
#if (Mapping_COM2OFFON == 1)  //串口2开管脚重映射
            GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
#endif
        } else if(COMx == COM3) {
#if (Mapping_COM3OFFON == 1)  //串口3开管脚重映射
            GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
#elif (Mapping_COM3OFFON == 2)
            GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);
#endif
        }

        RCC_APB1PeriphClockCmd(COMn_USART_CLK[COMx], ENABLE);
    }

    //==========串口管脚配置========================================================
    /* 配置串口发送脚--->复用推挽输出 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = COMn_TX_PIN[COMx];
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(COMn_TX_PORT[COMx], &GPIO_InitStructure);

    /* 配置串口接受脚--->浮空输入 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = COMn_RX_PIN[COMx];
    GPIO_Init(COMn_RX_PORT[COMx], &GPIO_InitStructure);
    //==========串口参数配置======================
    USART_InitStructure.USART_BaudRate = Baud;    //配置波特率
    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;

    /* 根据GPIO_InitStruct中指定的参数初始化外设GPIOx寄存器 */
    USART_Init(COMn_USART[COMx], &USART_InitStructure);

    /* 使能串口 */
    USART_Cmd(COMn_USART[COMx], ENABLE);
    /* 开启串口接受中断*/
    USART_ITConfig(COMn_USART[COMx], USART_IT_RXNE, ENABLE);//开启串口接受中断
    /* 清除串口发送完成标志(防止第一字节丢失)*/
    USART_ClearFlag(COMn_USART[COMx], USART_FLAG_TC);      //清除发送完成标志

    //=======串口中断优先级配置==============================================================
    //Usart1 NVIC 配置
    if(Priority1 >= 15) {
        Priority1 = 15;
    }

    if(Priority2 >= 15) {
        Priority2 = 15;
    }

    NVIC_InitStructure.NVIC_IRQChannel = COMn_IRQn[COMx];
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Priority1 ; //抢占优先级3 (0----15)
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = Priority2;				 //子优先级3   (0----15)
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;										 //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);																     //根据指定的参数初始化VIC寄存器
  
//		if(COMn_USART[COMx] == USART1)
//		COM_Printf(0,"波特率值 :  %6.0ld \r\n",72000000/COMn_USART[COMx]->BRR );   
//    else
//		COM_Printf(0,"波特率值 :  %6.0ld \r\n",36000000/COMn_USART[COMx]->BRR );  
}

//==============数据发送 ===========================================
/*
**********************************************************************
*功能:选择串口号发送单字节
*入口(COMx,DAT)
**********************************************************************
*/
void Usart_SendByte(COM_TypeDef COMx, u8  Dat)
{
    COMn_USART[COMx]->DR = (u8) Dat;
    while((COMn_USART[COMx]->SR & 0X40) == 0); //循环发送,直到发送完毕

    //    USART_SendData(COMn_USART[COMx], (u8)Dat);
    //    while(USART_GetFlagStatus(COMn_USART[COMx], USART_FLAG_TXE) == RESET);
}

void Usart_SendString(COM_TypeDef COMx, u8   *Dat, u16 len)
{
    while(len--) {
        Usart_SendByte( COMx, *Dat++);
    }
}

//////////////////////////////////////////////////////////////////
#if (debug==1)  //内部库输出
#ifndef __MICROLIB  //加入以下代码,支持printf函数,而不需要选择use MicroLIB
#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((USART1->SR&0X40)==0);//循环发送,直到发送完毕
    //    USART1->DR = (u8) ch;
    Usart_SendByte( COM1, (uint8_t) ch );
    return ch;
}
#else
int fputc(int ch, FILE *f)
{
    //	USART_SendData(USART1, (uint8_t) ch);

    //	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
    Usart_SendByte( COM1, (uint8_t) ch );
    return ch;
}
int GetKey (void)
{

    while (!(USART1->SR & USART_FLAG_RXNE));

    return ((int)(USART1->DR & 0x1FF));
}

#endif
#elif (debug==2)
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
//======LCD输出转接打印==========================================
//选择输出打印信息
const u8 enumA[] = {
    0,
//    1,  //AS608模块基础
//    2,  //AS608应用
//    3,  //ADC数据读取
//    4,  //LED的状态
//    5,  //温湿度模块
//    6,  //温湿度模块	
//	  7,  //FM24L64铁电模块
//	  8,  //打印风机信息	
};

void COM_Printf(u8 type, char *fmt, ...)
{
    u8 i;
    u8 StrlenC = 0;           //长度
    u8 COM_StrDat[100] = {0}; //缓存
    va_list ap;               //定义个链表
    for(i = 0; i < sizeof(enumA); i++) {
        if(type == enumA[i] && type != 0) {
            goto enumA1;
        }
    }
    return ;
enumA1:
    va_start(ap, fmt); //链表开始
    vsprintf((char *)COM_StrDat, fmt, ap); //数据格式化
    va_end(ap);       //链表结束
    StrlenC = strlen((char *)COM_StrDat);
    Usart_SendString(COM1, COM_StrDat, StrlenC);
}
#else
void COM_Printf(u8 type, char *fmt, ...)
{

}
#endif

#endif

猜你喜欢

转载自blog.csdn.net/Wekic/article/details/84751677