STM32F103 5个串口同时使用

发布者:painter最新更新时间:2018-08-13 来源: eefocus关键字:STM32F103  串口 手机看文章 扫描二维码
随时随地手机看文章

硬件平台:STM32F103(自带5串口)


5个串口同时工作不丢包-_-


相关宏定义


typedef enum

{

    UartPort1,

    UartPort2,

    UartPort3,

    UartPort4,

    UartPort5,

    UartPort_USB,

}UARTPORT;


#define   RXTIMEOUT    10         // 接收超时时间,如10mSec内未接收任何数据,当作一个接收包

#define   UART_TXBUFFERLEN  0x100         //发送缓冲区大小

#define   UART_RXBUFFERLEN  0x400          //接接缓冲区大小


typedef struct

{

    //接收

    volatile Uint       rxHead;

    volatile Uint       rxTail;

    volatile Uchar      rxBuf[UART_RXBUFFERLEN];

    volatile Uchar      rxTimeOut_Base;

    volatile Uchar      rxTimeOut;


    //发送

    volatile Uint       txHead;

    volatile Uint       txTail;

    volatile BOOLEAN    txEmpty;

    volatile Uchar      baudrate;

    volatile Uchar      txIdleTimeOut;

    volatile Uchar      txIdleTimeOut_Base;

    volatile Uchar      txBuf[UART_TXBUFFERLEN];

}UART_STRUCT;


static UART_STRUCT uart1;

static UART_STRUCT uart2;

static UART_STRUCT uart3;

static UART_STRUCT uart4;

static UART_STRUCT uart5;


串口1初始化


    USART_InitTypeDef USART_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;


    RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE );


    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


    /* Configure USART1 Tx (PA9) as alternate function push-pull */

    GPIO_InitStruct.GPIO_Pin = PIN_USART1_TXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_USART1_TXD, &GPIO_InitStruct );


    /* Configure USART1 Rx (PA10) as input floating */

    GPIO_InitStruct.GPIO_Pin = PIN_USART1_RXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_USART1_RXD, &GPIO_InitStruct );


    USART_StructInit(&USART_InitStruct);

    USART_InitStruct.USART_BaudRate = 115200;

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_InitStruct.USART_StopBits = USART_StopBits_1;

    USART_InitStruct.USART_Parity = USART_Parity_No ;

    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(USART1, &USART_InitStruct);

    /* Enable the USARTx Interrupt */


#if 1

//  USART_ITConfig(USART2, USART_IT_TXE, ENABLE);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);


    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

#endif

    USART_Cmd(USART1, ENABLE);


串口2初始化


    USART_InitTypeDef USART_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;


    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE );


    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


    /* Configure USART2 CTS (PA0) as input floating */

#if UART2_HARDWARE_FLOW

    GPIO_InitStruct.GPIO_Pin = PIN_USART2_CTS;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_USART2_CTS, &GPIO_InitStruct );

#endif


    /* Configure USART2 Rx (PA3) as input floating */

    GPIO_InitStruct.GPIO_Pin = PIN_USART2_RXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_USART2_RXD, &GPIO_InitStruct );


    /* Configure USART2 RTS (PA1) as alternate function push-pull */

#if UART2_HARDWARE_FLOW

    GPIO_InitStruct.GPIO_Pin = PIN_USART2_RTS;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_USART2_RTS, &GPIO_InitStruct );

#endif


    /* Configure USART2 Tx (PA2) as alternate function push-pull */

    GPIO_InitStruct.GPIO_Pin = PIN_USART2_TXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_USART2_TXD, &GPIO_InitStruct );


    USART_StructInit(&USART_InitStruct);

    USART_InitStruct.USART_BaudRate = 115200;

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_InitStruct.USART_StopBits = USART_StopBits_1;

    USART_InitStruct.USART_Parity = USART_Parity_No ;

    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

#if UART2_HARDWARE_FLOW

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS;

#else

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

#endif


    USART_Init(USART2, &USART_InitStruct);

#if 1

//  USART_ITConfig(USART2, USART_IT_TXE, ENABLE);

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);


    NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

#endif

    USART_Cmd(USART2, ENABLE);


