USART(通用同步/异步收发器):

USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里

数据帧格式:起始位(12位)+数据位(8~9位)+停止位(0.5,1,1.5,2位)

校验位:奇校验、偶校验、无校验

波特率:每秒钟最多传输多少位(常用9600、15200、921600)


USART的初始化配置

//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
//把PA9配置为复用推挽输出,供USART的TX使用
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化PA10引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//可选浮空或上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
 
//初始化USART 9600波特率 无流控 无校验 8位字长 1位停止位 选择发送和接收模式
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;//波特率
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//串口模式
USART_InitStructure.USART_Parity=USART_Parity_No;//校验位选择无校验
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位长度
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长选择8位
USART_Init(USART1,&USART_InitStructure);
	
//开启RXNE标志位到NVIC的输出
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
//优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
	
USART_Cmd(USART1,ENABLE);

USART1的TX和RX分别对应PA9和PA10,PA9应该配置成复用输出推挽模式


接受一个数据:

一、使用中断触发接收数据,首先开启RXNE到中断的通道,用USART_ITConfig函数,再配置NVIC优先级分组等参数。

RXNE:数据寄存器非空(Read data register not empty) RXNE = 1:收到数据;RXNE = 0:接收数据失败。

void USART1_IRQHandler(void)
{
	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
	{
        //进行的操作
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);//若读出收到的数据,不用手动清零
	}
}

二、在主函数里不断判断RXNE标志位,如果置1,就说明收到数据了,再调用ReceiveData,读取DR寄存器。

int main(void)
{
    OLED_Init();
    Serial_Init();

    while(1)
    {
        if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
        {
            RxData = USART_ReceiveData(USART1);
            OLED_ShowHexNum(1, 1, RxData, 2);
        }
    }
}

发送一个数据

发送数据使用函数USART_SendData,发送完后判断TxE标志位

TxE:发送数据寄存器空(Transmit data register empty)1:数据已经被转移到移位寄存器;0:数据还没有被转移到移位寄存器

发送数据前检查TxE标志位,防止数据被覆盖

//发送一个数据
void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1,Byte);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//TXE发送数据寄存器空标志位,为1即空
	//硬件会将标志位清零
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