当前位置: 首页 > news >正文

imx6 配置串口波特率_STM32F103 串口的使用方法

串口通讯简介:

串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式。

通讯结构

设备内部一般以TTL电平传输,设备之间是通过RS232/RS485电平标准传输。

两个设备或者器件要想实现串口通讯,要电平匹配才能够正常通讯。

电平标准

根据使用的电平标准不同,串口通讯可分为 RS232标准及TTL标准,具体标准如下:

f274d403e4c1af697ca8a843ec34a1b4.png

在电子电路中,模块之间常使用TTL的电平标准,但其抗干扰能力较弱,为了增加串口的通讯距离及抗干扰能力,使用RS-232电平标准在设备之间传输信息,经常使用MA3232芯片对TTL电平及RS-232电平进行相互转换。

协议层

1.数据包

串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备得RXD接口,在协议层中规定了数据包的内容,具体包括起始位、主体数据(8位或9位)、校验位以及停止位,通讯的双方必须将数据包的格式约定一致才能正常收发数据。

2.波特率

由于异步通信中没有时钟信号,所以接收双方要约定好波特率,即每秒传输的码元个数,以便对信号进行解码,常见的波特率有4800、9600、115200等。STM32中波特率的设置通过串口初始化结构体来实现。

3.起始和停止信号

数据包的首尾分别是起始位和停止位,数据包的起始信号由一个逻辑0的数据位表示,停止位信号可由0.5、1、1.5、2个逻辑1的数据位表示,双方需约定一致。STM32中起始和停止信号的设置也是通过串口初始化结构体来实现。

4.有效数据

有效数据规定了主题数据的长度,一般为8或9位,其在STM32中也是通过串口初始化结构体来实现的。

5.数据校验

在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、 0 校验(space)、 1 校验(mark)以及无(noparity)。这些也都可以在串口初始化结构体中实现的。

串口是我们常用的一个数据传输接口,STM32F103系列单片机共有5个串口,

ea6b10857b24c953d9cd43598005315d.png

其中1-3是通用同步/异步串行接口USART(Universal Synchronous/Asynchronous Receiver/Transmitter),

4、5是通用异步串行接口UART(Universal Asynchronous Receiver/Transmitter)。

STM32比51单片机好用的一个地方就是串口比较多,51单片机一般只有2个串口,有时不够用。

下面以USART1为例,说明一下STM32串口设置的一般步骤:

1) 串口时钟使能,GPIO 时钟使能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟

2) GPIO端口设置

设置发送和接收引脚的信息,将Tx(发送引脚)配置为推挽复用模式用来发送数据,Rx(接收引脚)配置为浮空输入模式用来接收数据。

GPIO_InitTypeDef GPIO_InitStructure;//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9   //USART1_RX      GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10

3)Usart1 NVIC 配置(如果需要开启中断,才进行本步骤的设置)

NVIC_InitTypeDef NVIC_InitStructure;//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;     //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;           //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化NVIC寄存器//如果需要接收串口数据,则开启串口接收中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断

4) 串口参数初始化

USART_InitTypeDef结构体,内部包含串口通讯相关工作参数:

typedef struct {    uint32_t USART_BaudRate; // 波特率    uint16_t USART_WordLength; // 字长    uint16_t USART_StopBits; // 停止位    uint16_t USART_Parity; // 校验位    uint16_t USART_Mode; // USART 模式    uint16_t USART_HardwareFlowControl; // 硬件流控制} USART_InitTypeDef;
USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1

5) 使能串口

USART_Cmd(USART1, ENABLE);                    //使能串口1

6) 编写串口发送函数

//发送一个字节void USART1_Send_Byte(u8 Data)                     {    USART_GetFlagStatus(USART1, USART_FLAG_TC);        USART_SendData(USART1,Data);    while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );}//发送字符串,遇到字符串结尾标志'0'结束void USART1_Send_String(u8 *Data)                 {    while(*Data)        USART1_Send_Byte(*Data++);}//按长度发送字符串,这种方法可以发送含0x00的字符串void USART1_Send_String_By_Lens(u8 *Data, int Len){    int i;    for(i=0; i

7) 编写中断处理函数

