微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 普通IO口模拟串口异步通信如何区分起始起始位和数据位呢?

普通IO口模拟串口异步通信如何区分起始起始位和数据位呢?

时间:10-02 整理:3721RD 点击:
如题所述  照着51串口的异步时序写的串口通讯  可问题是2个单片机用普通IO口通信时  如果发送信息的主机先开始工作而从机后开始工作的话   从机就有可能将数据帧中的数据位当成起始位 这样接收就陷入混乱了啊  有什么最简单的方法解决这个问题呢

这感觉就是 相当于数据在发送中出现错的情况。  让从机在收到数据后与判断一下,如果数据错误就反馈给主机,让主机停止发送数据,再从新开始发送行不?

《从入门到精通STC8051单片机核心技术》辅助参考视频地址:
http://pan.baidu.com/share/home? ... are#category/type=0

例4.6        任意IO口模拟串口,22.1184MHz内部R/C时钟,波特率9600bps。
#include "STC15W4K.H"            // 包含 "STC15W4K.H"寄存器定义头文件  
#define RECEIVE_MAX_BYTES  1     // 最大接收字节数
unsigned char RecvBuf[16];       // 接收数据缓冲区
unsigned char RecvCount=0;       // 接收数据计数器
sbit T_TXD=P3^2;                 // 发送数据的引脚       
sbit R_RXD=P3^3;                 // 接收数据的引脚
bit RXD_OK;                                 // 数据接收完成标志,1(接收正确),0(接收错误)
//******************************************/
void delay104uS()
{    // 由第一章介绍的软件计算得出
}
void delay52uS()                    // 起始位结束后52uS采样数据
{// 由第一章介绍的软件计算得出
}
void SendByte(unsigned char Dat)
{
        unsigned char i=8;            // 发送8 位数据
        T_TXD=0;                            // 发送起始位
        delay104uS();       
        while(i--)
        {
                if(Dat&1) T_TXD=1;
                else T_TXD=0;
                delay104uS();
                Dat>>=1;
        }
        T_TXD=1;                            // 发送停止位
        delay104uS();                    // 延时       
}
unsigned char RecvByte()
{
        unsigned char i;       
        unsigned char Dat=0;                // 接收到的数据
        RXD_OK=0;                                        // 字节数据接收正常标志,0——错误,1——正常
        delay52uS();                              // 数据位中心位置读数据       
        if(R_RXD==0)                        // 确认起始位正常
        {         
                delay104uS();                        // 起始位宽度                
                for(i=0;i<8;i++)
                {
                        if(R_RXD) Dat|=(1<<i);
                        delay104uS();
                }        
                if(R_RXD==1)                    // 确认停止位正常
                {
                        RXD_OK=1;
                }
        }  
        return Dat;
}
// 功能:串口打印字符串
//*****************************************/
void PrintfStr(char * pstr)
{
        while(*pstr)   
        {
                SendByte(*pstr++);
        }
}
// 功能:函数主体
//******************************************/
void main(void)
{  
        unsigned char i;        
        PrintfStr("模拟串口:STC15\r\n");
        while(1)                          
        {
                if(R_RXD==0)        // 死循环不断检测R_RXD是否有起始位出现
                {
                        RecvBuf[RecvCount]=RecvByte();
                        if (RXD_OK==1)                                                // 一个字节接收正常
                        {  
                                RecvCount++;
                                if(RecvCount>=RECEIVE_MAX_BYTES)
                                {
                                        RecvCount=0;
                                        for(i=0;i<RECEIVE_MAX_BYTES;i++)
                                        {
                                                SendByte(RecvBuf+1);           // 接收到得数据+1后发回
                                        }
                                }
                        }               
                }
        }
}
实验结果:使用STC_ISP软件自带的串口助手,设置波特率9600,N,8,1格式,文本模式显示,然后给单片机上电,可看到串口助手显示“模拟串口:STC15”,修改串口助手为HEX模式显示,发送一个数据,则单片机加1后发回到串口助手。计算机串口助手发给单片机0x55(01010101)时单片机接收端P3.3引脚波形如图4-5所示,注意是低位在前,高位在后,单片机发给计算机串口助手0x55(01010101)时单片机发送端P3.2波形如图4-6所示,同样是低位在前,高位在后。

                     图4-5  计算机串口助手发送到单片机接收端的波形

                        图4-6  单片机发给计算机串口助手时单片机发送端波形
现在对以上程序作必要说明,以上实验结果使用的是STC高速单片机,若使用传统单片机(如AT89C51)有可能出现收发数据不正确的现象,原因就在于104uS与55uS的延时程序,或许很多人会疑惑,按道理来说,使用104uS与55uS的延时是没有错的,但是在SendByte和RecvByte的函数当中,执行每一行代码都要消耗一定的时间,这就延长了实际的时间,导致收发数据出现问题,但使用STC高速单片机,由于指令执行速度非常快(比AT89C51快12倍),对波特率几乎没影响,并且实际波特率允许有3%的误差,从图4-6与图4-7可以看出波特率已经非常准确,不需再作调整,对其它低速单片机,我们必须通过逻辑分析仪实际测试发送数据的每一位的时间并不断调整延时函数时间(通常可先发一个字节如:0x55=01010101进行观察),使其达到最佳值,因此延时程序延时时间值不能够按照常规来计算得到,实际值一般会比计算值偏小一点。为了提高接收信号时的抗干扰能力,程序中做了一些额外处理,为了更好的理解程序或用于没有明显干扰的场合,可参见例4.7,程序更加直观,更容易理解。
更多内容看电子文档。

