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

运行可看到现象:

相关推荐
山木嵌入式6 小时前
【STM32实战】轻量级任务调度器实现
stm32·单片机·rtos·任务调度器·裸机开发
guygg886 小时前
基于霍尔传感器的BLDC控制源码
单片机·嵌入式硬件
ytttr8737 小时前
DSP 28335 CAN总线通信程序
开发语言·stm32·单片机
一枝小雨9 小时前
RISC-V架构sp寄存器 & RISC-V架构下FreeRTOS任务上下文保存与恢复
单片机·架构·嵌入式·risc-v·rtos·内核原理
BW.SU10 小时前
PackagingTool 嵌入式资源打包合并工具
单片机·二进制·嵌入式开发·资源合并软件·图片打包
长安第一美人10 小时前
工业级实时监控系统开发:PHP+ZMQ+JS 前后端分离架构全解析
前端·嵌入式硬件·架构·交互·rk3588·zmq后端
田甲10 小时前
STM32开发环境迁移实践:从 CubeMX 生成 CMake 工程到 VS Code 编译与调试
stm32·单片机·嵌入式硬件
hoiii18710 小时前
在 STM32F1上读取 BMX055 三轴加速度
stm32·单片机·嵌入式硬件
嵌入式小站11 小时前
STM32 零基础可移植教程 04:按键输入,为什么按下去读到的是 0 或 1
chrome·stm32·嵌入式硬件
三佛科技-1873661339711 小时前
BP8522D贴片SOP7,5V150mA高集成度无VCC电容降压型恒压芯片解析
单片机·嵌入式硬件