STM32入门笔记10_USART串口通信+案例:上位机控制LED亮灭(USART串口通信、TIM定时器、EXTI综合案例)

这篇具有很好参考价值的文章主要介绍了STM32入门笔记10_USART串口通信+案例:上位机控制LED亮灭(USART串口通信、TIM定时器、EXTI综合案例)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

USART串口通信

通信接口

  • 通信的目的: 将一个设备的数据传送到另一个设备, 扩展硬件系统
  • 通信协议: 制定通信的规则, 通信双方按照协议规则进行数据收发
名称 引脚 双工 时钟 电平 设备
USART TX、RX 全双工 异步 单端 点对点
I2C SCL、SDA 半双工 同步 单端 多设备
SPI SCLK、MOSI、MISO、CS 全双工 同步 单端 多设备
CAN CAN_H、CAN_L 半双工 异步 差分 多设备
USB DP、DM 半双工 异步 差分 点对点

USART有同步和异步两种通讯方式, 但同步只用作特殊功能, 一般只使用异步通讯

串口通信

  • 串口是一种应用十分广泛的通讯接口, 串口成本低, 容易使用、通信线路简单, 可实现两个设备的互相通信
  • 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信, 极大地扩展了单片机的应用范围, 增强了单片机系统的硬件实力

通信方式

串行通信与并行通信

  • 串行通信: 数据字节一位位地依次传送的通信方式, 串行通信的速度慢, 但用的传输线条数少, 成本低适用于远距离的数据传送
  • 并行通信: 数据字节的各位同事传送的通信方式, 优点是数据传送速度快, 缺点是占用的传输线条数多, 适用于近距离通信, 远距离通信的成本较高

串行异步通信和串行同步通信

异步通信:

一次通信传送一个字符帧, 发送的字符之间的时间间隔可以是任意的, 优点是通信设备简单、价格低廉, 但因为具有起始位和停止位, 传输效率较低

同步通信:

进行通信前先建立同步, 发送频率和接受方的接受频率要同步。在发送信息时, 将多个字符加上同步字符组成一个信息帧, 有一个统一的时钟控制发送端的发送, 接收端识别到同步字符后, 就认为开始一个信息帧, 此后位数作为实际传输信息处理。优点: 传输速度较快, 可用于点对多点 缺点: 需要使用专用的时钟控制线实现同步, 对于长距离通信成本较高, 通信速率也会降低。一般用于同一PCB上芯片级之间的通信

串口参数及时序(串行异步通信)

  • 波特率: 串口通信的速率
  • 起始位: 标志一个数据帧的开始, 固定为低电平
  • 数据位: 数据帧的有效载荷, 1为高电平, 0为低电平, 低位先行
  • 校验位: 用于数据验证, 根据数据位计算得来
  • 停止位: 用于数据帧间隔, 固定为高电平

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

硬件电路

  • 简单双向串口通信有两根通信线(发送端TX和接受端RX)
  • TX与RX需要交叉连接
  • 当只需单向的数据传输时, 可以只接一根通信线
  • 当电平标准不一致时, 需要加电平转换芯片

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

电平标准

  • 电平标准是数据1和数据0的表达方式, 是传输线缆中人为规定的电压与数据的对应关系, 串口常用的电平标准有如下三种:
  • TTL电平: +3.3V或+5V表示1, 0V 表示0
  • RS232电平: -3~-15V表示1, +3~+15V表示0
  • RS485电平: 两线压差+2~+6V表示1, -2~-6V表示0(差分信号)

差分信号的干扰小, 一般TTL电平和RS232电平传输距离只有十几米, 而RS485电平的传输范围可达数千米

串口时序

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

USART简介

  • USART(Universal Synchronous/Asynchronous Receiver/Transmitter) 通用同步/异步收发器
  • USART是STM32内部集成的硬件外设, 可根据数据寄存器的一个字节数据自动生成数据帧时序, 从TX引脚发送出去, 也可自动接收RX引脚的数据帧时序, 拼接为一个字节数据, 存放在数据寄存器里
  • 自带波特率发生器, 最高可达4.5Mbits/s
  • 可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
  • 可选校验位(无校验/奇校验/偶校验)
  • 支持同步模式、硬件流控制、DMA、智能卡、IrDA、Lin
  • STM32F108C8T6 USART资源: USART1、USART2、USART3

