搜索
bottom↓
回复: 9

模拟串口

[复制链接]

出0入4汤圆

发表于 2014-4-19 14:47:36 | 显示全部楼层 |阅读模式
我的模拟串口是使用定时器,发以一个字节接收正确,连续发四个字节,第一个回复字节对,其它三个都是错误的,程序如下,请大家帮看看是什么原因

#include <stc90C5xad.h>                                         //使用8052内核单片机

  unsigned char i=0,j;


sbit TX_IO=P2^6;                                           //模拟串口发送IO
sbit RX_IO=P2^7;                                           //模拟串口接收IO         
bit sending,receing,received;                               //发送中,接收中,接收完毕标志
unsigned char rece_bit_count;                               //接收位计数变量
unsigned char rece_pls_count;                               //接收脉冲计数变量
unsigned char send_bit_count;                               //发送位计数变量
unsigned char send_pls_count;                               //发送脉冲计数变量
unsigned char receing_data;                                 //正在接收着的临时数据
unsigned char byte_need_to_send;                            //要发送出去的字节
unsigned char byte_received;                                //已收到的字节
unsigned char  ad[4];   
void send_byte(unsigned char byte_will_send)                //发送一个字节
{                                                          //函数开始
   byte_need_to_send=byte_will_send;                           //传递要发送的数据
   send_pls_count=3;                                          //采样倍率3
   send_bit_count=8;                                          //8位数据一位停止
   TX_IO=0;                                                   //发送起始位
   sending=1;                                                 //置标志位,中断程序开始发送该字节
   while(sending);                                             //等待数据发送完成
}                                                          //函数结束
     
void timer0(void) interrupt 1                               //中断服务程序
{  
TH0=0xFE;//(65536-(11059200/600/3/12))/256;                         //重载值=65536- (定时器脉冲频率÷波特率÷3)
TL0=0x00;//(65536-(11059200/600/3/12))%256;                         //溢出率=定时器脉冲频率÷ (65536-重载值)                                                        //函数开始
   if(receing)                                                //接收中?
     {                                                        //接收中开始
       if(--rece_pls_count==0)                                  //三次脉冲计数够了吗?
         {                                                     //接收一位二进制位开始
           rece_pls_count=3;                                      //脉冲计数辅助变量复位
           if(rece_bit_count)                                     //是在接收数据位还是停止位
             {                                                   //接收数据位开始
               receing_data=receing_data>>1;                       //向右移一位,准备拼入一位二进制数据
               if(RX_IO==1){receing_data=receing_data|0x80;}//如果收到的是二进制位"1",则拼入最高位中
               rece_bit_count=rece_bit_count-1;                    //已接收一位,接收位计数变量计数
             }                                                   //接收数据位结束
           else                                                   //如果已经收完8位数据
             {                                                   //就开始接收停止位
               receing=0;                                          //本字节已接收完毕
              if(RX_IO==1)                                        //停止位是"1"吗
               {                                                 //是“1”
//                 ad[i++]=receing_data;                       //将数据输出
//                                 if(i>3)
//                                 {
//                                 i=0;
                 received=1;                                       //摇旗示意数据正确接收完毕
                                 //}
               }                                                 //数据输出处理完毕
             }                                                   //停止位处理完毕
        }                                                     //接收一位二进制位结束
     }                                                        //接收中处理结束
     else                                                       //还没收到停止位,不是正在接收状态
      {                                                        //等待接收开始
         if(RX_IO==0)                                           //是一个起始位到来吗
          {                                                     //是.......
            receing=1;                                             //开始接收
            rece_pls_count=3;                                      //置接收起始位脉冲数
            rece_bit_count=8;                                      //置接收二进制位数
          }                                                     //起始位处理完毕
      }                                                        //等待接收完毕
        //----------------------------------------------------------------------------------------
     if(sending)                                                //是正在发送状态吗
      {                                                        //是……
         if(--send_pls_count==0)                                  //脉冲计数够了吗
         {                                                     //够了……
           send_pls_count=3;                                      //脉冲计数复位
           if(send_bit_count)                                     //是在发送数据还是要发送停止位
            {                                                   //发送数据开始
               TX_IO=byte_need_to_send&0x01;                       //从最低位开始发送数据
               byte_need_to_send=byte_need_to_send>>1;             //移动数据准备下一次发送
               send_bit_count=send_bit_count-1;                    //已经发送了一位二进制数要记下来
             }                                                   //发送数据结束
            else                                                   //数据已经发送完成
             {                                                   //发送停止位开始
               TX_IO=1;                                            //发送停止位
               sending=0;                                           //放下旗帜表示数据已经发送完成
             }                                                    //停止位发送完成
          }                                                      //一位二进制位处理完成
       }                                                         //发送状态处理完成
}                                                           //中断函数结束
void main(void)                                             //主程序
{                                                          //开始
        TMOD=0x01;                     //16位自动重载模式,当TR0=0时向TH0,TL0写入数据将同时写入重载寄存器
        TH0=0xFE;//(65536-(11059200/600/3/12))/256;                         //重载值=65536- (定时器脉冲频率÷波特率÷3)
        TL0=0x00;//(65536-(11059200/600/3/12))%256;                         //溢出率=定时器脉冲频率÷ (65536-重载值)
        TR0=1;                                                      //启动定时器,模拟串口开始工作
        EA=1;                                                       //打开总中断
        ET0=1;                                                      //打开定时器0中断
        PX0=1;                                                      //优先保证定时器0中断,确保模拟串口的可靠性
        while(1)                                                    //主循环
          {                                                         //主循环体开始
          if(received==1)                                           //收到一个字节的数据啦?
             {                                                      //是……
             received=0;                                           //知道了……
             ad[i++]= receing_data;                              //原封不动打回原籍
                         if(i>3)
                           {
                              i=0;
                             for(j=0;j<4;j++)
                                   {
                                     send_byte(ad[j]);
                                   }
                             
                           }
             }                                                      //收到字节处理完毕
          }                                                         //主循环体结束
}                                                           //主程序结束


阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-4-19 17:33:56 | 显示全部楼层
楼主用的是STC的例子吧,这个本人也用过,移植到STM8上也没有问题

出0入0汤圆

发表于 2014-4-19 19:01:49 | 显示全部楼层

出0入4汤圆

发表于 2014-4-19 20:09:38 | 显示全部楼层
用示波器抓一下波形,给代码很难看出来的

出0入0汤圆

发表于 2014-4-19 20:36:03 | 显示全部楼层
奉劝电工别给自己找麻烦了 老板不差个串口钱  搞这种不稳定的 出了问题还麻烦
把成本往转嫁给用户就好了

电工们顶起

出0入0汤圆

发表于 2014-4-19 21:06:16 | 显示全部楼层
十分佩服楼主的“执着”,不过这个程序实用意义不大,研究还行。
遇到资源的问题,真正考验的是解决这个问题的方法,单片机缺串口,要么换单片机,要么外挂串口芯片,用GPIO模拟可能是最不好的方法。

出0入4汤圆

 楼主| 发表于 2014-4-21 08:29:53 | 显示全部楼层
xyz2008 发表于 2014-4-19 17:33
楼主用的是STC的例子吧,这个本人也用过,移植到STM8上也没有问题

但是连续发多个数据怎么,怎么返回的数据错了,你有连续接收和发送多个数据的例子吗?能上传上来吗。

出0入4汤圆

 楼主| 发表于 2014-4-21 08:33:09 | 显示全部楼层
avr-arm 发表于 2014-4-19 21:06
十分佩服楼主的“执着”,不过这个程序实用意义不大,研究还行。
遇到资源的问题,真正考验的是解决这个问 ...

刚到一个公司,接收别人的项目,做好了板子,让我编程,修改电路,没办法啊,公司大都用的模拟串口,我以前也没这样做过。

出0入0汤圆

发表于 2014-4-21 08:46:34 | 显示全部楼层
做过一个9600bps取部分数据转4800bps的(单向),全是模拟串口的

出100入101汤圆

发表于 2014-4-21 09:03:15 | 显示全部楼层
波特率做不高,系统资源占用大。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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