//串口1中断服务程序,此接收的数据是以0x0D、0x0A结尾为标志的数据帧。void USART1_IRQHandler(void)                    {    u8 Res;    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)    {        USART_ClearFlag(USART1, USART_IT_RXNE);             //清除标志位                Res =USART_ReceiveData(USART1);    //读取接收到的数据                if((USART_RX_STA&0x8000)==0)//接收未完成        {            if(USART_RX_STA&0x4000)//接收到了0x0d            {                if(Res==0x0D)                    USART_RX_STA|=0x4000;                else if(Res!=0x0a)                    USART_RX_STA=0;//接收错误,重新开始                else                    USART_RX_STA|=0x8000;    //接收完成了            }            else //还没收到0X0D            {                    if(Res==0x0d)                    USART_RX_STA|=0x4000;                else                {                    USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;                    USART_RX_STA++;                    if(USART_RX_STA>(USART_REC_LEN-1))                        USART_RX_STA=0;//接收数据错误,重新开始接收                      }                     }        }     }}

接收完数据之后,在main函数中对接收到的数据进行处理。

if(USART_RX_STA&0x8000){    //得到此次接收到的数据长度,即USART_RX_BUF数组中的有效数据长度    uart1Len=USART_RX_STA&0x3f;                                   //对接收到的数据进行数据处理,接收的数据暂存在USART_RX_BUF数组中       //... ...                 USART_RX_STA=0;       memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF));        //清空数组  }

串口应用:

  • 与TTL串口传感器或模块直接通讯;
  • 转为RS232与PC通讯;
  • 转为RS485与485部件的传感器或器件通讯;

USB转串口的原理图:

0e113249468ec10c4c79dd01226ebf15.png

使用CH340C芯片的话,就可以省略外部晶振了,可以节省PCB布局空间;

win7系统一般选择CH340作为USB转串口驱动,Win10系统下选择CH341驱动作为USB转串口驱动;

TTL串口转RS232原理图:

f45dc9bf6271e52f2be739cdc02d72f1.png

TTL串口转RS485原理图:

e69765b20754f8553d3e2e363e336d1c.png

RS485总线一般使用时默认处于接收状态。

参考资料:

【正点原子】MiniSTM32开发板资料

喜欢请关注微信公众号:程序员小哈

有啥想玩的模块,留言给我,咱们一起玩

e20921d7c343c292414545b1deb88168.png

相关文章:

  • 十天征服单片机百度云_单片机学习「1」 初始51单片机
  • jpa删除数据后数据库无修改_Java编程第46讲——强大、奇妙的数据库操作工具JPA...
  • 有赞小程序源码_有赞小程序商城怎么开通,如何收费?
  • docker pycharm 连接_七、连Pycharm都不知道怎么用,学什么Python
  • github图片_通过这个 Go 项目搭建一个图片服务器竟然这么简单
  • pecs_神奇的PECS是什么?看看BCaBA教师们怎么说
  • 仿生蛇类机器人 特点_仿生科技成为机器人技术发展最快的领域之一
  • ue4 曲线图实现 蓝图_UE4[蓝图]只需一秒!最速实现【二段跳】
  • 临键锁如何实现幻读_阿里面试:如何用Redis实现分布式锁?
  • 相机裁剪旋转_测试版的Windows 10相机应用程序开始支持文档扫描
  • eve战巡族伤害_新版本各族3级战巡资料【纯手打】
  • 索尼的hlg是什么_hlg(索尼hlg和slog的区别)
  • 卷积过滤器的宽度_02卷积层与池化层中的核与过滤器
  • yum mysql5.5_yum安装mysql5.5及修改root密码
  • php mysql 二进制_用mysql存储二进制数据流
  • ES6指北【2】—— 箭头函数
  • 【技术性】Search知识
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Bootstrap JS插件Alert源码分析
  • Electron入门介绍
  • JavaScript服务器推送技术之 WebSocket
  • javascript数组去重/查找/插入/删除
  • java取消线程实例
  • JS数组方法汇总
  • js学习笔记
  • mysql常用命令汇总
  • OSS Web直传 (文件图片)
  • Python打包系统简单入门
  • SpringCloud集成分布式事务LCN (一)
  • TypeScript实现数据结构(一)栈,队列,链表
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 我这样减少了26.5M Java内存!
  • 一文看透浏览器架构
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #if #elif #endif
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (3)(3.5) 遥测无线电区域条例
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (安卓)跳转应用市场APP详情页的方式
  • (二十四)Flask之flask-session组件
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (南京观海微电子)——I3C协议介绍
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息