USART框图

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

USART基本结构

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

数据帧

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 字长包含校验位 一般情况下: 9位字长(设置奇偶校验) 8位字长(无校验)
    上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

起始位侦测

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 在一位的时间里进行16次的采样
  • 3、5、7/ 8、9、10次进行采样 且要求每3位至少应该有两个0(只有两个0会在状态寄存器里置NE, 噪声标志位)

数据采样

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 8、9、10次采样每3位也至少应该有两个0(只有两个0会在状态寄存器里置NE, 噪声标志位)

波特率发生器

  • 发送器和接收器的波特率由波特率寄存器BRR里的DIV确定
  • 计算公式: 波特率 = fPCLK2/1 /(16 * DIV)

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

案例: 上位机控制LED亮灭

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

说明:

按键输入端为PA1 采用EXTI中断

PA0输出控制LED1, PA2输出控制LED2

LED2可通过按键控制

LED1通过上位机下达指令控制

利用Timer定时器每隔十秒进入一次中断, 获取LED1和LED2的亮灭状态

硬件接线

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

PA0接LED1, PA1接按键,PA2接LED2,PA9为单片机的Tx发送端接CH3400的Rx端,PA10为单片机的Rx接收断接CH3400的Tx端

初始化USART

/*
串口通信初始化函数 抢占优先级0 响应优先级0
*/
void Serial_Init(void)  
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 配置GPIO
	// TX 发送端
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// RX 接收断
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置USART串口通信
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=9600;  // 波特率
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  // 无流控
	USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;  // 两种模式都打开
	USART_InitStructure.USART_Parity=USART_Parity_No;  // 奇偶校验
	USART_InitStructure.USART_StopBits=USART_StopBits_1;  // 停止位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;  // 8位
	USART_Init(USART1, &USART_InitStructure);
	
	// 打开USART中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // 接收寄存器非空(正在接收)
	
	// 配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动USART
	USART_Cmd(USART1, ENABLE);
}

主要代码

Serial.c
#include "stm32f10x.h"

char Down_String[] = "AABBCCDD01000000\r\n";  // 保存从下位机获取的数据
char Header[] = "AABBCCDD00";  // 协议头+数据来源
char Up_String[100];  // 保存从上位机传送来的数据
uint8_t idx;  //下标 
uint8_t Decode_Flag;
/*
串口通信初始化函数 抢占优先级0 响应优先级0
*/
void Serial_Init(void)  
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 配置GPIO
	// TX 发送端
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// RX 接收断
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置USART串口通信
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=9600;  // 波特率
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  // 无流控
	USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity=USART_Parity_No;  // 奇偶校验
	USART_InitStructure.USART_StopBits=USART_StopBits_1;  // 停止位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;  // 8位
	USART_Init(USART1, &USART_InitStructure);
	
	// 打开USART中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // 接收寄存器非空(正在接收)
	
	// 配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动USART
	USART_Cmd(USART1, ENABLE);
}

/*
	发送单个数据
*/
void Send_Byte(uint16_t Byte)
{
	USART_SendData(USART1, Byte);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完毕
}

/*
	发送字符串
*/
void Serial_SendString(char * String)
{
	uint8_t i;
	for(i=0; String[i] != '\0'; ++i)
	{
		Send_Byte(String[i]);
	}
}

/*
	向上位机传送监控的信息
*/
void Transimit_Message(void)
{
	Serial_SendString((char*)Down_String);
}

/*
	获取LED信息 LED为低电平驱动
*/
void Get_LEDInfo(void)
{
	// LED1 
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1){ // LED1灭
		Down_String[11] = '0';
	}else{
		Down_String[11] = '1';
	}
	// LED2
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==1){ // LED2灭
		Down_String[13] = '0';
	}else{
		Down_String[13] = '1';
	}
}

/*
	下位机解码上位机传送的信息
*/
uint8_t Decode_Info(char * String)
{
	for(uint8_t i=0; i < 8; ++i)
	{
		if(String[i] != Header[i])
		{
			return 0;
		}
	}
	// 判断是否有保留位
	for(uint8_t i=12; i <= 15; ++i)
	{
		if(String[i] != '0') return 0;
	}
	// 控制LED1亮灭
	if(String[10] == '0' && String[11] == '1')
	{
		// 开灯
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
	}
	else if(String[10] == '0' && String[11] == '0')
	{
		// 关灯
		GPIO_SetBits(GPIOA, GPIO_Pin_0);
	}
	else return 0;
	
	return 1;
}

