找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9466|回复: 8
打印 上一主题 下一主题
收起左侧

51单片机普通IO口模拟串口源程序

  [复制链接]
跳转到指定楼层
楼主
ID:140725 发表于 2016-10-18 14:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
完整代码下载:
Xserial.zip (1.37 KB, 下载次数: 164)


大家放心用,但是你们程序要好好看看,容易中断冲突,现在我们也在解决中,接收和发送字符串的程序有需要的邮箱给你们发送过去

东西是好东西,我们遇到了中断问题,有点麻烦,数据采集上来后用模拟串口挂到485总线,向一个控制单片机发送数据,用12864显示,但是控制单片机的串口通信的中断和模拟串口中断冲突,上位机和下位机没有办法通信,今天下午实在没有办法了,又做了一块单片机最小系统,让采集板上的数据之间和这块最小系统板进行通信12864上显示,现在还没有想到好的解决办法,等解决之后再告诉大家,还有就是接受字符串的时候,先进行解包,再进行标识位检测,这个程序发程序的方法是一个一个字符发送的,接收的时候要先放进数组里面,要是有需要的可以单独联系我,希望大家共同进步。

这两天项目结项,一直比较忙,没来得及回复大家,这个程序非常有用吗,毕竟大部分的单片机串口都是一个到两个,有时候功能扩展的时候,不可避免的要使用串口,当你发现串口不够用的时候,你可以使用这个程序,我把接收函数给大家参考一下

   while(1)
  {
    if(StartBitOn())
    {
          Msg[i_L]=PGetChar();
          if(Msg[i_L]!='a')
          {
            i_L++;
          }
          else
          {  
                i_L=0;
                chinese_disp(0,2,"温度");//这个是12864液晶显示函数大家不用管
          }
         }
        }

说实话,这东西用起来虽然挺好,但是能不用就不要用,现在单片机大都是双串口的,一般都够用,我们做的东西,用52单片机模拟串口通信,模拟modbus通信,三个定时器全开,中断全用,时序容易出错,所以建议大家不要过多依赖模拟的东西,能花点钱买个好点片子,减少开发周期,上策。


