找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC8A单片机通过串口写入数据存到EEPROM,两条命令单独运行正常,一起运行有一条me...

[复制链接]
跳转到指定楼层
楼主
80黑币
STC8A单片机通过串口写入数据存到EEPROM,两条命令单独运行正常,一起运行有一条能运行
CF 01 04 FD这条命令执行不了
单片机源程序如下:
  1. #include "Uart.h"

  2. bit   busy;          //判忙标志
  3. uchar idata SinBuf[20];    //接收缓冲区
  4. uint  SinP;          //接收指针
  5. uchar idata SoutBuf[20];   //发送缓冲区

  6. uint  SoutP;         //发送指针

  7. uchar Send_OK,Sin_OK;       //发送完成标志
  8. U32   Ul_Value,RXDATA,ADDR_485;      //超声波值
  9. /**************************************初始化串口********************************************/
  10. void UartInit(void)
  11. {
  12.     SCON = 0x50;
  13.     T2L = BRT;
  14.     T2H = BRT >> 8;
  15.     AUXR = 0x15;

  16.     busy = 0;

  17.     ES = 1;
  18.           EA = 1;
  19. }
  20. /**************************************串口服务函数*******************************************/

  21. void ReceiveChar (void) interrupt 4 using 3
  22. {
  23.   uchar ch;
  24.         uchar idata Start=0xCF;//帧头;
  25.         uchar idata End=0xFD;//帧尾;  


  26.         static bit bReceiveAdr= 0;    //接收地址标志  
  27.         uchar ucharAdr;//存放地址;

  28.         static bit bReceiveCmd= 0;    //接收命令标志  
  29.         uchar ucharCmd;         //存放命令;  

  30.         static bit bReceiveEnd=0;//接收帧尾标志;
  31.         bit bReceiveComplete=0;    //收到一个完整的数据包(导引头+地址+数据+帧尾)例:CF 00 04 FD


  32. //*********************
  33.   if (RI)
  34.   {
  35.   ES = 0;
  36.   RI = 0;
  37.   ch=SBUF;
  38.                
  39.   SinBuf[SinP]=ch;
  40.   SinP= SinP+1;
  41.         SW_Ctrl  = 0;

  42. if(ch==Start)//如果收到帧头;
  43.                 {
  44.                         bReceiveAdr=1;//接收地址标志1,准备接收地址;
  45.                         bReceiveComplete=0;// 完整帧数据包状态为0;
  46.                         
  47.                 }
  48.                 else if(bReceiveAdr==1)//开始接收地址
  49.                 {        ucharAdr=SinBuf[2];
  50.                         bReceiveAdr=0;//清除地址标志;
  51.                         bReceiveCmd=1;//准备接收命令;
  52.                 }
  53.                 else if(bReceiveCmd==1)//开始接收命令;
  54.                 {        ucharCmd=ch;
  55.                         bReceiveCmd=0;
  56.                         bReceiveEnd=1;
  57.                 }
  58.                 else if(bReceiveEnd ==1 &&(SinBuf[3]==End))//如果帧尾是End;//就代表一帧数据包完成;
  59.             {        bReceiveComplete=1;
  60.                 }

  61.                 else//收到干扰;
  62.                 {
  63.                         bReceiveAdr=0;
  64.                         bReceiveCmd=0;
  65.                         bReceiveEnd=0;
  66.                         bReceiveComplete=0;
  67.                         //ucharAdr=0;
  68.                 }

  69.                 if(bReceiveComplete ==1)//如果有完整的数据包;
  70.                 {

  71.                          if(SinBuf[2]==0x04)//查询  //如果是查询命令,就把对应的地址位的值取回来,按格式发回上位机;
  72.                         {        
  73.                                 
  74.                                 CommandType();

  75.       SinP= 0;
  76.                         Sin_OK = 1;
  77.                
  78.                

  79.                         }
  80.                         
  81.                 }
  82.          if (SinBuf[0] != 0x06 )
  83.         {
  84.     SinP= 0;
  85.     SinBuf[1] = 0;

  86.     }
  87.   if ((SinP == 8)&& (SinBuf[3] == 0x00))//修改这行可更换寄存器地址
  88.     {
  89.     SinP= 0;
  90.     Send_OK = 1;
  91.                         //return;

  92.         }

  93.   ES = 1;
  94.   }
  95.         
  96.   if (TI)//发送----------------
  97.   {
  98.                 ES = 0;
  99.                 TI = 0;

  100.    if (SoutP < 7)
  101.     {
  102.     SBUF = SoutBuf[SoutP];
  103.     SoutP= SoutP+ 1;
  104.     }
  105.         }
  106.   else
  107.     {
  108.     SW_Ctrl = 0;
  109.     SoutP=1;//发送指针归零
  110.                
  111.     }
  112.         
  113.                 ES = 1;
  114.   }//发送


  115. /**************************************发送03号指令*******************************************/
  116. void Respond03(void)
  117. {
  118.   unsigned int x;
  119.   unsigned int i ;
  120.   SoutBuf[0] = 0x06;//
  121.   SoutBuf[1] = 0x03;//A型号:01,B型号:02
  122.   SoutBuf[2] = 0x02;
  123.   SoutBuf[3] = ((Ul_Value & 0xFF00)>>8);
  124.   SoutBuf[4] = (Ul_Value & 0x00FF);
  125.   x = 0xffff;
  126.   for (i = 0;i<5 ; i++)
  127.   x = CRC_modbus_rtu(x,SoutBuf[i]);

  128.   SoutBuf[5] = (x & 0x00FF);
  129.   SoutBuf[6] = ((x & 0xFF00)>>8);

  130.   SoutP = 1;
  131.   SW_Ctrl = 1;
  132.   SBUF = 0x06;//启动中断发送
  133. }

  134. /*-------------------------------------------------------------
  135. 调用方式:void CommandType(void)
  136. 函数说明:
  137. ---------------------------------------------------------------*/
  138. void CommandType(void)
  139. {
  140. //  uchar CommandLong;
  141. //  CommandLong = SinBuf[1];
  142. //  if (SinBuf[0] != 0xCF)
  143. //    return;
  144. //  if (SinBuf[CommandLong - 1] != 0xFD)
  145. //    return;
  146.   switch (SinBuf[1])
  147.     {
  148.     case 0x01://采集器发送请求
  149.       {
  150.       RXDATA = 0x01;
  151.                   IapErase(0x0400);                         //擦除0400扇区数据         
  152.             IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  153.       break;
  154.       }
  155.     case 0x02:
  156.       {
  157.        RXDATA = 0x02;
  158.                    IapErase(0x0400);                         //擦除0400扇区数据         
  159.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  160.       break;
  161.       }
  162.        case 0x03:
  163.       {
  164.        RXDATA = 0x03;
  165.                    IapErase(0x0400);                         //擦除0400扇区数据         
  166.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  167.       break;
  168.       }    case 0x04:
  169.       {
  170.        RXDATA = 0x04;
  171.                    IapErase(0x0400);                         //擦除0400扇区数据         
  172.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  173.       break;
  174.       }    case 0x05:
  175.       {
  176.        RXDATA = 0x05;
  177.                    IapErase(0x0400);                         //擦除0400扇区数据         
  178.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  179.       break;
  180.       }    case 0x06:
  181.       {
  182.        RXDATA = 0x06;
  183.                    IapErase(0x0400);                         //擦除0400扇区数据         
  184.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  185.       break;
  186.       }    case 0x07:
  187.       {
  188.        RXDATA = 0x07;
  189.                    IapErase(0x0400);                         //擦除0400扇区数据         
  190.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  191.       break;
  192.       }    case 0x08:
  193.       {
  194.        RXDATA = 0x08;
  195.                    IapErase(0x0400);                         //擦除0400扇区数据         
  196.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  197.       break;
  198.       }    case 0x09:
  199.       {
  200.        RXDATA = 0x09;
  201.                    IapErase(0x0400);                         //擦除0400扇区数据         
  202.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  203.       break;
  204.       }    case 0x0A:
  205.       {
  206.        RXDATA = 0x0A;
  207.                    IapErase(0x0400);                         //擦除0400扇区数据         
  208.              IapProgram(0x0400, RXDATA);                    //在0400写入数据        
  209.       break;
  210.       }
  211.     }
  212. }
  213. void Respond01(void)
  214. {
  215.   ADDR_485 =         RXDATA;
  216.   SoutBuf[0] = 0xCF;//
  217.   SoutBuf[1] = ADDR_485;//A型号:01,B型号:02
  218.   SoutBuf[2] = 0x04;
  219.   SoutBuf[3] = 0xFD;
  220.   SoutP = 1;
  221.   SW_Ctrl = 1;
  222.   SBUF = 0xCF;//启动中断发送
  223. }
  224. void Respond02(void)
  225. {

  226.   SoutBuf[0] = 0xCF;//
  227.   SoutBuf[1] = ADDR_485;//A型号:01,B型号:02
  228.   SoutBuf[2] = 0x04;
  229.   SoutBuf[3] = 0xFD;
  230.   SoutP = 1;
  231.   SW_Ctrl = 1;
  232.   SBUF = 0xCF;//启动中断发送
  233. }