/*
	根据反馈解码状态打印信息
*/
void Decode_Info_Print(void)
{
	if(Decode_Flag == 0)
	{
		// 解码失败, 请用正确的协议进行通讯
		Serial_SendString("Decoded failed!\r\nPlease ensure the communication protocol is correct!\r\n");
	}
	else
	{
		// 解码成功!LED1状态转换成功
		Serial_SendString("Decoded successful!\r\n");
	}
	Decode_Flag = 0;
}

/*
	中断函数
*/
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)  // 接受寄存器不空
	{		
		uint8_t Serial_RxData;
		Serial_RxData = USART_ReceiveData(USART1);  // 接受数据
		Up_String[idx++] = (char)Serial_RxData;
		// 清除中断标志
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}
Serial.h
#ifndef __SERIAL_H
#define __SERIAL_H
#include "stm32f10x.h"
void Serial_Init(void);
void Send_Byte(uint16_t Byte);
void Serial_SendString(char * String);
void Transimit_Message(void);
void Get_LEDInfo(void);
uint8_t Decode_Info(char * String);
void Decode_Info_Print(void);
extern char Down_String[];
extern char Header[];
extern uint8_t idx;
extern uint8_t Decode_Flag;
extern char Up_String[100];

#endif
LED.c
#include "stm32f10x.h"

/*
	初始化LED1
*/
void LED1_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_0);  // 设置高电平
}

/*
	关灯 低电平驱动
*/
void LED1_Off(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_0);
}

/*
	开灯
*/
void LED1_On(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}

/*
	翻转灯泡状态
*/
void LED1_Turn(void)
{
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1){
		LED1_On();
	}else{
		LED1_Off();
	}
}

void LED2_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_2);  // 设置高电平
}

/*
	关灯 低电平驱动
*/
void LED2_Off(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);
}

/*
	开灯
*/
void LED2_On(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}

/*
	翻转灯泡状态
*/
void LED2_Turn(void)
{
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==1){
		LED2_On();
	}else{
		LED2_Off();
	}
}
key.c
#include "stm32f10x.h"
#include "LED.h"

/*
	初始化按键 PA1 抢占优先级1 响应优先级1
*/
void Key_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	// 初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  // 上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; // PA1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置AFIO
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
	
	// 配置中断
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStructure);
	
}

/*
	按键中断函数
*/
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1) == SET)
	{
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
		{	
			LED2_Turn();
		}
		// 清除中断标志
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
}
Timer.c
#include "stm32f10x.h"
#include "Serial.h"
/*
	初始化定时器 抢占优先级0 响应优先级1 
*/
void Timer_Init(void)
{
	// RCC开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	// 选择时钟源
	TIM_InternalClockConfig(TIM2);  // 内部时钟
	
	// 配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;  // 内部时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;  // 计数模式
	TIM_TimeBaseInitStructure.TIM_Period=50000-1;  // 加载到自动重装寄存器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;  // 预分频的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;  // 重复计数器的值 
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);  //
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);  // 清除标志
	// 使能更新中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	// 配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;  // 中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动定时器
	TIM_Cmd(TIM2, ENABLE);
	return;
}