串口3初始化


    USART_InitTypeDef USART_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;



    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE );


    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


    /* Configure USART1 Tx (PC10) as alternate function push-pull */

    GPIO_InitStruct.GPIO_Pin = PIN_UART3_TXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_UART3_TXD, &GPIO_InitStruct );


    /* Configure USART1 Rx (PC11) as input floating */

    GPIO_InitStruct.GPIO_Pin = PIN_UART3_RXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_UART3_RXD, &GPIO_InitStruct );


    USART_StructInit(&USART_InitStruct);

    USART_InitStruct.USART_BaudRate = 115200;

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_InitStruct.USART_StopBits = USART_StopBits_1;

    USART_InitStruct.USART_Parity = USART_Parity_No ;

    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(USART3, &USART_InitStruct);


    /* Enable the USARTx Interrupt */

#if 1

    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);


    NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);


#endif

    USART_Cmd(USART3, ENABLE);


串口4初始化


    USART_InitTypeDef USART_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;


    RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART4, ENABLE );


    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


#if 0

    GPIO_InitStruct.GPIO_Pin = PIN_UART4_CTS;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_UART4_CTS, &GPIO_InitStruct );

//    GPIO_ResetBits(PORT_UART4_CTS,PIN_UART4_CTS);

#endif


    /* Configure USART1 Tx (PC10) as alternate function push-pull */

    GPIO_InitStruct.GPIO_Pin = PIN_UART4_TXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_UART4_TXD, &GPIO_InitStruct );


    /* Configure USART1 Rx (PC11) as input floating */

    GPIO_InitStruct.GPIO_Pin = PIN_UART4_RXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_UART4_RXD, &GPIO_InitStruct );


    USART_StructInit(&USART_InitStruct);

    USART_InitStruct.USART_BaudRate = 115200;

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_InitStruct.USART_StopBits = USART_StopBits_1;

    USART_InitStruct.USART_Parity = USART_Parity_No ;

    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(UART4, &USART_InitStruct);


    /* Enable the USARTx Interrupt */

#if 1

//  USART_ITConfig(USART2, USART_IT_TXE, ENABLE);

    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);


    NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);


#endif

    USART_Cmd(UART4, ENABLE);


串口5初始化


    USART_InitTypeDef USART_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;


    RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART5, ENABLE );


    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;



    /* Configure USART1 Tx (PC10) as alternate function push-pull */

    GPIO_InitStruct.GPIO_Pin = PIN_UART5_TXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( PORT_UART5_TXD, &GPIO_InitStruct );


    /* Configure USART1 Rx (PC11) as input floating */

    GPIO_InitStruct.GPIO_Pin = PIN_UART5_RXD;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( PORT_UART5_RXD, &GPIO_InitStruct );


    USART_StructInit(&USART_InitStruct);

    USART_InitStruct.USART_BaudRate = 115200;

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_InitStruct.USART_StopBits = USART_StopBits_1;

    USART_InitStruct.USART_Parity = USART_Parity_No ;

    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(UART5, &USART_InitStruct);


    /* Enable the USARTx Interrupt */

#if 1

    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);


    NVIC_InitStruct.NVIC_IRQChannel = UART5_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);


#endif

    USART_Cmd(UART5, ENABLE);


中断处理



void USART_Irq_Function(UART_STRUCT *uart,USART_TypeDef *uartdef)

{

    //接收到数据USART_ GetITStatus

    while (USART_GetITStatus(uartdef, USART_IT_RXNE))

    {

        Uchar temp;


        USART_ClearFlag(uartdef, USART_FLAG_RXNE | USART_FLAG_ORE);

        temp = USART_ReceiveData(uartdef);

        if (((uart->rxHead + 1) % UART_RXBUFFERLEN) != uart->rxTail)

        {

            uart->rxBuf[uart->rxHead] = temp;

            uart->rxHead = (uart->rxHead + 1) % UART_RXBUFFERLEN;

            uart->rxTimeOut = uart->rxTimeOut_Base;

        }

    }

    //发送数据

    if (USART_GetITStatus(uartdef,USART_IT_TXE))

    {

        // USART_ClearFlag(uartdef, USART_FLAG_TXE);

        if (uart->txHead == uart->txTail)

        {

            uart->txEmpty = TRUE;

            USART_ITConfig(uartdef, USART_IT_TXE, DISABLE);

        }

        else

        {

            USART_SendData(uartdef, uart->txBuf[uart->txTail]);

            uart->txTail = (uart->txTail + 1) & (UART_TXBUFFERLEN - 1);

            uart->txIdleTimeOut = uart->txIdleTimeOut_Base;

        }

    }


}


