STM32&串口(串口基础)

串口整个东西可以说但凡你要碰单片机,想做点上点档次的东西的话那你就包用它的。32的串口配置并不难,哪怕是比起51其实也难不到哪去。

目录

一.通信基础

1.通信方式

2.通信速率

二.串口基础

1.串口的数据帧结构(协议)

2.STM32中的USART

三.串口程序配置

1.接收的同时发送一位数据

2.非常经典的不等长数据配置

好了就这些,祝你看完就会。


一.通信基础

1.通信方式

1.你要知道什么叫:半双工通信;全双工通信;单工通信;这些的定义是什么就可以了。因为再配置中其实串口是可以配置成其中的某一种的。当然了,全双工是最常用的一种。由于都比较简单,这里就不多赘述。

2.同步通信与异步通信:
定义是这样的:
同步通信:发送和接收双方按照预定的时钟节拍进行数据的发送和接收,双方的操作严格同步。 异步通信:双方不需要严格的时钟同步,每一帧数据通过起始位和停止位分割,接收方可以 独立地识别每个数据块。

让我来暴力的给你总结一句话:同步的有时钟线,异步的咩有时钟线。

2.通信速率

比特率:比特率是指在单位时间内可以发送的二进制数量,也就是信息发送速率。
波特率:波特率本质上是单位时间内信号调制的次数,决定了单位时间内能发送出多少码元。

二.串口基础

1.串口的数据帧结构(协议)

启动位:它是一个逻辑0(低电平)的信号。告诉接收方数据传输即将开始。

停止位:停止位是一个逻辑高电平1,用于指示数据传输的结束。

有效数据位:就是二进制数据,由一堆高低电平组成。这里有个重点是:串口是按位发送的,而这里是低位先发送

校验位:校验数据完整性的,主要看数据包中的1的数量和对用的是否一致。但是不咋用因为不准确,不准确了自然用的就少了。

2.STM32中的USART

1.可以是异步也可以是同步
2.拥有一个硬件流控制器,其实就是用硬件来强行匹配接--收的速率匹配来降低丢包率的。
3.拥有一个波特率发生器,一般最高可以4.5MB/s
4.USART的框图:

5.USART的常用寄存器的位:
 

其中:
TXE                           发送空中断
TC                             发送完成中断                                                      
RXNE                        接收非空中断(读取后自动RESET)
IDLE                          空闲中断
TE&RE                      发送/接收使能

其中空闲中断由软件复位。

三.串口程序配置

1.接收的同时发送一位数据

串口的配置方式和GPIO,TIM等外设配置一致的相似:

void uart_init(uint32_t bundrate){
	
	uart_handle.Instance = USART1;
	uart_handle.Init.BaudRate = bundrate;
	uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	uart_handle.Init.Mode = UART_MODE_TX_RX;
	uart_handle.Init.Parity = UART_PARITY_NONE;
	uart_handle.Init.StopBits = UART_STOPBITS_1;
	uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
	HAL_UART_Init(&uart_handle);
}

随后是非常经典的MSP配置:

void HAL_UART_MspInit(UART_HandleTypeDef *huart){
	__HAL_RCC_USART1_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	//TX初始化为复用推挽输出
	GPIO_InitTypeDef gpio_init;	
	gpio_init.Mode = GPIO_MODE_AF_PP;
	gpio_init.Pin = GPIO_PIN_9;
	gpio_init.Pull = GPIO_PULLUP;
	gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&gpio_init);
	//RX初始化为浮空输入
	gpio_init.Mode = GPIO_MODE_AF_INPUT;
	gpio_init.Pin = GPIO_PIN_10;
	HAL_GPIO_Init(GPIOA,&gpio_init);
	
	HAL_NVIC_SetPriority(USART1_IRQn,2,2);
	HAL_NVIC_EnableIRQ(USART1_IRQn);
	
	__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);
	__HAL_UART_ENABLE_IT(huart,UART_IT_IDLE);
}

这里有个重点是GPIO的两个口一个是推挽输出一个是浮空输入,如果你基础就知道使用推挽输出是为了保证数据逻辑电平不被GPIO内设的电压影响,使用浮空输入也是如此,把控制电压的控制权交出去。如果你不知道原因,也可以直接用以下推荐:

中断部分:

void USART1_IRQHandler(){
	uint8_t data;
	if(__HAL_UART_GET_FLAG(&uart_handle,UART_FLAG_RXNE) != RESET){
		HAL_UART_Receive(&uart_handle,&data,1,500);    //接收
		HAL_UART_Transmit(&uart_handle,&data,1,500);   //发送
	}

}

2.非常经典的不等长数据配置

配置方面一样,唯一不同的就是这里使用了空闲中断,该中断在被使能后会在接收完所有数据后空闲时发起一个中断,检测该中断是否触发就可以完整的收取数据:

void USART1_IRQHandler(){
	uint8_t rev_data;
	if(__HAL_UART_GET_FLAG(&uart_handle,UART_FLAG_RXNE) != RESET){
		HAL_UART_Receive(&uart_handle,&data,1,1000);
		rev_buf[len++] = rev_data;	
	}
	
	if(__HAL_UART_GET_FLAG(&uart_handle,UART_FLAG_IDLE) != RESET){
		HAL_UART_Transmit(&uart_handle,&rev_data,sizeof(rev_buf),500);
		memset(rev_buf,0,sizeof(rev_buf));
		len = 0;
		__HAL_UART_CLEAR_IDLEFLAG(&uart_handle);	//软件清零
	}
	
}

注意sizeof对数组使用时返回的是整个数组的字节数,这里可以使用sizeof直接测量数组的长度是因为串口的数据为设置位8位,所以在定义时使用了uint8_t。故而只是数值上相等。

好了就这些,祝你看完就会。

点个关注8

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值