20120725-51单片机IO口模拟串口通讯3-中断法
来源:互联网 发布:如何删除mac的已购软件 编辑:程序博客网 时间:2024/05/17 22:54
硬件环境:STC89C52
软件环境:IDE Keil uVision V4.10
编译器 C51 V9.0
代码如下:
/**********************************************方法3:中断法硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1波特率:9600描述:所谓中断法是指根据模拟出的波特率,每1位持续的时间的长短是通过定时器计数 溢出产生中断来延时的。测试1:上电发送1个0x03的字符测试2:上电先发送1个0x03的字符,然后等待接收,将收到的字符再发送出去(分别一个一个发送0x01,0x02,0x03,0x04,0x05)测试3:上电等待接收,将收到的字符再发送出去(分别一个一个发送0x01,0x02,0x03,0x04,0x05)结果:测试1:错误!上电发送0x03,接到到0xE0测试1:错误!上电发送0x00,接到到0x80测试1:错误!上电发送0x01,接到到0xC0测试1:错误!上电发送0x02,接到到0x81测试2:错误!上电接收到错误字符0xE0,此后分别接收到0x01,0x02,0x03,0x04,0x05,均正确测试3:错误!接收到第1个字符错误0x82,此后分别接收到0x02,0x03,0x04,0x05,均正确。第1个错误的字符有时会是0x81注意:初始化时,要将定时器T0的溢出标志位清0时间:2012.07.25 于单位**********************************************/#include "reg52.h"#define uchar unsigned charsbit P1_0 = 0x90;sbit P1_1 = 0x91;sbit P1_2 = 0x92;#define RXD P1_0#define TXD P1_1#define WRDYN 44 //写延时#define RDDYN 43 //读延时void Delay2cp(unsigned char i);void WaitTF0( void );#define TM0_FLAG P1_2 //设传输标志位//计数器及中断初始化void S2INI(void){TMOD |=0x02;//计数器0,方式2TH0=0xA0; //预值为256-96=140,十六进制A0TL0=TH0; TR0=0; //在发送或接收才开始使用TF0=0; ET0=1; //允许定时器0中断EA=1; //中断允许总开关}//发送一个字符void WByte(uchar input){ //发送启始位 uchar i=8; TR0=1; TXD=(bit)0; WaitTF0(); //发送8位数据位 while(i--) { TXD=(bit)(input&0x01); //先传低位 WaitTF0(); input=input>>1; } //发送校验位(无) //发送结束位 TXD=(bit)1; WaitTF0(); TR0=0;}//接收一个字符uchar RByte(){uchar Output=0;uchar i=8;TR0=1; //启动Timer0TL0=TH0;WaitTF0(); //等过起始位//发送8位数据位while(i--){Output >>=1;if(RXD)Output |=0x80; //先收低位WaitTF0(); //位间延时}while(!TM0_FLAG) if(RXD) break;TR0=0; //停止Timer0return Output;}//中断1处理程序void IntTimer0() interrupt 1{ TM0_FLAG=1; //设置标志位。}//查询传输标志位void WaitTF0( void ){while(!TM0_FLAG); TM0_FLAG=0; //清标志}//检查是不是有起始位bit StartBitOn(){return (RXD==0); }void main(){uchar ccc;S2INI();//2012.07. 25 李响添加//计时器T0启用之前要把溢出标志清0,计时满TF0=1//缺少如下的语句,将发生描述中的错误TM0_FLAG=0;//测试1/*WByte(0x03);WByte(0x01);WByte(0x02);WByte(0x03);WByte(0x04);WByte(0x05);while(1){;}*///测试2WByte(0x03);while(1){if(StartBitOn()){ccc=RByte();WByte(ccc);}}//测试3/*while(1){if(StartBitOn()){ccc=RByte();WByte(ccc);}}*/}
附解决问题过程中所抓的波形:
测试1:错误!上电发送0x00时的波形。
测试1:错误!上电发送0x00时接收到的数据。
分析:上电发送0x00,理应也收到数据0x00,波形的形状也应该如上图所示,但接收到的数据为0x80则显示这波形是错误的。且往下看。
----------------------------------------------------------------------------------------------------------------------------------------
测试1:错误!上电发送0x01时的波形。
测试1:错误!上电发送0x01时接收到的数据。
分析:波形错误,接收到的数据也错误。起始位为低电平,理应持续1位的时间,但可以看出,起始位保持很短的时间就跳为高电平了。说明起始位到来以后,相应的延时时间那里出了问题。
正确的0x01的波形如下图所示:
----------------------------------------------------------------------------------------------------------------------------------------
测试1:错误!上电发送0x02时的波形。
测试1:错误!上电发送0x02时接收到的数据。
正确的0x02的波形如下图所示:
----------------------------------------------------------------------------------------------------------------------------------------
测试1:错误!上电发送0x03时的TXD的波形。
上电发送0x03时接收到的数据。
正确的0x03的波形如下:
----------------------------------------------------------------------------------------------------------------------------------------
测试2:错误!上电本应先接到一个0x03的字符,但实际接收到的为0xE0,此后收发均正确。
测试2:错误!上电本应先接到一个0x03的字符,但实际接收到的为0xE0,此后收发均正确。
此图仅用于证明除第一个字符错误外,此后其它接收到的字符均正确。
----------------------------------------------------------------------------------------------------------------------------------------
测试3:错误!先手动发送第1个字符0x01,此时接收到的错误数据81,此时的波形
接收到的错误数据0x81
上电后,依次发送0x01,0x02,0x03,0x04,0x05,接收到第1个字符0x81错误,后4个字符正确
上边的那个实验,有的时候偶尔会出现第1个字符是0x82的错误数据。
----------------------------------------------------------------------------------------------------------------------------------------
以下两图为0x04和0x05的正确的波形
0x04时的波形
0x05时的波形
----------------------------------------------------------------------------------------------------------------------------------------
分析:可以看出,起始位持续的时间不正确。
原因为:中断标志位上电后默认为1,高电平,需要手动将其清0。本程序利用了P1^2做为中断标志位,P1^2上电后为高电平。在程序中,S2INI();之后,添加TM0_FLAG=0;解决此问题。
- 51单片机IO口模拟串口通讯3-中断法
- 20120725-51单片机IO口模拟串口通讯3-中断法
- 20120725-51单片机IO口模拟串口通讯4
- 20120725-51单片机IO口模拟串口通讯5
- 20120725-51单片机IO口模拟串口通讯6
- 51单片机IO口模拟串口通讯2-计数法
- 51单片机IO口模拟串口通讯1-延时法
- 20120725-51单片机IO口模拟串口通讯1-延时法
- 20120725-51单片机IO口模拟串口通讯2-计数法
- 51单片机IO口模拟串口通讯C源程
- 51单片机IO口模拟串口通讯C源程序
- 51单片机IO口模拟串口通讯4
- 51单片机IO口模拟串口通讯5
- 51单片机IO口模拟串口通讯C源程(详细分析)
- 20120726-分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”
- 模拟串口的实现--单片机IO口
- STM32 IO口模拟串口通讯
- 51单片机串口通讯
- java oracle 存储过程(有返回值)返回列表--》学习二(转载+修改)
- 关于Android短信拦截(三)
- 关于socket长连接的心跳包
- 解压cpio.gz文件
- 关于Tslib编译可能遇到的问题总结
- 20120725-51单片机IO口模拟串口通讯3-中断法
- 坦白错误
- SliverLight程序发布注意事项
- 昵称
- Zend studio中开发常用快捷键,字符,模板设置
- GridView中DateTime格式问题(十一)
- Eclipse 插件安装的四种方法
- .NET程序安装包制作(WinForm)
- 线段树:敌兵布阵