硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3740|回复: 16
收起左侧

[客户分享] 【持续更新】串口的基本知识你掌握了吗

  [复制链接]

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
发表于 2018-10-12 09:48:15 | 显示全部楼层 |阅读模式
本帖最后由 ssssssss 于 2018-10-22 13:56 编辑

       在做项目的时候是不是发现串口是最常用的通信接口,所以我自己整理了一下关于串口的一些常识性知识,方便自己学习。
          关键词:Loto虚拟示波器,串口时序,电平标准,模拟串口
    我们常说的串口按电平分类的话有两种,一种是TTL电平的串口,一种是232电平的串口。
首先我们先看一下这两种电平的区别。
TTL电平标准:输出L:  <0.8V;  H: >2.4V,输入L:  <1.2V:   H: >2.0V
TTL器件输出低电平要小于0.8V,高电平要大于2.4V,输入,低于1.2V就认为是0,高于2.0就认为是1.于是TTL电平的输入低电平的噪声容限就只有(O.8-0)/2=0.4V,高电平的噪声容限为(5-2.4)/2=1.3V.
RS232标准:
逻辑1的电平为-3~-15V,辑0的电平为+3~+15V,注意电平的定义反相了一次。

   然而TTL电平的串口还可以分为两种UART与USART。我们打开stm32cubeMX看到stm32F103有2个UART3个USART。在日常我们就可以说,它有5个串口,因为USART可以配置成UART

stm32cubeMX软件

stm32cubeMX软件
usart.png
    UART与USART都是单片机上的串口通信,他们之间的区别如下:
首先从名字上看:
UART:universal asynchronous receiver and transmitter通用异步收/发器
USART:universal synchronous asynchronous receiver and transmitter通用同步/异步收/发器
  从名字上可以看出,USART在UART基础上增加了同步功能,即USART是UART的增强型,事实也确实是这样。但是具体增强到了什么地方呢?
  其实当我们使用USART在异步通信的时候,它与UART没有什么区别,但是用在同步通信的时候,区别就很明显了:大家都知道同步通信需要时钟来触发数据传输,也就是说USART相对UART的区别之一就是能提供主动时钟。如STM32的USART可以提供时钟支持ISO7816的智能卡接口。


     在实际的项目中用的最多的还是UART ,配置为:N, 8 ,1.波特率常用的有2400,9600,57600,115200.我们用串口来干什么呢?用过一些模块的工程师会知道,很多模块都是通过串口来控制或者通过串口透传数据的,比如gsm(2g,4g),gps,wifi,蓝牙等等,这些模块都是通过串口来控制。所以作为一个工程师,必须要搞懂串口。
首先我们了解一下我们的工具,大家可以到我的淘宝店里看看:
https://shop296209296.taobao.com/index.htm?spm=a1z10.5-c.w5002-18352947751.2.acd4173daNW4Pn
想要的可以联系我。
下面我们通过Loto虚拟示波器采集不同波特率的TTL的UART 波形:

9600.gif 2400.gif 57600t.gif 115200.gif

对比理论的时序图,我们找找起始位和停止位,这个数据是多少?
串口时序图177.png
有时候我们面试会考一个题目,那就是UART波特率9600的时候,它的一个bit是多长时间,这个怎么算?初学者肯定蒙了,我用串口直接就配置然后发数据就行了,从来没算过,下面我总结一下:

波特率2400:1/2400416.67*10^(-6)s=416.67us
波特率4800:1/4800208.33*10^(-6)s=208.33us
波特率9600:1/9600104.17*10^(-6)s=104.17us
波特率19200:1/1920052.08*10^(-6)s=52.08us
波特率57600:1/5760017.36*10^(-6)s=17.36us
波特率115200:1/1152008.68*10^(-6)s=8.68us

对比我们用Loto虚拟示波器采集的数据看看是不是一致呢?

79~FY%~OK6JIPMKHO$@0YN3.png 1152005.png 2400.png 57600.png

我们算这个数据有什么用呢?是的!没错!就是模拟串口!当单片机串口不够用的时候项目中会用到。接下来我会分析几个论友写的代码,逐步深入理解TTL串口。

下面这个模拟串口的代码:
首先说它的发送吧,发送一个字节,先发送起始位OI_TXD = 0;  然后delay_us(BuadRate_9600);然后依次从低位开始检测Data的每一位,从而拉高拉低OI_TXD,然后延时,移位,重复8次,最后发送停止位发送完一个Data
接收的话:它是stm32开了个定时器4和一个外部中断.外部中断采到下降沿,然后定时器设置为107us中断一次,去采集一个bit,为什么是107us呢?因为此时波特率是9600,一个bit是104.17us,然后可以依次采集每个bit,直到采完一个data。(个人感觉107us不稳定)

复制代码

评分

参与人数 3金币 +80 收起 理由
王海靖 + 10 很给力!
龙之谷 + 20 很给力!
eric2013 + 50 赞一个!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-10-12 09:52:11 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-12 09:54:33 | 显示全部楼层
本帖最后由 ssssssss 于 2018-10-12 10:05 编辑

谢谢硬汉,怎么把图片插入到汉字中间,图片必须放最后吗?有什么方法?
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-12 09:57:41 | 显示全部楼层

怎么把图片插入到汉字中间,图片必须放最后吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-10-12 10:19:26 | 显示全部楼层
QQ截图20181012101905.png
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2018-10-12 16:31:53 | 显示全部楼层
只对楼主的波形软件感兴趣,是不是Qt搞的
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-12 16:45:29 | 显示全部楼层
byccc 发表于 2018-10-12 16:31
只对楼主的波形软件感兴趣,是不是Qt搞的