/*
	10秒钟进入一次中断 获取系统信息
*/
void TIM2_IRQHandler(void)
{
	// 判断标志位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		// 获取LED信息
		Get_LEDInfo();
		// 将信息发送给上位机
		Transimit_Message();
		// 清除标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
main.c
#include "stm32f10x.h" 
#include "delay.h"
#include "LED.h"  
#include "key.h"
#include "Timer.h"  // 定时器 10s 获取一次信息
#include "Serial.h"  // 串口相关程序
// 上位机控制LED亮灭
int main(void)
{
	LED1_Init();
	LED2_Init();
	Key_Init();
	Timer_Init();
	Serial_Init();
	while(1)
	{
		// 接收到一个完整协议的数据 进行解析
		if(idx >= 16)
		{
			// 解码
			Decode_Flag = Decode_Info((char*)Up_String);
			// 打印解码信息
			Decode_Info_Print();  
			idx = 0;
		}
	}
}

效果展示

上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言
上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言
上位机控制stm32,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

视频链接

【单片机作业: USART通信案例上位机控制LED灯亮灭】

参考资料

嵌入式单片机STM32原理及应用
【STM32入门教程-2023持续更新中】文章来源地址https://www.toymoban.com/news/detail-702503.html

到了这里,关于STM32入门笔记10_USART串口通信+案例:上位机控制LED亮灭(USART串口通信、TIM定时器、EXTI综合案例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32中常见的通信协议之USART(串口)

    USART是一种通用的串行、异步通信总线,该总线有两条数据线,可以实现全双工的发送和接收。 串口的通信速度用波特率来表示,其单位为bps(bit per second)即每秒钟传送bit的数量。 串口规定,数据线在空闲的状态下,必须是置为高电平的状态。 起始信号为低电平,因为串口

    2023年04月08日
    浏览(46)
  • STM32F4 基于USART串口的蓝牙通信

    目录 一、硬件资源 连接方案 其他配置 二、实验原理 基本定义 USART介绍 USART工作原理 数据发送 数据接收 蓝牙HM-10配置 三、代码部分 usart.c usart.h Serial.c Serial.h main.c 结语 STM32F401,OLED,蓝牙hm10 连接方案 设备1的TX与设备2的RX连接,这样设备1发送的数据可以被设备2接收到。

    2024年01月17日
    浏览(46)
  • STM32 串口通信USART1的配置和使用

    UART:universal asynchronous receiver and transmitter通用异步收发器 USART:universal synchronous asynchronous receiver and transmitter通用同步异步收发器 上图是利用寄存器配置的步骤,下面我用官方库函数配置USART1 1、要配置串口usart1,先查看数据手册以及开发板原理图的芯片管脚 根据上图可以看

    2024年02月05日
    浏览(46)
  • 【嵌入式学习-STM32F103-USART串口通信】

    4-1 基本流程 4-2 整体代码 4-2-1 main.c 4-2-2 Serial.c 4-2-3 Serial.h 5-1 查询 5-2 中断 5-3 整体代码 5-3-1 main.c 5-3-2 Serial.c 5-3-3 Serial.h 6-1 使用状态机接收数据包的思路 6-2 串口收发HEX数据包 6-2-1 main.c 6-2-2 Serial.c 6-2-3 Serial.h 6-3串口收发文本数据包 6-3-1 main.c 6-3-2 Serial.c 6-3-3 Serial.h 全双工:打

    2024年02月15日
    浏览(58)
  • STM32串口通信中的USART_RecieveData函数分析

    拿这个中断函数为例         很多人可能注意到了接收数据函数的返回类型为无符号短整型,疑惑这里为什么用了一个无符号字符类型变量rec接收。 先看看这个函数的定义         其实,是因为串口设置的字长为8,所以数据寄存器中第八位为0,第0~7位为数据有效位,

    2024年02月11日
    浏览(34)
  • 【STM32】STM32学习笔记-USART串口协议(25)

    按数据传送的方式,通讯可分为串行通讯与并行通讯,串行通讯是指设备之间通过少量数据信号线(一般是8根以下), 地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式。而并行通讯一般是指使用8、16、32及64根或更多的数据线进行传输的通讯方式, 它们的通

    2024年01月19日
    浏览(45)
  • stm32学习笔记-9 USART串口

    注:笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注:工程及代码文件放在了本人的Github仓库。 从本节开始,将逐一学习STM32的通信接口。首先介绍以下stm32都集成了什么通信外设。 为了控制或读取外挂模块,stm32需要与外挂模块进行通信,来扩

    2024年02月14日
    浏览(42)
  • 【STM32】STM32学习笔记-USART串口数据包(28)

    串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式, 电子工程师在调试设备时也经常使用该通讯方式输出调试信息。 在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和

    2024年01月18日
    浏览(40)
  • 【Qt上位机与STM32进行串口通信】-2-Qt串口开发

    系列文章目标:Qt上位机与STM32进行串口通信,控制多个LED的状态。 本篇文章的主要目标: 1、设计两个界面,串口连接界面、控制界面。 2、只有在串口连接成功才能打开控制界面。 3、打开控制界面时,串口保持连接。 4、自定义控件,提升开发效率。 以下是我入门Qt的视频

    2024年02月06日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包