extern void USART1_IRQHandler(void)

{

    USART_Irq_Function(&uart1,USART1);

}


extern void USART2_IRQHandler(void)

{

    USART_Irq_Function(&uart2,USART2);

}


extern void USART3_IRQHandler(void)

{

#ifdef INCLUDE_UARTPORT3

    USART_Irq_Function(&uart3,USART3);

#endif

}


extern void UART4_IRQHandler(void)

{

#ifdef INCLUDE_UARTPORT4


    USART_Irq_Function(&uart4,UART4);

#endif

}


extern void UART5_IRQHandler(void)

{

#ifdef INCLUDE_UARTPORT5

    USART_Irq_Function(&uart5,UART5);

#endif

}


超时检查


//函  数:检查是否有收到数据包,1ms调用一次

//参  数无

//返  回:无

extern void checkUartRxTimeOut()

{

    if (uart1.rxTimeOut)

    {

        if (--uart1.rxTimeOut == 0)

        {

            pushEvent(evCOM1,uart1.rxHead);

        }

    }

    if (uart2.rxTimeOut)

    {

        if (--uart2.rxTimeOut == 0)

        {

            pushEvent(evCOM2,uart2.rxHead);

        }

    }


    if (uart3.rxTimeOut)

    {

        if (--uart3.rxTimeOut == 0)

        {

            pushEvent(evCOM3,uart3.rxHead);

        }

    }


    if (uart4.rxTimeOut)

    {

        if (--uart4.rxTimeOut == 0)

        {

            pushEvent(evCOM4,uart4.rxHead);

        }

    }


    if (uart5.rxTimeOut)

    {

        if (--uart5.rxTimeOut == 0)

        {

            pushEvent(evCOM5,uart5.rxHead);

        }

    }


    if (uart1.txIdleTimeOut) uart1.txIdleTimeOut--;

    if (uart2.txIdleTimeOut) uart2.txIdleTimeOut--;

#ifdef INCLUDE_UARTPORT3

    if (uart3.txIdleTimeOut) uart3.txIdleTimeOut--;

#endif

#ifdef INCLUDE_UARTPORT4

    if (uart4.txIdleTimeOut) uart4.txIdleTimeOut--;

#endif

#ifdef INCLUDE_UARTPORT5

    if (uart5.txIdleTimeOut) uart5.txIdleTimeOut--;

#endif

}


关键字:STM32F103  串口 引用地址:STM32F103 5个串口同时使用

上一篇:STM32F407串口的基本使用
下一篇:STM32F4之USART【库函数操作】

推荐阅读最新更新时间:2024-03-16 16:10