《从入门到精通STC8051单片机核心技术》内容真实,言语简洁,以当今流行的STC15系列单片机为主线进行讲解,并介绍了很多具有重要实用价值的实例,学会后即可用于产品开发,目前教材正在排版印刷过程中,这里提供与教材配套的辅助参考视频,需要电子版的,可参考论坛中的《STC51单片机入门(C语言》。
QQ群:324284310,QQ:347305156    验证:STC单片机、STM32等,不能为空。教材目录:

第1章  单片机高效入门

  1.1  单片机简介

1.1.1  认识单片机

1.1.2  单片机的用途

1.1.3  学习的典型芯片与C语言介绍

1.1.4  本书配套实验板及相关学习工具介绍

1.2  点亮1个发光二极管   

  1.2.1  单片机型号命名规则

  1.2.2  单片机引脚功能说明   

1.2.3  制作一个最简单的单片机实验电路

1.2.4  使用Keil uVsion3环境编写最简单的程序

1.2.5  ISP下载程序到单片机(将电脑上的目标代码“灌入”单片机中运行)

1.2.6  程序解释

1.3  Keil 仿真  

1.3.1  软件仿真(标准8051方式仿真,不能仿真单片机新增功能)

1.3.2  硬件仿真(利用STC专用仿真芯片仿真,可仿真所有功能)

1.4  经典流水灯实例

1.5  单片机C语言延时程序详解

  1.5.1 学会使用计算软件

  1.5.2 计算软件内部运算过程详解

  1.5.3 利用库函数实现短暂精确延时

1.5.4 使用定时器/计数器实现精确延时

1.6  main()、void main()和int main()的区别

1.7  printf 格式化输出函数

第2章  单片机开发必须掌握的C语言基础

2.1  简单数据类型与运算符

2.1.1  原码、反码、补码、BCD码、格雷码

    2.1.2  常量      

    2.1.3  变量的数据类型(bit、char、int、long、float)

2.1.4  变量存储空间(code、data 、bdata 、idata、xdata)

2.1.5  变量存储类型(auto、static、extern)

2.1.6  变量作用域

2.1.7  运算符   

2.1.8  运算符的优先级与结合性

2.2  C51构造数据类型

2.2.1  数组:将相同类型数据组合在一起就构成数组(如数码管显示缓冲区)

2.2.2  结构体:将不同类型数据组合在一起就构成结构体(如年月日2014-12-31)

2.2.3  共用体:不同变量占用相同内存地址就是共用体

2.2.4  指针:用于直接读取或修改内存值

2.2.5  #define与typedef的差别

2.3  流程与控制

  2.3.1  分支结构

  2.3.2  循环结构

  2.3.3  跳转结构

2.4   函数

    2.4.1  函数定义

2.4.2  调用格式

2.4.3  传值调用与传地址调用2种方式对比

2.4.4  数组作为函数参数

2.4.5  使用指针变量作函数形式参数

2.4.6  使用结构体变量指针作为函数参数

2.4.7  函数作用域

2.4.8  库函数

2.5   模块化编程

    2.5.1  头文件的编写

    2.5.2  条件编译

2.5.3  多文件程序(模块化编程)

第3章  定时器/计数器、中断系统     

3.1 定时器/计数器

3.1.1 单片机定时器/计数器工作原理概述

3.1.2 定时器/计数器的相关寄存器   

3.1.3 定时器/计数器的工作方式     

3.1.4 初值计算

3.1.5 编程举例

3.2 可编程时钟输出

3.3 中断系统

3.3.1 中断系统结构图

3.3.2 操作电路图中的开关(相关寄存器介绍)

3.3.3 编写中断函数

3.3.4 中断程序举例

3.3.5 外中断代码调试(按键的防抖技术)

第4章  串口通信

4.1  最基本的串口通信

4.1.1  串口数据发送格式

4.1.2  串口相关寄存器

4.1.3  波特率计算步骤详解

4.1.4  单片机与计算机通信的简单例子

4.2  彻底理解串口通信协议            

4.3  串口隔离电路

4.4  计算机扩展串口(USB 转串口芯片CH340G)

4.5  RS485串行通信

4.6  SSI通信

4.6.1  SSI数据通信格式

4.6.2  SSI硬件电路

4.6.3  SSI软件实现

4.7 数据通信中的错误校验

4.7.1 校验和(CheckSum)与重要的串口通信实例  

4.7.2 CRC校验(全称:循环冗余码校验)        

4.8  单片机串口向计算机串口发送2进制、16进制、数值与字符串              

第5章  SPI通信

5.1  SPI总线数据传输格式       

5.1.1  接口定义

5.1.2  传输格式

5.2  SPI接口相关寄存器

5.2.1  SPI相关的特殊功能寄存器  

5.2.2  SPI接口引脚切换

5.3  SPI接口运用举例

第6章  I2C通信

6.1  I2C总线数据传输格式  

6.1.1  各个位的传输要求   

  6.1.2  多字节传输格式     

6.2  程序模块功能测试      

6.2.1  硬件仿真观察24C02读写结果(R/C时钟:22.1184MHz)

  6.2.2  硬件仿真观察24C32/64读写结果(R/C时钟:22.1184MHz)

6.3  24C02运用实例(断电瞬间存储整数或浮点数)         

第7章  单片机内部比较器与DataFlash存储器  

7.1  STC15W系列单片机内部比较器

7.1.1  比较器结构图

7.1.2  寄存器说明

7.1.3  电路讲解与程序实例

7.2  DataFlash存储器      

  7.2.1  DataFlash操作有关的寄存器介绍

7.2.2  DataFlash操作实例(断电瞬间存储数据)

第8章  可编程计数阵列CCP/PCA/PWM模块(可用作DAC)

8.1  PCA模块总体结构图

8.2  PCA模块的特殊功能寄存器

8.3  PCA模块的工作模式与应用举例

第9章  模数转换器ADC

9.1  模数转换器ADC主要技术指标

9.2  使用单片机内部的10位ADC转换器

9.2.1、ADC相关的特殊功能寄存器

9.2.2、实例代码

9.3  12位ADC转换芯片MCP3202-B

9.4  16位ADC转换芯片ADS1110A0

9.5  18位ADC转换芯片MCP3421A0T-E/CH

第10章  数模转换器DAC

10.1  TLC5615数模转换电路与基本测试程序

10.2  TLC5615产生锯齿波、正弦波、三角波

10.3  TLC5615的高级运用(播放歌曲)

第11章  单片机实用小知识

11.1  复位

11.1.1  外部RST引脚复位

11.1.2  软件复位

11.1.3  内部低压检测复位

11.1.4  看门狗定时器复位

11.2  单片机的低功耗设计

11.2.1  相关寄存器说明

11.2.2  应用举例

11.3  单片机扩展32K外部数据存储器62256

11.3.1  电路讲解

11.3.2  软件测试实例

第12章  常用单片机接口程序  

12.1  数码管静态显示

12.2  数码管动态显示

12.3  独立键盘

12.4  矩阵键盘

第13章  1602液晶

13.1 1602液晶外形与电路图

13.2 1602液晶运用举例

13.3 1602液晶显示汉字与特殊符号

第14章  精密电压表\电流表\通用显示器\计数器制作

14.1  功能说明与电路原理分析

14.2  程序实例

14.2.1  通用显示器功能检测程序(外部程序)

14.2.2  计数器功能检测程序(外部程序)

14.2.3  模块程序

第15章  步进电机测试

15.1  步进电机特点

15.2  步进电机的3种励磁方式

15.3  步进电机驱动电路

15.4  步进电机驱动实例

15.5  步进电机专用驱动器介绍

第16章  频率检测

16.1  频率检测的用途与频率定义

16.2  频率检测实例

第17章  DS1302时钟芯片

17.1  DS1302的SPI数据通信格式

17.2  程序实例

第18章  红外通信   

18.1  红外通信电路与基本原理

18.2  红外接收软件实例

第19章  单总线DS18B20 通信(长距离无线通信)

19.1  DS18B20运用基础

     19.1.1  单只DS18B20的温度检测电路

     19.1.2  DS18B20的通信时序

     19.1.3  DS18B20内部功能部件ROM、RAM、E2RAM、指令集

   19.1.4  读取温度步骤

19.2  单只DS18B20的温度检测实例

19.3  多只DS18B20的温度检测

     19.3.1  读取传感器代码实例

19.3.2  读取传感器温度实例

第20章  SD卡与znFAT文件系统

20.1  认识SD卡与SD卡驱动程序

20.1.1  认识SD卡

20.1.2  电路讲解

20.1.3  通信时序与完整驱动程序说明

20.2  znFAT文件系统

20.2.1  znFAT的移植方法

20.2.2  znFAT移植实例

第21章  MP3播放器实验(znFAT文件系统运用实例  

21.1  MP3介绍与电路讲解

21.2  正弦测试

21.3  通过SD卡播放MP3文件

第22章  数字存储示波器技巧与逻辑分析仪的操作

22.1  测量直流电源开关机瞬间输出毛剌浪涌

22.2  测量稍纵即逝的红外发射信号

22.3  精确测量直流电源纹波

22.4  示波器带宽选用依据

22.5  逻辑分析仪快速入门

附录1   ASCII码表

参   考   文   献

大哥贴这么多也没回答我的问题

我没有设奇偶校验,就起始位0+八位数据+结束位1,模拟串口通讯会不会把数据里面的0当成起始位,那么数据就错了。

火钳刘明!

只需要在每次发送是都先发两个包头:比如0X11和0XEE,然后判断接收到的是不是这两个,是的话,才开始认为接受证券,开始发争产大哥数据。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top