简单实现通过串口打印hello(深入学习配置stm32串口USART)

通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一
个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个
UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同
步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输
出,我们平时用的串口通信基本都是 UART。
串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数
据信息、停止信息,可能还有校验信息
TX:发送数据输出引脚。
RX:接收数据输入引脚。
SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引
脚。
nRTS:请求以发送(Request To Send),n 表示低电平有效。如果使能 RTS 流控制,当
USART 接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收寄存器已满时,
nRTS 将被设置为高电平。该引脚只适用于硬件流控制
nCTS:清除以发送(Clear To Send),n 表示低电平有效。如果使能 CTS 流控制,发送
器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,如果为
高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。
USART 引脚在 STM32F103ZET6芯片具体分布见表 21-3。
表 21-3 STM32F103VET6 芯片的 USART 引脚
引脚 APB2总线 APB1总线
USART1 USART2 USART3 UART4 UART5
TX PA9 PA2 PB10 PC10 PC12
RX PA10 PA3 PB11 PC11 PD2
SCLK PA8 PA4 PB12
nCTS PA11 PA0 PB13
nRTS PA12 PA1 PB14
STM32F103VET6 系统控制器有三个 USART 和两个 UART,其中 USART1 和时钟来
源于 APB2 总线时钟,其最大频率为 72MHz,其他四个的时钟来源于 APB1 总线时钟,其
最大频率为 36MHz。UART 只是异步传输功能,所以没有 SCLK、nCTS 和 nRTS 功能引脚
在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。
名称 描述
TE
发送使能
TXE
发送寄存器为空,发送单个字节的时候使用
TC
发送完成,发送多个字节数据的时候使用
TXIE
发送完成中断使能

在接收数据时,编程的时候有几个比较重要的标志位我们来总结下。
名称 描述
RE
接收使能
RXNE
读数据寄存器非空
RXNEIE
发送完成中断使能

uart.c

#include "stdio.h"
#include "stm32f10x.h"
//初始化跟串口相关gpio
void init_uart_gpio(void)
{
	GPIO_InitTypeDef pa10;
	GPIO_InitTypeDef pa9;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//txd
	pa9.GPIO_Mode=GPIO_Mode_AF_PP;
	pa9.GPIO_Pin=GPIO_Pin_9;
	pa9.GPIO_Speed=GPIO_Speed_50MHz;
	//rxd
	pa10.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	pa10.GPIO_Pin=GPIO_Pin_10;
	
	GPIO_Init(GPIOA,&pa9);
	GPIO_Init(GPIOA,&pa10);
}
//初始化串口1
void init_uart1(void )
{
	USART_InitTypeDef usart;
	//打开串口外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	//第二步设置串口波特率,数据格式,工作参数
	usart.USART_BaudRate=115200;
	usart.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	usart.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
	usart.USART_Parity= USART_Parity_No;	
	usart.USART_StopBits=USART_StopBits_1;
	usart.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&usart);

	
}

//初始化串口中断
void init_uart_it(void )
{
	//启用串口1
	USART_Cmd(USART1,ENABLE);
	//打开串口中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
}


//开启总中断
void init_uart_nvic(void )
{
	NVIC_InitTypeDef nvic;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
  //配置中断源
	nvic.NVIC_IRQChannel = USART1_IRQn;			
	nvic.NVIC_IRQChannelPreemptionPriority = 1;	
	nvic.NVIC_IRQChannelSubPriority = 1;		
	nvic.NVIC_IRQChannelCmd = ENABLE;				
	NVIC_Init(&nvic);
	
}
//发送一个字节
void usart_sendbyte(USART_TypeDef *pUSARTx,uint8_t ch)
{
	//发送一个字节
	USART_SendData( USART1, ch);
	//等待发送成功
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){
	}
	
}



void usart_sendstring(USART_TypeDef * pUSARTx,char *data)
{
	//发送每个字符,不包含‘\0’
	while(*data != '\0')
	{
		usart_sendbyte(pUSARTx, *data);
		data++;
	
	}
	
}

int fputc(int ch,FILE *f)
{
	usart_sendbyte(USART1,ch);
	return ch;
}

//取消半主机模式
#pragma import(__use_no_semihosting)
 
struct __FILE
{
	int a;
};
 
FILE __stdout;
 
void _sys_exit(int x)
{
	
}
//总的初始化调用,等等在main中要用
void init_uart(void )
{
	init_uart_gpio();
	init_uart1();
	init_uart_it();
	init_uart_nvic();
	
}

uart.h

#ifndef MY_UART_H
#define MY_UART_H
void init_uart(void);
#endif

main.c

#include "uart.h"
#include "stdio.h"
#include "stm32f10x.h"
//延时函数
void delay(void)
{
	int i;
	int j;
	for(i=100;i>0;i--)
	{
		for(j=100;j>0;j--){
		}
	}
	
}

int main(void )
{
//初始化串口
	init_uart();
//不断向串口发数据
	while(1)
	{
		delay();
		printf("hello\n");
	}
	return 0;
}

实验结果

简单实现通过串口打印hello(深入学习配置stm32串口USART)_第1张图片

你可能感兴趣的:(stm32)