5923|6

90

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

模拟接收串口(P3.2),收到数据转发给真实串口,为什么数据会变成原来的2倍! [复制链接]

/***************************************************************
* 模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口
* 在单片机上模拟了一个串口,使用P3.2作为发送和接收端
* 以P3.2模拟串口接收端,从模拟串口接收数据发至串口
***************************************************************/
#include
#include
#include
typedef unsigned char uchar ;
uchar tmpbuf2[64]={0};
//用来作为模拟串口接收数据的缓存
struct
{   
  uchar recv :6;//tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中   
  uchar send :6 ;//tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口
  }
  tmpbuf2_point={0,0};
  sbit newRXD=P3^2 ;//模拟串口的接收端设为P3.2
  void UartInit()
  {
   SCON=0x50 ;// SCON: serail mode 1, 8-bit UART   
   TMOD|=0x21 ;// TMOD: timer 1, mode 2, 8-bit reload,自动装载预置数(自动将TH1送到TL1);T0工作在方式1,十六位定时
   PCON|=0x00 ;// SMOD=0   
   TH1=0xFD ;// Baud:9600  fosc=11.0592MHz 9600bps为从串口接收数据的速率  
   TL1=0xFD ;// 计数器初始值,fosc=11.0592MHz 因为TH1一直往TL1送,所以这个初值的意义不大
   TH0=0xFF ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz  
   TL0=0xA0 ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz
   IE|=0x81 ;// 中断允许总控制位EA=1;使能外部中断0   
   TF0=0 ;   
   IT0=1 ;// 设置外部中断0为边沿触发方式   
   TR1=1 ;// 启动TIMER1,用于产生波特率
                 }
                 void WaitTF0(void)
                 {   
                  while(!TF0);  
                   TF0=0 ;  
                          
                          TH0=0xFF ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz   
                          TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz  
                       
                                }
                                //接收一个字符
                                uchar RByte()
                                {   
                                 uchar Output=0 ;
                                 uchar i=8 ;  
                                 TR0=1 ;    //启动Timer0     
                       
                                TH0=0xFF ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
                            TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz   
                       
                                TF0=0 ;
                                WaitTF0();//等过起始位
                            //接收8位数据位
                while(i--)   
                 {      
                  Output>>=1 ;   
          if(newRXD)Output|=0x80 ;//先收低位   
                  WaitTF0();//位间延时   
                     }
                  TR0=0 ;//停止Timer0
                  return Output ;
                  }
                  //向COM1发送一个字符
                  void SendChar(uchar byteToSend)
                  {   
                   SBUF=byteToSend ;   
                   while(!TI);   
                   TI=0 ;
                   }
                   void main()
                   {   
                    UartInit();
                        while(1)
                    {
                        if(tmpbuf2_point.recv!=tmpbuf2_point.send)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口)
                                {
                                         SendChar(tmpbuf2[tmpbuf2_point.send++]);   
                                             }
                                                     }
                                                            }
                //外部中断0,说明模拟串口的起始位到来了
                void Simulated_Serial_Start()interrupt 0
                 {   
                  EX0=0 ;    //屏蔽外部中断0   
                  tmpbuf2[tmpbuf2_point.recv++]=RByte();    //从模拟串口读取数据,存放到tmpbuf2数组中  
                  IE0=0 ;    //防止外部中断响应2次,防止外部中断函数执行2次   
                  EX0=1 ;    //打开外部中断0
                  }

用以上的程序模拟P3.2作为接收串口,用两个开发板,一个用来发数据,一个用来接收(用模拟的3.2口),接收的这个和电脑相连,数据可以显示,但都是发送数据的2倍,,大家看看哪里程序出问题了?
此帖出自51单片机论坛

最新回复

举个简答的例子,比方说你发送0x01,二进制为00000001,最低位为1,从最低位开始读取,这一位对应到程序里就是newRXD = 1,然后Output|=0x80(10000000),然后进行下一次循环;之后的newRXD都为0,循环一次Output往右移一位,依次为01000000 00100000 00010000 ......直到最后00000001 WaitTF0();//等过起始位 这个起始位是什么?真要有这个位的话,那1位起始位加8位数据位一共要读取9位,那这个程序最简单的改法就是让i的初始值等于9了吧?试试看对不对吧? [ 本帖最后由 SuperStar515 于 2011-8-12 01:22 编辑 ]  详情 回复 发表于 2011-8-12 01:20
点赞 关注
个人签名路漫漫,修远,求索
 

回复
举报

90

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
各路大侠帮忙分析一下啊。。。

[ 本帖最后由 skyflysgs 于 2011-8-11 19:24 编辑 ]
此帖出自51单片机论坛
 
个人签名路漫漫,修远,求索
 
 

回复

90

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
帖子沉了
此帖出自51单片机论坛
 
个人签名路漫漫,修远,求索
 
 

回复

449

帖子

0

TA的资源

五彩晶圆(高级)

4
 
成2倍关系应该是移位部分的问题

//接收8位数据位
while(i--)
{
Output>>=1 ;
if(newRXD)Output|=0x80 ;//先收低位
WaitTF0();//位间延时
}

这里应该先收低位再移位(Output>>=1 ; )吧?
此帖出自51单片机论坛
 
个人签名世界是个圈,人生也是个圈。
 
 

回复

90

帖子

0

TA的资源

一粒金砂(高级)

5
 

回复 4楼 SuperStar515 的帖子

刚试了,结果还是一样,第一次output=0,移位不变,应该没影响吧,还有,我看不懂
if(newRXD)Output|=0x80 ;//先收低位
这是什么意思》?如果newrxd=1,Output|=0x80 ....怎么就先接低位了呢?这是网上找了个程序改的,这一句看不懂啊!
此帖出自51单片机论坛
 
个人签名路漫漫,修远,求索
 
 

回复

449

帖子

0

TA的资源

五彩晶圆(高级)

6
 

举个简答的例子,比方说你发送0x01,二进制为00000001,最低位为1,从最低位开始读取,这一位对应到程序里就是newRXD = 1,然后Output|=0x80(10000000),然后进行下一次循环;之后的newRXD都为0,循环一次Output往右移一位,依次为01000000 00100000 00010000 ......直到最后00000001

WaitTF0();//等过起始位

这个起始位是什么?真要有这个位的话,那1位起始位加8位数据位一共要读取9位,那这个程序最简单的改法就是让i的初始值等于9了吧?试试看对不对吧?

[ 本帖最后由 SuperStar515 于 2011-8-12 01:22 编辑 ]
此帖出自51单片机论坛
 
个人签名世界是个圈,人生也是个圈。
 
 

回复

90

帖子

0

TA的资源

一粒金砂(高级)

7
 

回复 6楼 SuperStar515 的帖子

是不是这样,原来i=8的时候,原来的起始位0就放在接收的最低位上了,而最高位丢失,相当于原来的数据左移了一位,所以会出现接收到的是原来的两倍,现在把i改成9,相当于output再右移一位,将最低位的(原来的起始位)0右移掉,最高位不会丢失,所以i=9是对的。。。
试了一下,果然对了,,,谢谢你
此帖出自51单片机论坛
 
个人签名路漫漫,修远,求索
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表