如何在STM32C8T6上同时使用多个串口

【stm32c8t6多个串口使用】

最近做的一个小项目会同时用到多个串口,不同串口连接不同外设根据不同控制指令来执行相应的功能(wifi、语音等)如何同时进行不同串口之间的配置原理和配置单个串口相同,下面就以三个串口中断分别来进行LED的控制,后面根据自己的需求将串口接在不同的外设上面就好了。

stm32c8t6上面可以使用很多串口,通常没有经过重映射的引脚有三组串口
USART1 ------> TX(PA9) RX(PA10)
USART2 ------> TX(A2)  RX(A3)
USART3 ------> TX(PB10) RX(PB11)

下面所配置的串口就是这三组串口

下面是进行端口映射可以配置的串口引脚,可以根据自己的需求查看相关数据手册进行配置,和基本的配置大致相同,多了端口映射

串口配置源码

/*========================usart.h=====================*/

#ifndef __USART_H
#define __USART_H

#include "stm32f10x.h"
#include <stdio.h>

//串口1
#define USART1_GPIO_PORT      GPIOA
#define USART1_GPIO_CLK       RCC_APB2Periph_GPIOA
#define USART1_TX_GPIO_PIN    GPIO_Pin_9
#define USART1_RX_GPIO_PIN    GPIO_Pin_10

//串口2
#define USART2_GPIO_PORT      GPIOA
#define USART2_GPIO_CLK       RCC_APB2Periph_GPIOA
#define USART2_TX_GPIO_PIN    GPIO_Pin_2
#define USART2_RX_GPIO_PIN    GPIO_Pin_3

//串口3
#define USART3_GPIO_PORT      GPIOB
#define USART3_GPIO_CLK       RCC_APB2Periph_GPIOB
#define USART3_TX_GPIO_PIN    GPIO_Pin_10
#define USART3_RX_GPIO_PIN    GPIO_Pin_11


void usart_init(void);
void usart_init2(void);
void usart_init3(void);
void Init_Usart(void);
void USART_Send_Byte(USART_TypeDef* USARTx, uint16_t Data);
void USART_Send_String(USART_TypeDef* USARTx, char *str);

#endif  /* __USART_H */

/*=======================usart.c======================*/
#include "./usart/usart.h"
/**
 * 功能:串口初始化函数
 * 参数:None
 * 返回值:None
 */
void usart_init(void)
{
    GPIO_InitTypeDef GPIO_Init_Structure;                            //定义GPIO结构体
    USART_InitTypeDef USART_Init_Structure;                          //定义串口结构体
	NVIC_InitTypeDef  NVIC_Init_Structure;														//定义中断结构体
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
    RCC_APB2PeriphClockCmd(USART1_GPIO_CLK,  ENABLE);                 //开启GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,  ENABLE);            //开启APB2总线复用时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,  ENABLE);          //开启USART1时钟
    
    //配置PA9  TX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_AF_PP;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART1_TX_GPIO_PIN;
    GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init( USART1_GPIO_PORT, &GPIO_Init_Structure);
    
    //配置PA10 RX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART1_RX_GPIO_PIN;
    GPIO_Init( USART1_GPIO_PORT, &GPIO_Init_Structure);
    //串口相关配置
  	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);																					//串口中断配置
    USART_Init_Structure.USART_BaudRate = 115200;                                          //波特率设置为115200
    USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;       //硬件流控制为无
    USART_Init_Structure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                       //模式设为收和发
    USART_Init_Structure.USART_Parity = USART_Parity_No;                                   //无校验位
    USART_Init_Structure.USART_StopBits = USART_StopBits_1;                                //一位停止位
    USART_Init_Structure.USART_WordLength = USART_WordLength_8b;                           //字长为8位   
    USART_Init(USART1, &USART_Init_Structure);                                             //初始化	
    USART_Cmd(USART1, ENABLE);                                                            //串口使能
		
		//中断结构体配置
	NVIC_Init_Structure.NVIC_IRQChannel 			=   USART1_IRQn;
	NVIC_Init_Structure.NVIC_IRQChannelCmd   	=   ENABLE;
	NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority  =  0;
	NVIC_Init_Structure.NVIC_IRQChannelSubPriority         =  1;
	NVIC_Init(&NVIC_Init_Structure);
   
}




void usart_init2(void)
{
    GPIO_InitTypeDef GPIO_Init_Structure;                            //定义GPIO结构体
    USART_InitTypeDef USART_Init_Structure;                          //定义串口结构体
	NVIC_InitTypeDef  NVIC_Init_Structure;														//定义中断结构体
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
    RCC_APB2PeriphClockCmd(USART2_GPIO_CLK,  ENABLE);                 //开启GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,  ENABLE);            //开启APB2总线复用时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,  ENABLE);          //开启USART1时钟
    
    //配置PA2 TX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_AF_PP;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART2_TX_GPIO_PIN;
    GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_10MHz;
    
    GPIO_Init( USART2_GPIO_PORT, &GPIO_Init_Structure);
    
    //配置PA3 RX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART2_RX_GPIO_PIN;
    GPIO_Init( USART2_GPIO_PORT, &GPIO_Init_Structure);
	
    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);	
    USART_Init_Structure.USART_BaudRate = 115200;                                          //波特率设置为115200
    USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;       //硬件流控制为无
    USART_Init_Structure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                       //模式设为收和发
    USART_Init_Structure.USART_Parity = USART_Parity_No;                                   //无校验位
    USART_Init_Structure.USART_StopBits = USART_StopBits_1;                                //一位停止位
    USART_Init_Structure.USART_WordLength = USART_WordLength_8b;                           //字长为8位  
    USART_Init(USART2, &USART_Init_Structure);  
    USART_Cmd(USART2, ENABLE);
		
		//中断结构体配置
	NVIC_Init_Structure.NVIC_IRQChannel 			=   USART2_IRQn;
	NVIC_Init_Structure.NVIC_IRQChannelCmd   	=   ENABLE;
	NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority  =  0;
	NVIC_Init_Structure.NVIC_IRQChannelSubPriority         =  3;
	NVIC_Init(&NVIC_Init_Structure);
}