这个软件是c#搞的
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2018-10-12 17:32:34 | 显示全部楼层
ssssssss 发表于 2018-10-12 16:45
这个软件是c#搞的

非常不错
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-10-13 02:56:17 | 显示全部楼层
软件的确漂亮
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-15 09:52:32 | 显示全部楼层

硬汉哥晚上都不睡觉?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-10-16 01:18:46 | 显示全部楼层
ssssssss 发表于 2018-10-15 09:52
硬汉哥晚上都不睡觉?

睡觉,你又更新了,赞!
回复

使用道具 举报

1

主题

103

回帖

106

积分

初级会员

积分
106
发表于 2018-10-16 16:59:07 | 显示全部楼层
虚拟示波器不错。大家能用不
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-16 17:28:19 | 显示全部楼层
本帖最后由 ssssssss 于 2018-10-19 08:52 编辑
西点钟灵毓秀 发表于 2018-10-16 16:59
虚拟示波器不错。大家能用不

你可以看看
https://item.taobao.com/item.htm ... amp;id=579839697437
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-19 16:24:02 | 显示全部楼层
西点钟灵毓秀 发表于 2018-10-16 16:59
虚拟示波器不错。大家能用不

感觉还好吧?
回复

使用道具 举报

7

主题

70

回帖

91

积分

初级会员

积分
91
发表于 2018-10-19 17:21:08 | 显示全部楼层
关注了  哈哈哈
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-22 09:45:02 | 显示全部楼层

这个是我采集的232电平的串口,大家可以对比一下波形
https://shop296209296.taobao.com/index.htm?spm=a1z10.5-c.w5002-18352947751.2.acd4173daNW4Pn
232.gif
232a5.png
232a7.gif
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-10-22 10:10:56 | 显示全部楼层
#include "sys.h"
#include "delay.h"

/**
*软件串口的实现(IO模拟串口)
* 波特率:9600    1-8-N
* TXD : PC13
* RXD : PB14
* 使用外部中断对RXD的下降沿进行触发,使用定时器4按照9600波特率进行定时数据接收。
* Demo功能: 接收11个数据,然后把接收到的数据发送出去
*/


#define OI_TXD        PCout(13)
#define OI_RXD        PBin(14)

#define BuadRate_9600        100

u8 len = 0;        //接收计数
u8 USART_buf[11];  //接收缓冲区

enum{
        COM_START_BIT,
        COM_D0_BIT,
        COM_D1_BIT,
        COM_D2_BIT,
        COM_D3_BIT,
        COM_D4_BIT,
        COM_D5_BIT,
        COM_D6_BIT,
        COM_D7_BIT,
        COM_STOP_BIT,
};

u8 recvStat = COM_STOP_BIT;
u8 recvData = 0;

void IO_TXD(u8 Data)
{
        u8 i = 0;
        OI_TXD = 0;  
        delay_us(BuadRate_9600);
        for(i = 0; i < 8; i++)
        {
                if(Data&0x01)
                        OI_TXD = 1;  
                else
                        OI_TXD = 0;        
               
                delay_us(BuadRate_9600);
                Data = Data>>1;
        }
        OI_TXD = 1;
        delay_us(BuadRate_9600);
}
       
void USART_Send(u8 *buf, u8 len)
{
        u8 t;
        for(t = 0; t < len; t++)
        {
                IO_TXD(buf[t]);
        }
}
       
void IOConfig(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        EXTI_InitTypeDef EXTI_InitStruct;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);         //使能PB,PC端口时钟
         
         //SoftWare Serial TXD
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;            
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz         
  GPIO_Init(GPIOC, &GPIO_InitStructure);                                         
  GPIO_SetBits(GPIOC,GPIO_Pin_13);                                                
         
         
        //SoftWare Serial RXD
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               
        GPIO_Init(GPIOB, &GPIO_InitStructure);         

        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
        EXTI_InitStruct.EXTI_Line = EXTI_Line14;
        EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断
        EXTI_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStruct);


        NVIC_InitStructure.NVIC_IRQChannel= EXTI15_10_IRQn ;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;  
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  
        NVIC_Init(&NVIC_InitStructure);  
       
}

void TIM4_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
       
        //定时器TIM4初始化
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值       
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
        TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

        //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器                         
}


int main(void)
{               
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
         delay_init();
         IOConfig();
  TIM4_Int_Init(107, 71);         //1M计数频率
         
  while(1)
        {
                if(len > 10)
                {
                        len = 0;
                        USART_Send(USART_buf,11);
                }
        }
}

void EXTI15_10_IRQHandler(void)
{
        if(EXTI_GetFlagStatus(EXTI_Line14) != RESET)
        {
                if(OI_RXD == 0)
                {
                        if(recvStat == COM_STOP_BIT)
                        {
                                recvStat = COM_START_BIT;
                                TIM_Cmd(TIM4, ENABLE);
                        }
                }
                EXTI_ClearITPendingBit(EXTI_Line14);
        }
}

void TIM4_IRQHandler(void)
{  
        if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update) != RESET)
        {
                TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);       
                 recvStat++;
                if(recvStat == COM_STOP_BIT)
                {
                        TIM_Cmd(TIM4, DISABLE);
                        USART_buf[len++] = recvData;       
                        return;
                }
                if(OI_RXD)
                {
                        recvData |= (1 << (recvStat - 1));
                }else{
                        recvData &= ~(1 << (recvStat - 1));
                }       
  }               
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 21:18 , Processed in 0.302735 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表