5,串口编程---实现简单的用串口发送接收数据

单片机通过串口向PC机发送数据

PC机通过串口接收单片机发过来的数据

1.UART和USART的区别:

USART支持同步通信方式,可以通过外部时钟信号进行同步传输,而UART仅支持异步通信方式

本开发板STM32F103ZET6有5个串口,用串口1作调试串口,因为串口通信和一键下载电路连接到了串口1上面,所i用串口1做调试串口

PA9因为传输输出的数据有高有低,串口1是外设,复用推挽输出,

PA10输入模式,只要不是模拟输入就行

1.IO初始化:PA9
usart外设初始化,另外需要写串口外设启动函数:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
中断初始化,

2,写串口发送和接收函数

3,主函数调用

1,IO初始化:PA9

usart外设初始化,另外需要写串口外设启动函数:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
中断初始化,
复制代码
//PA9复用推挽输出  PA10浮空输入
void Usart_Init(void)
{
	//GPIO 开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//库函数编程 IO初始化
	GPIO_InitTypeDef GPIO_InitStructure={0}; //定义结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//2外设初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	USART_InitTypeDef USART_InitStructure={0}; 
	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_Tx | USART_Mode_Rx; 
	USART_Init(USART1, &USART_InitStructure); 
	
	USART_Cmd(USART1, ENABLE); //使能USART1 外设
	
	//中断初始化
	NVIC_InitTypeDef NVIC_InitStructure={0}; 
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断通道:stm32f10x.h中
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure); 
	//开启串口1接收中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 
}

因为还没有写中断源,不能判断是哪个中断,所以先不写中断服务函数USART1_IRQHandler

2,写串口发送和接收函数

串口的作用是通信,收发信息,所以先写串口的收发操作:发送函数和接收函数

发送函数:1,等待发送寄存器为空,也就是等待上一次数据发送完毕,所以需要一个能够获取串口的寄存器状态的函数,查看串口相关的库函数找到USART_GetFlagStatus (检查指定的 USART 标志位设置与否),等待发送寄存器为空:由下图知,当TXE等于1,即==SET,数据已经被转移到移位寄存器,表示数据已经发送完毕,

然后发送数据,查看串口相关的库函数找到串口发送函数USART_SendData(通过外设 USARTx 发送单个数据)

接收函数分析同上,只不过接收函数需要另外定义变量接收函数返回值

复制代码
void Usart_Send(uint8_t data)
{
	//等待发送数据寄存器为空(等待上一次数据发送完毕)
	//当不为1时,也就是数据没有发送完毕,进入循环,不执行发数据
	//等于1发送寄存器为空,上一次数据发送完毕,可以发送数据了,所以不进入循环,直接执行发送数据函数
	while( USART_GetFlagStatus(USART1, USART_FLAG_TXE)!=SET){} //参考手册--中文P540
	//通过外设 USARTx 发送单个数据,库函数
		USART_SendData (USART1,data);
}

uint8_t Usart_Rece(void)
{
	//等待接收数据寄存器为空(等待上一次数据发送完毕)
		while( USART_GetFlagStatus(USART1, USART_FLAG_RXNE)!=SET){} //参考手册--中文P540
		//接收数据
		uint8_t data = USART_ReceiveData(USART1);
		return data;
}

使用该函数可以实现打印串口发送的函数,(为什么代码这样写?官方规定的就是这样)

复制代码
#include "stdio.h"
//fputc发送一个,串口打印数据
int fputc(int a,FILE *p)
{
	//串口发送函数
	Usart_Send(a);
	return a;
}

3.主函数这样写:

运行可看到现象:

相关推荐
木子单片机5 分钟前
基于51单片机温度上下限报警设计 数码管显示
stm32·单片机·嵌入式硬件·51单片机·keil
森利威尔电子-1 小时前
森利威尔SL3180 替换LTC3639 150V降压恒压芯片 3A峰值电流能力转换效率高 静态电流低
单片机·嵌入式硬件·集成电路·芯片·电源芯片
qq_401700412 小时前
合宙4G模块Air724UG
嵌入式硬件
yugi9878382 小时前
基于51单片机的篮球计分器设计
单片机·嵌入式硬件·51单片机
编程之升级打怪2 小时前
什么是PWM
嵌入式硬件
zmj3203243 小时前
单片机内存在C 语言编译后的 “逻辑分区”
c语言·单片机·内存分区
魈学习ing4 小时前
IO口无法外部上拉到3.3V以上,或被钳位到3.8V左右
stm32
小柯博客4 小时前
STM32MP2 Secure Boot实战
stm32·单片机·嵌入式硬件
Ww.xh4 小时前
STM32调用AI接口完整教程
stm32·单片机·嵌入式硬件
ZYNQRFSOC4 小时前
基于安路PH2A系列FPGA的JESD204B接口测试
嵌入式硬件·fpga开发