void usart_init3(void)
{
    GPIO_InitTypeDef GPIO_Init_Structure;                            //定义GPIO结构体
    USART_InitTypeDef USART_Init_Structure;                          //定义串口结构体
  	NVIC_InitTypeDef  NVIC_Init_Structure;														//定义中断结构体
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
    RCC_APB2PeriphClockCmd(USART3_GPIO_CLK,  ENABLE);                 //开启GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,  ENABLE);            //开启APB2总线复用时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,  ENABLE);          //开启USART1时钟
    
    //配置PB10 TX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_AF_PP;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART3_TX_GPIO_PIN;
    GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init( USART3_GPIO_PORT, &GPIO_Init_Structure);
    
    //配置PB11 RX
    GPIO_Init_Structure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;                //复用推挽
    GPIO_Init_Structure.GPIO_Pin   = USART3_RX_GPIO_PIN;
    GPIO_Init( USART3_GPIO_PORT, &GPIO_Init_Structure);
	
    USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);	
    USART_Init_Structure.USART_BaudRate = 115200;                                          //波特率设置为115200
    USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;       //硬件流控制为无
    USART_Init_Structure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                       //模式设为收和发
    USART_Init_Structure.USART_Parity = USART_Parity_No;                                   //无校验位
    USART_Init_Structure.USART_StopBits = USART_StopBits_1;                                //一位停止位
    USART_Init_Structure.USART_WordLength = USART_WordLength_8b;                           //字长为8位   
    USART_Init(USART3, &USART_Init_Structure);   
    USART_Cmd(USART3, ENABLE);
		
		//中断结构体配置
	NVIC_Init_Structure.NVIC_IRQChannel 			=   USART3_IRQn;
	NVIC_Init_Structure.NVIC_IRQChannelCmd   	=   ENABLE;
	NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority  =  1;
	NVIC_Init_Structure.NVIC_IRQChannelSubPriority         =  3;
	NVIC_Init(&NVIC_Init_Structure);
}


//三个串口初始化函数
void Init_Usart(void)
{
	usart_init();
	usart_init2();
	usart_init3();
}



/**
 * 功能:串口写字节函数
 * 参数1:USARTx :串口号
 * 参数2:Data   :需写入的字节
 * 返回值:None
 */
void USART_Send_Byte(USART_TypeDef* USARTx, uint16_t Data)
{
    USART_SendData(USARTx, Data);
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);
}
/**
 * 功能:串口写字符串函数
 * 参数1:USARTx :串口号
 * 参数2:str    :需写入的字符串
 * 返回值:None
 */
void USART_Send_String(USART_TypeDef* USARTx, char *str)
{
    uint16_t i=0;
    do
    {
        USART_Send_Byte(USARTx,  *(str+i));
        i++;
    }
    while(*(str + i) != '\0');
        
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}
/**
 * 功能:重定向
 */
int fputc(int ch,FILE *f)
{
    USART_SendData(USART1, (uint8_t)ch);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
    return (ch);
}
/**
 * 功能:重定向
 */
int fgetc(FILE *f)
{
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==RESET);
    return (int)USART_ReceiveData(USART1);
}

/*
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
    {
       
    }
}*/


/*
void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    {
       
    }
}*/



/*
void USART3_IRQHandler(void)
{
    char temp;
    if(USART_GetITStatus(USART3,USART_IT_RXNE) != RESET)
    {
        
    }
}
*/
/*=======================main.c======================*/
#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
int main()
{
    Init_Usart();
	led_init();
  
	printf("====================串口测试=====================\n");
	//USART_Send_String(USART1,"usart1 test\n");
    while(1)
    {
			
    }
}

//串口1中断
void USART1_IRQHandler(void)
{
	char temp;
	//USART_Send_String(USART1,"Usart1 interrupt test\n");	
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)
	{
		temp = USART_ReceiveData(USART1);
		if(temp == 'O')
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART1,"Led Open Successful\n");		
		}
		if(temp == 'C')
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART1,"Led Close Successful\n");
		}
	}
}


//串口2中断
void USART2_IRQHandler(void)
{
	char temp;
	//USART_Send_String(USART2,"Usart2 interrupt test\n");	
	if(USART_GetITStatus(USART2,USART_IT_RXNE)!= RESET)
	{
		temp = USART_ReceiveData(USART2);
		if(temp == 'O')
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART2,"Led Open Successful\n");		
		}
		if(temp == 'C')
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART2,"Led Close Successful\n");
		}
	}
}

//串口3中断
void USART3_IRQHandler(void)
{
	char temp;
	//USART_Send_String(USART3,"Usart3 interrupt test\n");	
	if(USART_GetITStatus(USART3,USART_IT_RXNE)!= RESET)
	{
		temp = USART_ReceiveData(USART3);
		if(temp == 'O')
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART3,"Led Open Successful\n");		
		}
		if(temp == 'C')
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
			USART_Send_String(USART3,"Led Close Successful\n");
		}
	}
}

实验结果

物联沃分享整理
物联沃-IOTWORD物联网 » 如何在STM32C8T6上同时使用多个串口

发表评论