请选择 进入手机版 | 继续访问电脑版

智凡单片机论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 738|回复: 0

串口通信

[复制链接]

80

主题

80

帖子

288

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
288
发表于 2018-12-19 21:23:27 | 显示全部楼层 |阅读模式
串口通信有什么用,简单说可以将温度、数字信号通过单片机送回给电脑数据库,那你可以通过网页、手机等做监测。下面讲解下最简单的串口通信协议:
         通信协议又分为硬件层协议和软件层协议。硬件层协议主要规范了物理上的连线,传输电平信号及传输的秩序等硬件性质的内容。常用的硬件协议有串口,IIC, SPI, RS485, CAN和 USB。软件层协议则更侧重上层应用的规范,比如modbus协议。串口的6个特征如下。
(1)、物理上的连线至少3根,分别是Tx数据发送线,Rx数据接收线,GND共用地线。
(2)、0与1的约定。RS232电平,约定﹣5V至﹣25V之间的电压信号为1,﹢5V至﹢25V之间的电压信号为0 。TTL电平,约定5V的电压信号为1,0V电压信号为0 。CMOS电平,约定3.3V的电压信号为1,0V电压信号为0 。其中,CMOS电平一般用于ARM芯片中。
(3)、发送秩序。低位先发。
(4)、波特率。收发双方共同约定的一个数据位(0或1)在数据传输线上维持的时间。也可理解为每秒可以传输的位数。常用的波特率有300bit/s, 600bit/s, 2400bit/s, 4800bit/s, 9600bit/s。
(5)、通信的起始信号。发送方在没有发送数据时,应该将Tx置1 。 当需发送时,先将Tx置0,并且保持1位的时间。接受方不断地侦测Rx,如果发现Rx常时间变高后,突然被拉低(置为0),则视为发送方将要发送数据,迅速启动自己的定时器,从而保证了收发双方定时器同步定时。
(6)、停止信号。发送方发送完最后一个有效位时,必须再将Tx保持1位的时间,即为停止位。

协议很简单的,所以实现起来也相对简单,但要注意时序,下面在程序中有说明:

*本身有条usb转ttl线(用来刷程序),就利用它来测试,把p1.0口和p3.1(txd)口连起来就可以,然后用stc-isp的串口助手就可以观察到p1.0口的数据输出,当然p1.0的数据输出要符合串口协议规范。

#include "reg52.h"
sbit TX=P1^0; //P1^0 output TTL signal, need to transferred to rs232 signal, can be connected to P3^1
#define u16 unsigned int //宏定义
#define u8 unsigned char
u8 sbuf;
bit ti=0;

void delay(u16 x)
{
while(x--);
}
void Timer0_Init()
{
TMOD = 0x01;
//TH0=65435/256;   //可以不要,后面有,只要设好tmod,tr0就好
//TL0=65435%6;
TR0=0;
}

void Isr_Init()
{
EA=1;     
ET0=1;
}

void Send_Byte(u8 dat)
{
sbuf=dat;//通过引入全局变量sbuf,可以保存形参dat
TH0=65432/256;    //这个值刚好是104us 中断,
TL0=65432%6;
TX=0; //A 起始位,注意,当把p1.0拉低时,对方就开始判断是否够一个位时长(104us)
TR0=1;     //激活时间器0中断,1号中断
while(ti==0); //等待发送完成
ti=0; //清除发送完成标志
}

void TF0_isr() interrupt 1   //理论上是每104us进入一次中断,但要考虑中断程序本身也有时延,可对方不                                                      会等你,所以要在程序中调整计时值
{
static u8 i; //记录进入中断的次数
                    //注意,因为第一次中断时是104us,为了及时反映数据变化,要马上对p1.0口输出,以免延时                              导致丢失
if(i<8)    //由低位第0位开始到第7位,发送8次
{
TX=sbuf&(1<<(i));   //下面那段就是原作者写的,但是实际行不通,因为太耗时了时延过长
                 //****if((sbuf&(1<<(i-1)))==0)  // (sbuf&(1<<(i-1)))表示取出i-1位
//{
//TX=0;
//}
//else
//{
// TX=1;
//}*****

   TH0=0xFF;  //上面提到,因为中断处理本身延时,所以计时值必须相应减少,减多少?我靠测试来不断                                   修正,例如可以用0x0F来测试,开始是7F,后来变3F,  ...1F ..... 最后用这个值才最终得到0F
   TL0=0xE8;
i++;         
}
else
{
TX=1;    //发送完8个数据位后,把p1.0拉高表示结束
TR0=0;    //关中断
i=0;
ti=1; //发送完成
}  
}

void main()
{
TX=1; //使TX处于空闲状态
Timer0_Init();
Isr_Init();
while(1)
{
Send_Byte(0x41); //0x41
delay(60000);
}
}

回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|智凡单片机论坛

GMT+8, 2019-8-25 15:13 , Processed in 0.058154 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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