STM32微控制器之全双工串口通信USART的使用方法

USART:通用同步/异步串行接收/发送器(Universal Synchronous/Asynchronous Receiver/Transmitter),通常称作USART。是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。
UART:通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),它是在USART 基础上裁剪掉了同步通信功能,只有异步通信。
简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本上都是UART。

仿真软件:Proteus 8.11 SP0,仿真STM32F103R6微处理器USART,代码如下:

一、USART初始化配置

void USART1_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	// Configure USART1 Tx as alternate function push-pull
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// Configure USART1 Rx as input floating
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// Configure USART1
	USART_InitStructure.USART_BaudRate = 9600;
	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(USART1, &USART_InitStructure);
	
	// NVIC configuration
	NVIC_Configuration();
	
	// Enable USART1 Receive and Transmit interrupts
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
	
	// Enable the USART1
	USART_Cmd(USART1, ENABLE);
}

二、嵌套向量中断控制器NVIC的配置

static void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	// Configure the NVIC Preemption Priority Bits
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	// Enable the USART1 Interrupt
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

三、中断处理函数

void USART1_IRQHandler(void)
{
	uint16_t temp;
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		temp = USART_ReceiveData(USART1);
		USART_SendData(USART1, temp);
	}
	
	if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
	{
		// Nothing to do
	}
}

四、常用函数实现

// 发送一个字节
void USART_SendByte(USART_TypeDef *USARTx, uint8_t c)
{
	USART_SendData(USARTx, c);
	
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
	{
		__asm("nop");
	}
}

// 发送一个字符串
void USART_SendString(USART_TypeDef *USARTx, char *str)
{
	while(*str)
	{
		USART_SendByte(USARTx, *str++);
	}

	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
	{
		__asm("nop");
	}
}

// 使能C语言标准库函数printf
// Retargets the C library printf function to the USART1
int fputc(int ch, FILE *f)
{
	// Place your implementation of fputc here
	// e.g. write a character to the USART1
	USART_SendData(USART1, (uint8_t)ch);
	
	// Loop until the end of transmission
	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
	{
		__asm("nop");
	}
	
	return ch;
}

// 使能C语言标准库函数scanf
int fgetc(FILE *f)
{
	while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
	{
		__asm("nop");
	}
	
	return (int)USART_ReceiveData(USART1);
}

五、主函数

#include "stm32f10x.h"
#include "bsp_usart.h"

int main(void)
{
	USART1_Config();
	
	USART_SendString(USART1, "Good Luck!\r\n");
	printf("The People's Republic Of China\r\n");
	
	for(uint8_t i=1; i<10; i++)
	{
		for(uint8_t j=1; j<10; j++)
		{
			printf("%u * %u = %u\r\n", i, j, i*j);
		}
	}
	
	while(1)
	{
		__asm("nop");
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *