1 | 基于查询实现的串口通信

main函数测试一次串口发送数据

C
uint32_t TimingDelay = 0;
void USART_Config(void);
void USART_SendString(int8_t *str);

void Delay_Ms(uint32_t nTime)
{
    TimingDelay = nTime;
    while(TimingDelay != 0);
}

int main(void)
{
    USART_Config();
    SysTick_Config(SystemCoreClock/1000);
    Delay_Ms(200);
    USART_SendString("Welcome to link2hinar.fun!");
    while(1);
}

串口初始化函数构建

开启GPIO和USART的时钟 | 配置TX/RX参数

C
void USART_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    
    //Deploy USART2 TX Mode
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //Deploy USART2 RX Mode
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //Deploy USART2 Mode
    USART_InitStructure.USART_BaudRate = 19200;
    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;
    USART_Init(USART2, &USART_InitStructure);
    USART_Cmd(USART2, ENABLE);
}

发送数据实现

拆分为发送比特 | 发送字节 | 查询寄存器

C
#define USART_FLAG_TXE ((uint16_t)0x0080) //bit7 = 1

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
    USARTx->DR = (Data & (uint16_t)0x01FF);
}

FlagStatus USART_GetFlagStatus(USART_TypeDef*USARTx, uint16_t USART_FLAG)
{
    FlagStatus bitstatus = RESET;
    if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) {
        bitstatus = SET;
    }
    else {
        bitstatus = RESET;
    }
    return bitstatus;
}

void USART_SendString(int8_t *str)
{
    uint8_t index = 0;
    do {
        USART_SendData(USART2, str[index]);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE) == RESET);
        ++index;
    }
    while(str[index] != 0); 
}

2 | 基于中断实现的串口通信

main函数测试串口循环发送数据

C
#include "stm32f10x.h"
#include "stdio.h"

uint8_t USART_RXBUF[20]; 
extern uint8_t RXOVER; 
void NVIC_Configuration(void); 
void USART_Config(void); 
void EXTI_Config(void);
void USART_SendString(USART_RXBUF); 

int main(void)
{
    uint8_t i; 
    USART_Config(); 
    while(1) {
        if (RXOVER == 1) {
            USART_SendString(USART_RXBUF);  
            USART_SendString("\r\n"); 
            
            for(i = 0; i < 20; ++i) {
                USART_RXBUF[i] = 0;
            }
            
            RXOVER = 0; 
            USART2->CR1 |= 1 << 5; 
        }
    }
}
main.c

2 | 基于中断实现的串口通信

中断操控

C
#include "stm32f10x_it.h"

extern uint8_t USART_RXBUF[20];
uint8_t RXOVER = 0; 
uint8_t RXCUNT = 0; 

void USART2_IRQHandler(void) 
{ 
    uint8_t temp;  //判断中断标志位(USART2的bit5位为1表明接收到一个字符)
    if(USART2->SR & (1 << 5) == SET) {  
        USART2->SR &= ~(1 << 5); //清除中断标志位USART2_SR的bit5为0
        temp = (uint16_t)(USARTx->DR & (uint16_t)0x01FF);//读USART2_DR的数据
        if((temp == 'x') || (RXCUNT == 20)) { 
            RXCUNT = 0; 
            RXOVER = 1; 
            USART2->CR1 &= ~(1 << 5);//禁止接收数据产生中断
        }
        else { 
            USART_RXBUF[RXCUNT] = temp;//接收到的数据放到USART_RXBUF[20] 
            ++RXCUNT;
        }
    }
}
stm32f10x.c