复制代码

3.png (32.07 KB, 下载次数: 42)

3.png

4.png (14.46 KB, 下载次数: 40)

4.png

2.png (59.74 KB, 下载次数: 45)

2.png

1.png (50.81 KB, 下载次数: 60)

1.png

Uart.rar

2.16 KB, 下载次数: 9

串口部分

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

使用道具 举报

沙发
ID:65956 发表于 2020-9-21 08:33 | 只看该作者
提醒一下,串口接收中断处理要时间,你发两条要能满足它的处理时间它才会接收处理,另外写EEPROM处理也需要时间,把这些时间差错开就没有问题了,比如你要连续发,在这两条中间发时加一些延时,这样串口中断有时间处理数据并存储就可以完成你要的结果了
回复

使用道具 举报

板凳
ID:411221 发表于 2020-9-21 19:10 | 只看该作者
aking991 发表于 2020-9-21 08:33
提醒一下,串口接收中断处理要时间,你发两条要能满足它的处理时间它才会接收处理,另外写EEPROM处理也需要 ...

并不是延时的问题,是CF 04 04 FD,和06 03 40 00 00 01 9D 7F这两条分别运行可以,但是两条同时运行只有06 03 40 00 00 01 9D 7F可以运行,CF 04 04 FD不能运行。暂时没有找到原因
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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