stm32——串口(USART)
·
stm32通信接口
综述一下
| 名称 | 引脚 | 方向 | 时钟 | 电平 | 设备 |
|---|---|---|---|---|---|
| USART | TX/RX | 全双工 | 异步 | TTL电平 | 点对点 |
| I2C | SDA/SCL | 半双工 | 同步 | TTL电平 | 多设备 |
| SPI | SCLK/MOSI/MISO/CS | 全双工 | 同步 | TTL电平 | 多设备 |
| CAN | CAN_H/CAN_L | 半双工 | 异步 | 差分电平 | 多设备 |
| USB | D+/D- | 半双工 | 异步 | 差分电平 | 点对点 |
简单解释一下
全双工与半双工的区别在于通信的方向性。
全双工通信允许同时进行数据的发送和接收,而半双工通信则只能在同一时间内进行数据的发送或接收,不能同时进行。
同步与异步的区别在于通信的时钟信号。
同步通信需要一个共享的时钟信号来协调数据的传输,而异步通信则不需要共享时钟,需要通信双方约定采样频率,还需要添加一些采样位置对齐的帧。
TTL电平是相对于GND的电平差,所以TTL其实还需要GND,而差分电平是两个信号线的差.
串口通信结构
1. USART(通用同步异步收发传输器)
USART是一种常用的串行通信接口,支持同步和异步两种通信模式。相较于U A R T
多了时钟输出。
UART(通用异步收发传输器)
是USART的一种异步通信模式,常用于串口通信。它通过TX(发送)和RX(接收)引脚进行数据传输,支持全双工通信。
USART基本结构
linux 查看串口
lsusb #查看USB设备
dmesg | grep ch341 #查看内核日志中与tty相关的信息
[63809.198053] usb 2-1: ch341-uart converter now attached to ttyUSB0 # 查看其映射在ttyusb0上
ls /dev/tty*
权限问题无法访问串口
ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 3月 20 18:51 /dev/ttyUSB0
这里查看ttyUSB0属于dialout组 所以要将user加入dialout组才可以使用串口调试
简单来个例子
先上代码
简单初始化一下
void UART_Init (void) {
// UART 初始化代码
__HAL_RCC_USART1_CLK_ENABLE (); // 使能 USART1 时钟
__HAL_RCC_GPIOA_CLK_ENABLE (); // 使能 GPIOA 时钟
//初始化GPIO引脚
GPIO_InitTypeDef GPIO_Init = { 0 };
GPIO_Init.Mode = GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_Init.Pin = GPIO_PIN_9;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init (GPIOA, &GPIO_Init); // 初始化 GPIOA9
usart.Instance = USART1; // 选择 USART1
usart.Init.BaudRate = 115200; // 设置波特率
usart.Init.WordLength = USART_WORDLENGTH_8B; // 8位数据位
usart.Init.StopBits = USART_STOPBITS_1; // 1位停止位
usart.Init.Parity = USART_PARITY_NONE; // 无奇偶校验
usart.Init.Mode = USART_MODE_TX; // 使能发送和接收
usart.Init.CLKPolarity = USART_POLARITY_LOW; // 时钟极性低
usart.Init.CLKPhase = USART_PHASE_1EDGE; // 时钟相位第一边沿
usart.Init.CLKLastBit = USART_LASTBIT_DISABLE; // 不输出最后一位时钟
HAL_USART_Init (&usart); // 初始化 USART1
}
void Send_Byte (uint8_t byte) {
HAL_USART_Transmit (&usart, &byte, 1, HAL_MAX_DELAY); // 发送一个字节
while (HAL_USART_GetState (&usart) != HAL_USART_STATE_READY); // 等待发送完成
}
主函数简单一个发送测试一下
int main (void) {
HAL_Init ();
OLED_Init ();
MX_GPIO_Init ();
UART_Init ();
Send_Byte (0x41);
while (1) {
}
}

- 封装一个发送数组函数
void Send_Array (uint8_t * array, uint16_t size) {
uint16_t i;
for (i = 0; i < size; i++) {
Send_Byte (array[i]); // 逐字节发送数组
}
}
uint8_t str[] = "Hello, UART!";
这里可能有疑问为什么uint可以使用字符串。字符串其实就是一个字符数组,字符在C语言中是以ASCII码的形式存储的,所以可以使用uint8_t类型来表示字符串中的每个字符。
Send_Array (str, sizeof (str) - 1); // 发送字符串,减去1是为了不发送末尾的'\0'

更多推荐

所有评论(0)