STM32 CubeIDE 通信协议实验

(该文章主要基于UART串口通信)

Goal

实现UART串口的自发自收,即PC发送数据给STM32然后再传输,将CubeMX代码移植到CubeIDE中。

Background

UART(蓝牙模块) vs  SPI(W25Q16 flash) vs  IIC(MPU6050,OLED)

逻辑分析仪(抓波形,用于协议解码、调试)vs示波器(运算、模拟)

通信协议目的:协议双方进行数据交互,先编码,以电平形式在电线上传输,再解码

通信协议三种模式:1. 半双工(IIC)2. 全双工(UART, SPI)3. 单工(只能收或者只能发)

UART(异步通信):

异步通信没有时钟,协定好每bit多少时间然后去采集,协定的时间叫做波特率,单片机和PC双方需协同一样的波特率。

TX发送端  RX接收端  GND标准口(作为电平高低参考值)

默认高电平,拉低电平为起始信号,传出8bits数据(人为设定数据位),采集到停止信号则拉高电平

STM32 CubeIDE 通信协议实验_第1张图片 

图 1 UART异步通信

IIC(同步通信):

SCL时钟    SDA传出数据、信号(这根线一个时间段只能一个从机使用)

SCL默认高电平,不像系统时钟一直有脉冲,SCL需要被触发。SDA默认高电平,当SDA先拉低作为起始信号,然后触发SCL也拉低,产生八个脉冲(人为设定8个数据位),也即上升沿采样,传出8bit数据,然后有第九个脉冲作为应答信号,第九个脉冲后有继续和停止两个选项,停止的话SCL先拉高,SDA随即拉高产生停止信号。继续和停止使用的编解码方式不一样。

可以实现一主多从,主机上的SCL和SDA对应不同的从机。每个从机有特定地址,发送地址锁定从机而对从机进行操作。

STM32 CubeIDE 通信协议实验_第2张图片

图 2 IIC

SPI:

片选CS    MOSI    MISO    SCK  

由一条数据线发送一条接受实现全双工

SCK,MISO,MOSI主机的三根线连到从机,用不同片选信号选中从机,即多根CS线,e.g. CS1控制从机1,CS2控制从机2,CS3控制从机3,如此类推。         

CS拉低则选中对应从机,作为起始信号,CS拉高为停止信号。SCK在这之间产生时钟脉冲,SPI不一定上沿采样,可选择。一些重要参数的配置:CPHA=0用于设置第一个上升沿开始进行周期采样,CPHA=1为第一个下降沿开始进行周期采样;CPOL=0则SCK信号默认低电平,CPOL=1则SCK信号默认高电平。

STM32 CubeIDE 通信协议实验_第3张图片 

图 3 SPI

通用同步异步收发器USART

UART vs USART:USART的信号线和时钟为同步的,而UART为异步通信。

STM32 CubeIDE 通信协议实验_第4张图片

图 4 USART框图

跨时钟域处理

STM32单片机通过CPU或DMA传到发送数据寄存器TDR,再发送到移位寄存器,在通过TX信号线将数据传输出去。

STM32接收数据则从RX信号线接收,先到移位寄存器,再到接收数据寄存器RDR,再传输到CPU。CPU工作时钟168MHz,USART1挂载在APB2上即84MHz,RX为一周期115200波特率,即11.52MHz和84MHz不匹配,因此引入寄存器,先让信号放入FIFO中缓存,为第一个时钟域,慢信号被缓存再被快速采集。

STM32 CubeIDE 通信协议实验_第5张图片 

图 5 USART1挂载在APB2时钟上

中断事件的一些事件标志位很重要,用于代码的理解。

STM32 CubeIDE 通信协议实验_第6张图片 

图 6 USART中断请求的一些事件标志位

单片机传输发送数据可以直接发送。

单片机接收数据则要用中断,因为要做好准备接收,如果在while里面写接收程序,因为while里面除了接收程序还有其他程序,当运行到其他程序而数据传入时会无法接收,因此需要将接收程序写入中断,而中断可以看作是程序中有最高优先级的,所以将接收程序写进中断。

Experiment Steps

在芯片手册找到USART1_TX和USART1_RX对应的接口为PA9和PA10。将其设置为推挽输出,其他参数为默认值。

STM32 CubeIDE 通信协议实验_第7张图片

图 7 USART1对应接口

参数设置115200波特率  8bit数据位。

需要打开STM32的中断,使能USART1 global interrupt。

初始化串口设置中断。

RXNE寄存器判断是否接收到信息,调库USART_ReceiveData(USART1),8bits接收数据,若采集到16bits数据,截取低8bits,因为人为设定数据位为8bits。高的8bits为零,低的8bits为接收数据。

通过检测回车加换行\r\n判断发送数据的结尾。

位宽:认为定义数据位为8bit,因为还有\r\n占两位,所以8+2=10bit,需要16bits接收。

编写程序时用debug一步步走,看到当接收1的时候对应了0x31(为1的ASCII码),它为ASCII码编码,若检测到\r则第14位(用16bits接收,0-15,所以倒数第二位为第14位)接收位设置为1,检测到\n则第15位接收位设置为1。

高位数据对应地址低位01000000...   \r对应0x0d  \n对应0x0a   

传输的数值放到BUF中缓存

8000即\n位为1标志结束,将其通过串口发回来。

Code: (该代码部分参考了已有文章)

#include "main.h"
UART_HandleTypeDef huart1;
char RxBuf[4];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  HAL_UART_Receive_IT(&huart1,(uint8_t *)RxBuf,1);
  while (1)
  {
  }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){
	if(UartHandle->Instance == USART1){
		HAL_UART_Transmit(&huart1, (uint8_t *)RxBuf, 1, 0XFFFF);
		HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuf, 1);
	}
}

Result

能够成功收发数据。

STM32 CubeIDE 通信协议实验_第8张图片

图 8 Result

 

你可能感兴趣的:(STM32,CubeIDE,漫漫学习路,stm32,单片机,arm,ide)