- STM32系列博客:
- STM32学习之旅① 开发环境搭建
- STM32学习之旅② 固件库的使用及工程模板的建立
- STM32学习之旅③ 从点灯到代码移植
- STM32学习之旅④ USART串口和上位机通信
- STM32学习之旅⑤ SPI控制TFT,从底层到底层的设计
目录:
文章目录
- 一、认识其本质
-
- (一)串口
- (二)协议
- (三)时序
- (四)上位机
- 二、所需材料
- 三、USART的介绍
- 四、USART串口的配置
- 五、发送函数
-
- (一)单字节发送
- (二)数据流发送
- 六、接收函数
- 七、串口打印,重定向printf函数
一、认识其本质
(一)串口
- 串口是串行接口 (Serial Interface)的简称,它是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位的传送,按位顺序进行,最少只需一根传输线即可完成;成本低但传送速度慢。串行通讯的距离可以从几米到几千米;根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。
(二)协议
- 所谓协议,就是通信双方约定好的规定,通信双方只有遵守这个规定才能够完成任务。举个栗子就是周幽王烽火戏诸侯,双方约定好以烽火为信 进行通信,但是愚蠢的周幽王为博美人褒姒一笑破坏了这个规定,最后付出的代价是惨重的。可见,通信双方只有遵守协议才能够完成通信。
(三)时序
- 时序就是协议的实际化,它实质上是一些列的脉冲信 ,通信双方将信息按照预先定好的规定(协议)转换成一系列的脉冲信 ,通过总线发送给接收方,接收方再将接收到的数据按照规定进行解析,从而得到发送方发送过来的数据。
(四)上位机
- 上位机和下位机其实是一个相对的概念,上位机指的是可以直接发出操控命令的计算机,一般指PC机,能够显示各种信 变化(液压,水位,温度等),能够将信息直接传递给人。下位机是直接控制设备获取设备状况的计算机,一般是PLC/单片机single chip microcomputer/slave computer/lower computer之类的,下位机需要PC机来对其进行控制。
二、所需材料
-
USB转TTL串口
-
串口助手, 密码:07z7
三、USART的介绍
-
stm32有丰富的通讯外设,USART(Universal Synchronous Asynchronous Receiver Transmitter)、SPI(Serial Peripheral interface)、I2c(Inter-Integrated Circuit)、CAN(Controller Area Network),因为stm32有完整的且强大的固件库,这使得配置串口的难度大大降低了,和用软件IO口模拟通信时序相比,硬件的支持可以大大提高通信的速率、大大降低出错的概率,从而提高了通信的质量和效率。用IO口模拟USART难度较大,它对延时要求比较苛刻,且出错的概率较大,所以一般很少用IO口模拟USART。IO口模拟I2c比较常见,由于I2c的最高通信速度只有3.4M/s,单片机的IO口速度可以完美驾驭。由于SPI多用于一些较高速的通信,例如LCD、OLED、TFT显示器的写入,EEPROM (Electrically Erasable Programmable read only memory)的写入和读取,用IO口模拟效果不是很理想,所以建议使用硬件自带接口。
-
关于USART,以下是官方的介绍
-
通过对stm32几个模块的操作,我们可以发现stm32外设配置的一些基本套路:打开相应的时钟->配置相应的引脚功能->声明对应的结构体->利用相应的Init函数进行初始化
-
打开打开USATT1、GPIOA、AFIO的时钟
- 配置相应的IO口,将其设为复用推挽输出和浮空输入
-
配置NVIC(Nested Vectored Interrupt Controller),即内嵌向量中断控制器,它是用来配置中断抢占优先级和从优先级(响应优先级)的
-
关于抢占优先级和响应优先级区别:
-
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
-
抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
-
抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
-
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
- 配置串口协议
五、发送函数
(一)单字节发送
- 在main函数中调用这个函数就能够完成单字节的发送了
- 打开串口助手就能够看到串口发来的数据了
- 打开串口助手可以看到串口发来的数据流
- 接收数据需要借助中断来完成
- 将接收到的数据流进行解析,用灯的亮灭将控制命令现实化
- 主函数要做的,就是循环判断是否有灯的状态需要改变,每次接收到上位机发来的命令后把当前的状态发送到上位机
#include "stm32f10x.h"#include "stm32f10x_gpio.h"#include "timer.h"#include "gpio_config.h"#include "usart.h"int main(){ SystemInit(); //初始化系统,系统时钟设定为72MHz systick_init(72); //配置systick,中断时间设置为72000/72000000 = 1us led_gpio_init(); usart_config(); tx_stack_init(); while(1) {if (key0.key_change_bit == CHGE_IN){ if((key0.led_on_off % 2) == 1) { LED0_ON; //打开LED0 tx_stack.data[0] = 0xff; } else { LED0_OFF; //关闭LED0 tx_stack.data[0] = 0x00; } key0.key_change_bit = NO_CHGE;}if (key1.key_change_bit == CHGE_IN){ if((key1.led_on_off % 2) == 1) { LED1_ON; //打开LED1 tx_stack.data[1] = 0xff; } else { LED1_OFF; //关闭LED1 tx_stack.data[1] = 0x00; } key1.key_change_bit = NO_CHGE;}if (key2.key_change_bit == CHGE_IN){ if((key2.led_on_off % 2) == 1) { LED2_ON; //打开LED2 tx_stack.data[2] = 0xff; } else { LED2_OFF; //关闭LED2 tx_stack.data[2] = 0x00; } key2.key_change_bit = NO_CHGE;}if (key3.key_change_bit == CHGE_IN){ if((key3.led_on_off % 2) == 1) { LED3_ON; //打开LED3 tx_stack.data[3] = 0xff; } else { LED3_OFF; //关闭LED3 tx_stack.data[3] = 0x00; } key3.key_change_bit =
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!
-