预览:
  1. #include "reg52.h"
  2. #include "intrins.h"  
  3. #include "math.h"     
  4. #include "stdio.h"
  5. sbit BT_SND =P1^5;
  6. sbit BT_REC =P1^6;
  7. sbit LED =P1^7;
  8. bit  LED_flage=1;
  9. //IO 口模拟232通讯程序
  10. //使用两种方式的C程序 占用定时器0
  11. #define MODE_QUICK
  12. #define F_TM F0
  13. #define TIMER0_ENABLE  TL0=TH0; TR0=1;
  14. #define TIMER0_DISABLE TR0=0;
  15. sbit ACC0=   ACC^0;
  16. sbit ACC1=   ACC^1;
  17. sbit ACC2=   ACC^2;
  18. sbit ACC3=   ACC^3;
  19. sbit ACC4=   ACC^4;
  20. sbit ACC5=   ACC^5;
  21. sbit ACC6=   ACC^6;
  22. sbit ACC7=   ACC^7;

  23. void IntTimer0() interrupt 1
  24. {
  25.   F_TM=1;
  26. }
  27. //发送一个字符
  28. void PSendChar(unsigned char inch)
  29. {
  30. #ifdef MODE_QUICK
  31.     ACC=inch;
  32.     F_TM=0;
  33.     BT_SND=0; //start bit
  34.     TIMER0_ENABLE; //启动
  35.     while(!F_TM);
  36.     BT_SND=ACC0; //先送出低位
  37.     F_TM=0;
  38.     while(!F_TM);
  39.     BT_SND=ACC1;
  40.     F_TM=0;
  41.     while(!F_TM);
  42.     BT_SND=ACC2;
  43.     F_TM=0;
  44.     while(!F_TM);
  45.     BT_SND=ACC3;
  46.     F_TM=0;
  47.     while(!F_TM);
  48.     BT_SND=ACC4;
  49.     F_TM=0;
  50.     while(!F_TM);
  51.     BT_SND=ACC5;
  52.     F_TM=0;
  53.     while(!F_TM);
  54.     BT_SND=ACC6;
  55.     F_TM=0;
  56.     while(!F_TM);
  57.     BT_SND=ACC7;
  58.     F_TM=0;
  59.     while(!F_TM);
  60.     BT_SND=1;
  61.     F_TM=0;
  62.     while(!F_TM);
  63.     TIMER0_DISABLE; //停止timer
  64.     #else
  65.     unsigned char ii;
  66.      ii=0;
  67.      F_TM=0;
  68.      BT_SND=0; //start bit
  69.      TIMER0_ENABLE; //启动
  70.      while(!F_TM);
  71.      while(ii<8)
  72.         {
  73.           if(inch&1)
  74.          {
  75.           BT_SND=1;
  76.          }
  77.          else
  78.          {
  79.           BT_SND=0;
  80.          }
  81.           F_TM=0;
  82.         while(!F_TM);
  83.           ii++;
  84.          inch>>=1;
  85.     }
  86.          BT_SND=1;
  87.          F_TM=0;
  88.          while(!F_TM);
  89.     #endif
  90.     TIMER0_DISABLE; //停止timer
  91. }
  92. //接收一个字符
  93. unsigned char PGetChar()
  94. {
  95.         #ifdef MODE_QUICK
  96.         TIMER0_ENABLE;
  97.         F_TM=0;
  98.         while(!F_TM); //等过起始位
  99.         ACC0=BT_REC;
  100.         TL0=TH0;
  101.         F_TM=0;
  102.         while(!F_TM);
  103.         ACC1=BT_REC;
  104.         F_TM=0;
  105.         while(!F_TM);
  106.         ACC2=BT_REC;
  107.         F_TM=0;
  108.         while(!F_TM);
  109.         ACC3=BT_REC;
  110.         F_TM=0;
  111.         while(!F_TM);
  112.         ACC4=BT_REC;
  113.         F_TM=0;
  114.         while(!F_TM);
  115.         ACC5=BT_REC;        
  116.         F_TM=0;
  117.         while(!F_TM);
  118.         ACC6=BT_REC;        
  119.         F_TM=0;
  120.         while(!F_TM);
  121.         ACC7=BT_REC;
  122.         F_TM=0;
  123.         while(!F_TM)
  124.     {
  125.                 if(BT_REC)
  126.                 {
  127.                   break;
  128.                 }
  129.     }
  130.         TIMER0_DISABLE; //停止timer
  131.         return ACC;
  132.         #else
  133.         unsigned char rch,ii;
  134.         TIMER0_ENABLE;
  135.         F_TM=0;
  136.         ii=0;
  137.         rch=0;
  138.         while(!F_TM); //等过起始位
  139.         while(ii<8)
  140.     {
  141.             rch>>=1;
  142.                 if(BT_REC)
  143.                 {
  144.                 rch|=0x80;
  145.                 }                                       
  146.                 ii++;
  147.                 F_TM=0;
  148.                 while(!F_TM);        
  149.     }
  150.         F_TM=0;
  151.          while(!F_TM)
  152.     {
  153.                 if(BT_REC)
  154.                 {
  155.                    break;
  156.                 }
  157.     }
  158.         TIMER0_DISABLE; //停止timer
  159.         return rch;
  160.         #endif
  161. }
  162. //检查是不是有起始位
  163. bit StartBitOn()
  164. {
  165.   return (BT_REC==0);
  166. }
  167. //定时器1初始化
  168. void Time1_Init(void)
  169. {
  170.    TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装)
  171.    PCON=00;
  172.    TR0=0; //在发送或接收才开始使用
  173.    TF0=0;
  174.    TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 执行的timer//104.167*11.0592/12= 96
  175.    TL0=TH0;
  176.    ET0=1;
  177.    EA=1;
  178. }
  179. //发送字符串
  180. void Send_Char(char *byte)
  181. {
  182.    int i=0;
  183.    for(i=0;*(byte+i)!='\0';i++)
  184.    {
  185.       PSendChar(*(byte+i));
  186.    }
  187. }
  188. //void delay(int x)
  189. //{
  190. //        int a,b;
  191. //        for(a=x;a>0;a--)
  192. //                for(b=10;b>0;b--);
  193. //}
  194. //void main()
  195. //{
  196. //   unsigned char gch;
  197. //   Time1_Init();
  198. //   LED=0;
  199. //  // Send_Char("S00.0C00.0%E00.0C00.0%L00000lx");
  200. //   while(1)
  201. //  {         
  202. //      
  203. //          PSendChar('1');
  204. //          delay(1000);
  205. ////      if(StartBitOn())
  206. ////          {
  207. ////            gch=PGetChar();
  208. ////            if(gch=='1')
  209. ////                {
  210. ////                  LED=LED_flage;  
  211. ////                  delay(1000);
  212. ////                  LED_flage=~LED_flage;
  213. ////                }
  214. ////               
  215. ////          }        
  216. //           
  217. //  }           
  218. //
  219. //}
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:164411 发表于 2017-4-24 14:53 | 只看该作者
你好能发给大家 接收字符串的吗?
回复

使用道具 举报

板凳
ID:164411 发表于 2017-4-24 15:06 | 只看该作者
我可以模拟得了串口接收到数据,但是总接收不到字符串
回复

使用道具 举报

地板
ID:128463 发表于 2017-5-1 12:16 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

5#
ID:593300 发表于 2019-7-31 20:52 来自手机 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

6#
ID:596409 发表于 2019-8-20 17:42 | 只看该作者
这个程序试过,为什么发送的时候连续的字符会丢失中间的,如果加一个空格就都可以收到
回复

使用道具 举报

7#
ID:301055 发表于 2019-8-20 23:41 | 只看该作者
十分感谢  开源万岁
回复

使用道具 举报

8#
ID:339215 发表于 2022-3-23 17:46 | 只看该作者
parmhan 发表于 2019-8-20 17:42
这个程序试过,为什么发送的时候连续的字符会丢失中间的,如果加一个空格就都可以收到

做个缓存,然后从缓存发出去不会
回复

使用道具 举报

9#
ID:847934 发表于 2022-4-3 12:37 | 只看该作者
小屁 发表于 2022-3-23 17:46
做个缓存,然后从缓存发出去不会

请问做缓存应该怎么做呢?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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