AVR单片机的串口查询设计
* Code adapted from Atmel AVR ApplICation Note AVR306 * PolLEDmode driver forUART, this is the similar to the * library default putchar() and getchar() in ICCAVR */ #include #include #include “uart.h” /* iniTIalize UART */ void InitUART( unsigned char baudrate ) { UBRR = baudrate; /* set the baud rate */ UCR = BIT
[单片机]
AVR单片机的<font color='red'>串口</font>查询设计
STM32CubeMx启动串口调试功能Printf调试
## 概述 项目中往往需要调试信息,调试stm32的时候,需要标准库里面的printf函数。在keil MDK环境下重定向printf与keil C51不同,由于本人使用了STM32CubeMX生成工程模板,HAL_USART_Transmit函数即是模板里串口输出的函数。由于printf最终是调用fputc输出数据,fputc是一个弱引用(weak)函数,覆写即可重定向printf。 代码清单 /* USER CODE BEGIN Includes */ #include FreeRTOS.h #include task.h #include queue.h #include stdio.h /* USER CODE
[单片机]
MSP430F5529-串口介绍
开发板一共有两个串口,分别为P4.4,P4.5和P3.3,P3.4 其中P4的串口是开发板上面用短接套套起来的那个,套上短接套进行相关以后就可以和电脑进行串口通信,也可以拆下短接套和其他外设或芯片进行串口通信。 不同频率第四步的配置的数据不同,其他配置应该没什么差别。 对于串口0的配置顺序也是这样的,只要把UCA后面的1改成0就行了。 注:截取的送药车代码,没测试过。 配置过程为: 1.特殊功能相关引脚 2.串口1功能配置寄存器(UCA1CTL1)中置位 UCSWRST 以进行接下来的配置,不置位不能正常配置串口。 3.功能配置
[单片机]
STM32F103单片机输出相位可调PWM波
STM32定时器功能如下 通常使用的是PWM模式,可以通过PWM功能可以生成频率和占空比可调的方波信号,有时候需要生成初始相位可调的方波,PWM功能就就不能满足要求了。可以通过输出比较模式来实现。 输出比较模式是将计数器CNT的值和捕获比较寄存器CCR的对比,当CNT值等于CCR的值时,翻转输出电平。 通过捕获比较寄存器CCMR模式设置位的描述可以看出,输出比较模式只有当 CCR = CNT时,输出电平才会翻转。而PWM模式下 CNT CCR 时输出一个电平,CNT CCR时输出相反的电平。 通过一个示意图来看看PWM输出模式 上图中是PWM输出的示意图,可以看出CNT的值从变化范围是 0---ARR,之间
[单片机]
<font color='red'>STM32F103</font>单片机输出相位可调PWM波
stm32入门——跑马灯(基于stm32f103zet6)
最近开始学stm32,着实感觉到了stm32和51之间的区别,但也有联系,总我感觉32与51之间最大的区别就是在使用某个外设之前,要对该外设进行时钟的使能(以达到降低功耗的目的),和相关配置。 刚学完跑马灯,下面对跑马灯用到的对IO口的配置相关知识分别对应官方库函数和寄存器进行总结。 如有错误或不足,请在下方留言。 文章内容基于正点原子战舰。 IO口的状态 IO口有八大模式:─ 输入浮空( GPIO_Mode_IN_FLOATING = 0x04,) ─ 输入上拉( GPIO_Mode_IPU = 0x48,) ─ 输入下拉( GPIO_Mode_IPD
[单片机]
stm32入门——跑马灯(基于<font color='red'>stm32f103</font>zet6)
STM8S处理串口中断注意
//溢出处理-如果发生溢出需要先清除ORE,再读DR寄存器 则可清除不断入中断的问题 if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART1,USART_FLAG_ORE); //清除ORE USART_ReceiveData(USART1); //读DR }
[单片机]
运用于电池管理系统中的串口与CAN通信模块电路设计
   串口通信模块: 电池管理系统将采集处理后的数据通过串口发送到PC机界面上,实现人机交互。通过串口界面,可以观察到电池的总电压、单体电压、电流、SOC、故障状态、充放电功率等参数,还可以通过串口发送实现管理系统的在线标定。其硬件电路主要基于MAX232芯片,如图)所示。   MAX232 是+5V电源的收发器,与计算机串口连接,实现RS-232接口信号和TTL 信号的电平转换,使BMS 和PC 机能够进行异步串行通讯。为了防止电磁干扰影响串口上数据的传输,必须对总线信号进行隔离。串口是单向传输,所以利用6N137光电耦合较为方便)所示为232TXD 信号 光耦 隔离电路。    CAN通信模块: CAN通信是架接电池管理系
[电源管理]
运用于电池管理系统中的<font color='red'>串口</font>与CAN通信模块电路设计
基于STM32F103C8T6的音频显示设计
0. 开机默认音频模式,按下S1进入麦克风模式,输入电压DC12~24V。 1. 六种音频显示模式(4种频谱显示,2种时域显示),经扫频音乐测试; 2. 采样电路采用自动增益控制(AGC),性能大大提升。 3. 代码清晰结构清晰,绝非粗制滥造。 4. 默认256分频,当然也可以设置1024分频。 5. 256分频,里面频点通过软件进行了显示优化,不需要调节显示强度。 6. S1按键:打开或关闭麦克风,S2按键:切换显示模式,S3按键:去除显示落点,S4按键:强度调节(1024分频可用)。 7. 支持麦克风信号和音频信号输入显示。 8. 预留2路电机,2路UART,1个RTC芯片。
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved