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.主函数这样写:

运行可看到现象:

相关推荐
VekiSon26 分钟前
Linux内核驱动——杂项设备驱动与内核模块编译
linux·c语言·arm开发·嵌入式硬件
来自晴朗的明天2 小时前
14、光耦隔离电路(EL3H7)
单片机·嵌入式硬件·硬件工程
G***技2 小时前
杰和IB3-272:以低功耗高性能打造新一代工业智能交互核心
单片机·嵌入式硬件·物联网
czhaii3 小时前
STC AI8052U单片机特点
单片机
MAR-Sky3 小时前
keil5中数据的不同定义和单片机(以stc8为例)里的对应关系(idata,xdata,data,code)
单片机·嵌入式硬件
项目題供诗5 小时前
51单片机入门(八)
单片机·嵌入式硬件·51单片机
羽获飞5 小时前
从零开始学嵌入式之STM32——9.STM32的时钟系统
stm32·单片机·嵌入式硬件
飞睿科技6 小时前
乐鑫智能开关方案解析:基于ESP32-C系列的低功耗、高集成设计
嵌入式硬件·物联网·esp32·智能家居·乐鑫科技
来自晴朗的明天7 小时前
13、NMOS 电源防反接电路
单片机·嵌入式硬件·硬件工程
17(无规则自律)7 小时前
深入浅出 Linux 内核模块,写一个内核版的 Hello World
linux·arm开发·嵌入式硬件