找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于STC12C2502AD单片机控制8路继电器动作的程序问题

[复制链接]
跳转到指定楼层
楼主
5黑币
为了工作方便想开发一个8继电器的开关电源作为工具使用;
于是买了带单片机的模块,以及拿到C 语言源代码,如下。但是由于新手+基础薄弱,在修改一些语句后,编译仍然出现warnings,虽生存hex文件,但是XCOM串口工具通过给的协议无法调试单片机模块;
想在这跟大佬请教,指出错误。

/*************以下是main.c源代码******************/
  1. #include <reg51.h>
  2. #include <intrins.H>
  3. #include <EEPROM.h>
  4. #define uchar unsigned char
  5.         
  6. sbit K1=P1^0;
  7. sbit K2=P1^1;
  8. sbit K3=P1^2;
  9. sbit K4=P1^3;
  10. sbit K5=P1^4;
  11. sbit K6=P1^5;
  12. sbit K7=P1^6;
  13. sbit K8=P1^7;
  14. uchar dat;
  15. uchar t,r,ii;
  16. uchar add;//掉电保持485地址
  17. uchar j=0;
  18. bit flag_zx=0;
  19. uchar sendBuf[10];
  20. uchar receBuf[10];
  21. bit busy;
  22. bit bz1=0;
  23. bit bz2=0;
  24. bit bz3=0;
  25. bit bz4=0;
  26. bit bz5=0;
  27. bit bz6=0;
  28. bit bz7=0;
  29. bit bz8=0;

  30. void delay(uchar t)
  31. {
  32.         uchar i,j;
  33.         for(i=0;i<t;i++)
  34.         {for(j=13;j>0;j--);
  35.                 {;
  36.                 }
  37.         }
  38. }
  39. /*********************************************
  40. 延时函数
  41. *********************************************/

  42. /*********************************************
  43. 串口初始化,波特率9600,方式1
  44. **********************************************/
  45. void Init_Com(void)
  46. {
  47.         TMOD=0x20;
  48.         PCON=0x00;
  49.         SCON=0x50;
  50.         TH1=0xFd;
  51.         TL1=0xFd;
  52.         TR1=1;ES=1;EA=1;
  53. }
  54. /***********发送函数***************************/
  55. void senduart2()
  56. {
  57.         //RS485_DIR=1;
  58.         SBUF=sendBuf[0];while(!TI);TI=0;
  59.         SBUF=sendBuf[1];while(!TI);TI=0;
  60.         SBUF=sendBuf[2];while(!TI);TI=0;
  61.         SBUF=sendBuf[3];while(!TI);TI=0;
  62.         SBUF=sendBuf[4];while(!TI);TI=0;
  63. }
  64. /******************清空发送缓冲区***************/
  65. void clear_receBuf()
  66. {
  67.         uchar i;
  68.         for(i=0;i<5;i++)
  69.         {
  70.                 receBuf[i]=0;
  71.         }
  72. }


  73. /************************************
  74. 主函数
  75. ************************************/

  76.    
  77. void main()
  78.         

  79. {
  80.         Init_Com();//串口初始化
  81.         add=IapReadByte(0);//add=0x00;
  82.         
  83.         while(1)
  84.         {
  85.                 /*uchar k;
  86.                 k=100;
  87.                 if((IN0==0)&&(bz1==0)){delay(k);if(IN0==0){delay(k);k1=!k1;bz1=1;}}if(bz1==1)&&(IN0==1)){delay(k);bz1=0;}
  88.           if((IN1==0)&&(bz2==0)){delay(k);if(IN1==0){delay(k);k2=!k2;bz2=1;}}if(bz2==1)&&(IN1==1)){delay(k);bz2=0;}
  89.           if((IN2==0)&&(bz3==0)){delay(k);if(IN2==0){delay(k);k3=!k3;bz3=1;}}if(bz3==1)&&(IN2==1)){delay(k);bz3=0;}
  90.                 if((IN3==0)&&(bz4==0)){delay(k);if(IN3==0){delay(k);k4=!k4;bz4=1;}}if(bz4==1)&&(IN3==1)){delay(k);bz4=0;}
  91.                 if((IN4==0)&&(bz5==0)){delay(k);if(IN4==0){delay(k);k5=!k5;bz5=1;}}if(bz5==1)&&(IN4==1)){delay(k);bz5=0;}
  92.           if((IN5==0)&&(bz6==0)){delay(k);if(IN5==0){delay(k);k6=!k6;bz6=1;}}if(bz6==1)&&(IN5==1)){delay(k);bz6=0;}
  93.           if((IN6==0)&&(bz7==0)){delay(k);if(IN6==0){delay(k);k7=!k7;bz7=1;}}if(bz7==1)&&(IN6==1)){delay(k);bz7=0;}
  94.                 if((IN7==0)&&(bz8==0)){delay(k);if(IN7==0){delay(k);k8=!k8;bz8=1;}}if(bz8==1)&&(IN7==1)){delay(k);bz8=0;}
  95. /***********************************
  96.                 接收数据判断函数
  97. ************************************/
  98. if(RI)//如果有接收
  99. {
  100.         RI=0;//接收标志清零
  101.         receBuf[r++&0x0f]=SBUF;//把接收的数据存到BUT数组中
  102.         if(receBuf[0]!=0xaa){r=0;}
  103.         if(r>=5)
  104.         {r=0;
  105.                 flag_zx=1;
  106.         }
  107. }
  108. if(flag_zx==1)
  109. {
  110.         flag_zx=0;
  111.                
  112.                                           //0          1       2        3       4                           
  113.                                           //起始位   地址位  功能位   数据位  结束位
  114.                                           if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add))                //如果开始位和结束位,还有地址都正确,进行下一步判断
  115.                                           {
  116.                                              if(receBuf[2]==0x01)  //修改板子地址
  117.                                              {
  118.                                                   add=receBuf[3];
  119.                                                   IapEraseSector(0);  //擦除扇区
  120.                                                   IapProgramByte(0,add);//写入新的地址                                      
  121.                                                   sendBuf[0]=0xaa;
  122.                                                   sendBuf[1]=add;
  123.                                                   sendBuf[2]=0x00;
  124.                                                   sendBuf[3]=add;
  125.                                                   sendBuf[4]=0xbb;
  126.                                                   senduart2();
  127. }
  128.                                              else if(receBuf[2]==0x02)  //打开单路继电器
  129.                                              {
  130.                                                                switch(receBuf[3])
  131.                                                                       {
  132.                                                                                     case 0x01: K1=0; break;
  133.                                                                                     case 0x02: K2=0; break;
  134.                                                                                     case 0x03: K3=0; break;
  135.                                                                                     case 0x04: K4=0; break;
  136.                                                                                     case 0x05: K5=0; break;
  137.                                                                                     case 0x06: K6=0; break;
  138.                                                                                     case 0x07: K7=0; break;
  139.                                                                                     case 0x08: K8=0; break;
  140.                                                                       }
  141.                                              }
  142.                                              else if(receBuf[2]==0x03)  //关闭单路继电器
  143.                                              {
  144.                                                                switch(receBuf[3])
  145.                                                                       {
  146.                                                                                     case 0x01: K1=1; break;
  147.                                                                                     case 0x02: K2=1; break;
  148.                                                                                     case 0x03: K3=1; break;
  149.                                                                                     case 0x04: K4=1; break;
  150.                                                                                     case 0x05: K5=1; break;
  151.                                                                                     case 0x06: K6=1; break;
  152.                                                                                     case 0x07: K7=1; break;
  153.                                                                                     case 0x08: K8=1; break;
  154.                                                                       }                                 
  155.                                              }
  156.                                              else if(receBuf[2]==0x04)  //打开全部继电器
  157.                                              {
  158.                                                   if(receBuf[3]==0xff)
  159.                                                   {
  160.                                                                                     K1=0;
  161.                                                                                     K2=0;
  162.                                                                                     K3=0;
  163.                                                                                     K4=0;
  164.                                                                                     K5=0;
  165.                                                                                     K6=0;
  166.                                                                                     K7=0;
  167.                                                                                     K8=0;
  168.                                                                       sendBuf[0]=0xaa;
  169.                                                                       sendBuf[1]=add;
  170.                                                                       sendBuf[2]=0xff;
  171.                                                                       sendBuf[3]=0x00;
  172.                                                                       sendBuf[4]=0xbb;
  173.                                                                       senduart2();
  174.                                                                       }
  175.                                              }
  176.                                              else if(receBuf[2]==0x05)  //关闭全部继电器
  177.                                              {
  178.                                                   if(receBuf[3]==0x00)
  179.                                                   {
  180.                                                                                     K1=1;
  181.                                                                                     K2=1;
  182.                                                                                     K3=1;
  183.                                                                                     K4=1;
  184.                                                                                     K5=1;
  185.                                                                                     K6=1;
  186.                                                                                     K7=1;
  187.                                                                                     K8=1;
  188.                                                                       sendBuf[0]=0xaa;
  189.                                                                       sendBuf[1]=add;
  190.                                                                       sendBuf[2]=0x07;
  191.                                                                       sendBuf[3]=0x00;
  192.                                                                       sendBuf[4]=0xbb;
  193.                                                                       senduart2();
  194.                                                                       }                                 
  195.                                              }
  196.                                              else if(receBuf[2]==0x06)  //查询继电器
  197.                                              {
  198.                                                                       sendBuf[0]=0xaa;
  199.                                                                       sendBuf[1]=add;
  200.                                                                       sendBuf[2]=0x07;
  201.                                                                       sendBuf[3]=0xfe;
  202.                                                                       sendBuf[4]=0xbb;
  203.                                                                      
  204.                                                  switch(receBuf[3])
  205.                                                            {
  206.                                                                          case 0x01: if(K1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  207.                                                                          case 0x02: if(K2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  208.                                                                          case 0x03: if(K3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  209.                                                                          case 0x04: if(K4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  210.                                                                          case 0x05: if(K5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  211.                                                                          case 0x06: if(K6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  212.                                                                          case 0x07: if(K7==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  213.                                                                          case 0x08: if(K8==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  214.                                                                          default:break;
  215.                                                            }
  216.                                                                        senduart2();
  217.                                              }                                          
  218.                                           }
  219.                                           if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
  220.                                           {
  221.                                                   add=0x00;
  222.                                                  IapEraseSector(0);  //擦除扇区
  223.                                                IapProgramByte(0,0);//写入新的地址   
  224.                                                   sendBuf[0]=0xaa;
  225.                                                   sendBuf[1]=add;
  226.                                                   sendBuf[2]=0x07;
  227.                                                   sendBuf[3]=0x00;
  228.                                                   sendBuf[4]=0xbb;
  229.                                                   senduart2();
  230.                                                                                                                                                                                 
  231.                                           }
  232.                                           clear_receBuf();
  233.                             }
  234.                              /*if(Program==1)
  235.                                                                                                                 {
  236.                                                                                                                 Program=0;
  237.                                                                                                                 KK1=P0;
  238.                                                                                                                 KK2=P1;
  239.                                                                                                                 KK3=P2;
  240.                                                                                                                 KK4=P3;
  241.                                                                                                                 IapEraseSector(0);
  242.                                                                                                                  IapProgramByte(0,KK1);
  243.                                                                                                                  IapProgramByte(0,KK2);
  244.                                                                                                                  IapProgramByte(0,KK3);
  245.                                                                                                                  IapProgramByte(0,KK4);
  246.              }*/
  247. }
  248. }
  249. /*****结束*****/
复制代码
/*************以下是EEPROM.h源代码, 用于main.c调用******************/
  1. #ifndef _EERPOM_H_
  2. #define _EEPROM_H_

  3. #include "reg51.h"
  4. #include "intrins.h"
  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;


  7. /*Declare SFR associated with the IAP */
  8. sfr IAP_DATA = 0xE2; //Flash data register
  9. sfr IAP_ADDRH = 0xE3; //Flash address HIGH
  10. sfr IAP_ADDRL = 0xE4; //Flash address LOW
  11. sfr IAP_CMD = 0xE5; //Flash command register
  12. sfr IAP_TRIG = 0xE6; //Flash command trigger
  13. sfr IAP_CONTR = 0xE7; //Flash control register
  14. /*Define ISP/IAP/EEPROM command*/
  15. #define CMD_IDLE 0 //Stand-By
  16. #define CMD_READ 1 //Byte-Read
  17. #define CMD_PROGRAM 2 //Byte-Program
  18. #define CMD_ERASE 3 //Sector-Erase
  19. /*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
  20. //#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
  21. //#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
  22. #define ENABLE_IAP 0x82 //if SYSCLK<20MHz
  23. //#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
  24. //#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
  25. //#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
  26. //#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
  27. //#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
  28. //Start address for STC12C2052AD series EEPROM
  29. #define IAP_ADDRESS 0x0000
  30. void Delay(BYTE n);
  31. void IapIdle();
  32. BYTE IapReadByte(WORD addr);
  33. void IapProgramByte(WORD addr, BYTE dat);
  34. void IapEraseSector(WORD addr);

  35. #endif
复制代码
/***********以下是Warnings******************/

Build started: Project: 20211123
Build target 'Target 1'
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DELAY?MAIN
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  _IAPERASESECTOR
    MODULE:  .\Objects\main.obj (MAIN)
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  _IAPPROGRAMBYTE
    MODULE:  .\Objects\main.obj (MAIN)
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  _IAPREADBYTE
    MODULE:  .\Objects\main.obj (MAIN)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  _IAPREADBYTE
    MODULE:  .\Objects\main.obj (MAIN)
    ADDRESS: 000AH
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  _IAPERASESECTOR
    MODULE:  .\Objects\main.obj (MAIN)
    ADDRESS: 0064H
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  _IAPPROGRAMBYTE
    MODULE:  .\Objects\main.obj (MAIN)
    ADDRESS: 006CH
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  _IAPERASESECTOR
    MODULE:  .\Objects\main.obj (MAIN)
    ADDRESS: 0236H
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  _IAPPROGRAMBYTE
    MODULE:  .\Objects\main.obj (MAIN)
    ADDRESS: 023DH
Program Size: data=36.2 xdata=0 code=872
creating hex file from ".\Objects\20211123"...
".\Objects\20211123" - 0 Error(s), 9 Warning(s).
Build Time Elapsed:  00:00:01

求助以上问题,不胜感激

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

使用道具 举报

沙发
ID:624769 发表于 2021-12-8 22:55 | 只看该作者
如果是: STC12C2502AD
首先, include  STC12C2502AD 的头文件,
然后, STC12C2502AD  需要设置端口模式,你可以参考手册。

然后,最关键的警告,你调用了 Eeprom 相关的函数, 但是,你并没有提供实体函数,仅仅声明了,这么一个函数,内部是空的。
回复

使用道具 举报

板凳
ID:213173 发表于 2021-12-9 06:24 | 只看该作者
没有相关的函数可以调用,缺少EEPROM.c文件。给你补齐了。
  1. #include <reg51.h>
  2. #include <intrins.H>
  3. //#include <EEPROM.h>
  4. #define uchar unsigned char
  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;
  7. /*Declare SFR associated with the IAP */
  8. sfr IAP_DATA    =   0xE2;           //Flash data register
  9. sfr IAP_ADDRH   =   0xE3;           //Flash address HIGH
  10. sfr IAP_ADDRL   =   0xE4;           //Flash address LOW
  11. sfr IAP_CMD     =   0xE5;           //Flash command register
  12. sfr IAP_TRIG    =   0xE6;           //Flash command trigger
  13. sfr IAP_CONTR   =   0xE7;           //Flash control register
  14. /*Define ISP/IAP/EEPROM command*/
  15. #define CMD_IDLE    0               //Stand-By
  16. #define CMD_READ    1               //Byte-Read
  17. #define CMD_PROGRAM 2               //Byte-Program
  18. #define CMD_ERASE   3               //Sector-Erase
  19. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz
  20. #define IAP_ADDRESS 0x0000

  21. sbit K1=P1^0;
  22. sbit K2=P1^1;
  23. sbit K3=P1^2;
  24. sbit K4=P1^3;
  25. sbit K5=P1^4;
  26. sbit K6=P1^5;
  27. sbit K7=P1^6;
  28. sbit K8=P1^7;

  29. uchar dat;
  30. uchar t,r,ii;
  31. uchar add;//掉电保持485地址
  32. uchar j=0;
  33. bit flag_zx=0;
  34. uchar sendBuf[10];
  35. uchar receBuf[10];
  36. bit busy;
  37. bit bz1=0;
  38. bit bz2=0;
  39. bit bz3=0;
  40. bit bz4=0;
  41. bit bz5=0;
  42. bit bz6=0;
  43. bit bz7=0;
  44. bit bz8=0;

  45. void Delay(BYTE n);
  46. void IapIdle();
  47. BYTE IapReadByte(WORD addr);
  48. void IapProgramByte(WORD addr, BYTE dat);
  49. void IapEraseSector(WORD addr);

  50. /*********************************************
  51. 延时函数
  52. *********************************************/
  53. /*
  54. void delay(uchar t)
  55. {
  56.         uchar i,j;
  57.         for(i=0;i<t;i++)
  58.                 for(j=13;j>0;j--);
  59. }*/
  60. /*********************************************
  61. 串口初始化,波特率9600,方式1
  62. **********************************************/
  63. void Init_Com(void)
  64. {
  65.         TMOD=0x20;
  66.         PCON=0x00;
  67.         SCON=0x50;
  68.         TH1=0xFd;
  69.         TL1=0xFd;
  70.         TR1=1;
  71. //        ES=1;//查询方式不需开中断
  72. //        EA=1;
  73. }
  74. /***********发送函数***************************/
  75. void senduart2()
  76. {
  77.         //RS485_DIR=1;
  78.         SBUF=sendBuf[0];while(!TI);TI=0;
  79.         SBUF=sendBuf[1];while(!TI);TI=0;
  80.         SBUF=sendBuf[2];while(!TI);TI=0;
  81.         SBUF=sendBuf[3];while(!TI);TI=0;
  82.         SBUF=sendBuf[4];while(!TI);TI=0;
  83. }
  84. /******************清空发送缓冲区***************/
  85. void clear_receBuf()
  86. {
  87.         uchar i;
  88.         for(i=0;i<5;i++)
  89.         {
  90.                 receBuf[i]=0;
  91.         }
  92. }
  93. /************************************
  94. 主函数
  95. ************************************/
  96. void main()
  97. {
  98.         Init_Com();//串口初始化
  99.         add=IapReadByte(0);//add=0x00;
  100.         while(1)
  101.         {
  102.                 if(RI)//如果有接收
  103.                 {
  104.                         RI=0;//接收标志清零
  105.                         receBuf[r]=SBUF;//把接收的数据存到BUT数组中
  106.                         if(receBuf[0]==0xaa)//验证数据头,否则下次接收覆盖receBuf[0]
  107.                         {
  108.                                 r++;
  109.                                 if(r>=5)
  110.                                 {
  111.                                         r=0;
  112.                                         flag_zx=1;
  113.                                 }
  114.                         }
  115.                 }
  116.                 if(flag_zx==1)
  117.                 {
  118.                         flag_zx=0;

  119.                         //  0        1       2        3       4                           
  120.                         //起始位   地址位  功能位   数据位  结束位
  121.                         if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add))//如果开始位和结束位,还有地址都正确,进行下一步判断
  122.                         {
  123.                                 if(receBuf[2]==0x01)  //修改板子地址
  124.                                 {
  125.                                         add=receBuf[3];
  126.                                         IapEraseSector(0);  //擦除扇区
  127.                                         IapProgramByte(0,add);//写入新的地址
  128.                                         sendBuf[0]=0xaa;
  129.                                         sendBuf[1]=add;
  130.                                         sendBuf[2]=0x00;
  131.                                         sendBuf[3]=add;
  132.                                         sendBuf[4]=0xbb;
  133.                                         senduart2();
  134.                                 }
  135.                                 else if(receBuf[2]==0x02)  //打开单路继电器
  136.                                 {
  137.                                         switch(receBuf[3])
  138.                                         {
  139.                                                 case 0x01: K1=0; break;
  140.                                                 case 0x02: K2=0; break;
  141.                                                 case 0x03: K3=0; break;
  142.                                                 case 0x04: K4=0; break;
  143.                                                 case 0x05: K5=0; break;
  144.                                                 case 0x06: K6=0; break;
  145.                                                 case 0x07: K7=0; break;
  146.                                                 case 0x08: K8=0; break;
  147.                                         }
  148.                                 }
  149.                                 else if(receBuf[2]==0x03)  //关闭单路继电器
  150.                                 {
  151.                                         switch(receBuf[3])
  152.                                         {
  153.                                                 case 0x01: K1=1; break;
  154.                                                 case 0x02: K2=1; break;
  155.                                                 case 0x03: K3=1; break;
  156.                                                 case 0x04: K4=1; break;
  157.                                                 case 0x05: K5=1; break;
  158.                                                 case 0x06: K6=1; break;
  159.                                                 case 0x07: K7=1; break;
  160.                                                 case 0x08: K8=1; break;
  161.                                         }                                 
  162.                                 }
  163.                                 else if(receBuf[2]==0x04)  //打开全部继电器
  164.                                 {
  165.                                         if(receBuf[3]==0xff)
  166.                                         {
  167.                                                 K1=0;
  168.                                                 K2=0;
  169.                                                 K3=0;
  170.                                                 K4=0;
  171.                                                 K5=0;
  172.                                                 K6=0;
  173.                                                 K7=0;
  174.                                                 K8=0;
  175.                                                 sendBuf[0]=0xaa;
  176.                                                 sendBuf[1]=add;
  177.                                                 sendBuf[2]=0xff;
  178.                                                 sendBuf[3]=0x00;
  179.                                                 sendBuf[4]=0xbb;
  180.                                                 senduart2();
  181.                                         }
  182.                                 }
  183.                                 else if(receBuf[2]==0x05)  //关闭全部继电器
  184.                                 {
  185.                                         if(receBuf[3]==0x00)
  186.                                         {
  187.                                                 K1=1;
  188.                                                 K2=1;
  189.                                                 K3=1;
  190.                                                 K4=1;
  191.                                                 K5=1;
  192.                                                 K6=1;
  193.                                                 K7=1;
  194.                                                 K8=1;
  195.                                                 sendBuf[0]=0xaa;
  196.                                                 sendBuf[1]=add;
  197.                                                 sendBuf[2]=0x07;
  198.                                                 sendBuf[3]=0x00;
  199.                                                 sendBuf[4]=0xbb;
  200.                                                 senduart2();
  201.                                         }                                 
  202.                                 }
  203.                                 else if(receBuf[2]==0x06)  //查询继电器
  204.                                 {
  205.                                         sendBuf[0]=0xaa;
  206.                                         sendBuf[1]=add;
  207.                                         sendBuf[2]=0x07;
  208.                                         sendBuf[3]=0xfe;
  209.                                         sendBuf[4]=0xbb;
  210.                                         switch(receBuf[3])
  211.                                         {
  212.                                                 case 0x01: if(K1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  213.                                                 case 0x02: if(K2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  214.                                                 case 0x03: if(K3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  215.                                                 case 0x04: if(K4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  216.                                                 case 0x05: if(K5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  217.                                                 case 0x06: if(K6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  218.                                                 case 0x07: if(K7==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  219.                                                 case 0x08: if(K8==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  220.                                                 default:break;
  221.                                         }
  222.                                         senduart2();
  223.                                 }                                          
  224.                         }
  225.                         if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
  226.                         {
  227.                                 add=0x00;
  228.                                 IapEraseSector(0);  //擦除扇区
  229.                                 IapProgramByte(0,0);//写入新的地址   
  230.                                 sendBuf[0]=0xaa;
  231.                                 sendBuf[1]=add;
  232.                                 sendBuf[2]=0x07;
  233.                                 sendBuf[3]=0x00;
  234.                                 sendBuf[4]=0xbb;
  235.                                 senduart2();
  236.                         }
  237.                         clear_receBuf();
  238.                 }
  239.         }
  240. }
  241. /*----------------------------
  242. Disable ISP/IAP/EEPROM function
  243. Make MCU in a safe state
  244. ----------------------------*/
  245. void IapIdle()
  246. {
  247.     IAP_CONTR = 0;                  //Close IAP function
  248.     IAP_CMD = 0;                    //Clear command to standby
  249.     IAP_TRIG = 0;                   //Clear trigger register
  250.     IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
  251.     IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
  252. }

  253. /*----------------------------
  254. Read one byte from ISP/IAP/EEPROM area
  255. Input: addr (ISP/IAP/EEPROM address)
  256. Output:Flash data
  257. ----------------------------*/
  258. BYTE IapReadByte(WORD addr)
  259. {
  260.     BYTE dat;                       //Data buffer

  261.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  262.     IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
  263.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  264.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  265.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  266.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  267.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  268.     dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
  269.     IapIdle();                      //Close ISP/IAP/EEPROM function

  270.     return dat;                     //Return Flash data
  271. }

  272. /*----------------------------
  273. Program one byte to ISP/IAP/EEPROM area
  274. Input: addr (ISP/IAP/EEPROM address)
  275.        dat (ISP/IAP/EEPROM data)
  276. Output:-
  277. ----------------------------*/
  278. void IapProgramByte(WORD addr, BYTE dat)
  279. {
  280.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  281.     IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
  282.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  283.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  284.     IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
  285.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  286.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  287.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  288.     IapIdle();
  289. }

  290. /*----------------------------
  291. Erase one sector area
  292. Input: addr (ISP/IAP/EEPROM address)
  293. Output:-
  294. ----------------------------*/
  295. void IapEraseSector(WORD addr)
  296. {
  297.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  298.     IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
  299.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  300.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  301.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  302.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  303.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  304.     IapIdle();
  305. }

复制代码
回复

使用道具 举报

地板
ID:989451 发表于 2021-12-10 00:55 | 只看该作者
wulin 发表于 2021-12-9 06:24
没有相关的函数可以调用,缺少EEPROM.c文件。给你补齐了。

好消息是没有报错,坏消息是XCOM仍然无法调试,delay 这块应该还有问题,还没改好;
再次感谢大佬
回复

使用道具 举报

5#
ID:213173 发表于 2021-12-10 07:22 | 只看该作者
lampman2017 发表于 2021-12-10 00:55
好消息是没有报错,坏消息是XCOM仍然无法调试,delay 这块应该还有问题,还没改好;
再次感谢大佬

不要试图一次调试全部功能都成功。先简化程序,基本功能调试成功再逐步完善。
  1. #include <reg51.h>
  2. #include <intrins.H>
  3. //#include <EEPROM.h>
  4. #define uchar unsigned char
  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;
  7. /*Declare SFR associated with the IAP */
  8. sfr AUXR   = 0x8E;
  9. sfr IAP_DATA    =   0xE2;           //Flash data register
  10. sfr IAP_ADDRH   =   0xE3;           //Flash address HIGH
  11. sfr IAP_ADDRL   =   0xE4;           //Flash address LOW
  12. sfr IAP_CMD     =   0xE5;           //Flash command register
  13. sfr IAP_TRIG    =   0xE6;           //Flash command trigger
  14. sfr IAP_CONTR   =   0xE7;           //Flash control register
  15. /*Define ISP/IAP/EEPROM command*/
  16. #define CMD_IDLE    0               //Stand-By
  17. #define CMD_READ    1               //Byte-Read
  18. #define CMD_PROGRAM 2               //Byte-Program
  19. #define CMD_ERASE   3               //Sector-Erase
  20. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz
  21. #define IAP_ADDRESS 0x0000
  22. /*
  23. sbit K1=P1^0;
  24. sbit K2=P1^1;
  25. sbit K3=P1^2;
  26. sbit K4=P1^3;
  27. sbit K5=P1^4;
  28. sbit K6=P1^5;
  29. sbit K7=P1^6;
  30. sbit K8=P1^7;

  31. uchar dat;
  32. uchar t,r,ii;
  33. uchar add;//掉电保持485地址
  34. uchar j=0;
  35. bit flag_zx=0;
  36. uchar sendBuf[10];
  37. uchar receBuf[10];
  38. bit busy;
  39. bit bz1=0;
  40. bit bz2=0;
  41. bit bz3=0;
  42. bit bz4=0;
  43. bit bz5=0;
  44. bit bz6=0;
  45. bit bz7=0;
  46. bit bz8=0;
  47. */
  48. void Delay(BYTE n);
  49. void IapIdle();
  50. BYTE IapReadByte(WORD addr);
  51. void IapProgramByte(WORD addr, BYTE dat);
  52. void IapEraseSector(WORD addr);

  53. /*********************************************
  54. 延时函数
  55. *********************************************/
  56. /*
  57. void delay(uchar t)
  58. {
  59.         uchar i,j;
  60.         for(i=0;i<t;i++)
  61.                 for(j=13;j>0;j--);
  62. }*/
  63. /*********************************************
  64. 串口初始化,波特率9600,方式1
  65. **********************************************/
  66. void Init_Com(void)                //9600bps@11.0592MHz
  67. {
  68.         PCON &= 0x7F;                //波特率不倍速
  69.         SCON = 0x50;                //8位数据,可变波特率
  70.         AUXR &= 0xBF;                //定时器时钟12T模式
  71.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  72.         TMOD &= 0x0F;                //设置定时器模式
  73.         TMOD |= 0x20;                //设置定时器模式
  74.         TL1 = 0xFD;                //设置定时初始值
  75.         TH1 = 0xFD;                //设置定时重载值
  76.         ET1 = 0;                //禁止定时器%d中断
  77.         TR1 = 1;                //定时器1开始计时
  78. //  ES=1;//查询方式不需开中断
  79. //  EA=1;
  80. }
  81. /***********发送函数***************************/
  82. /*
  83. void senduart2()
  84. {
  85.         //RS485_DIR=1;
  86.         SBUF=sendBuf[0];while(!TI);TI=0;
  87.         SBUF=sendBuf[1];while(!TI);TI=0;
  88.         SBUF=sendBuf[2];while(!TI);TI=0;
  89.         SBUF=sendBuf[3];while(!TI);TI=0;
  90.         SBUF=sendBuf[4];while(!TI);TI=0;
  91. }*/
  92. /******************清空发送缓冲区***************/
  93. /*
  94. void clear_receBuf()
  95. {
  96.         uchar i;
  97.         for(i=0;i<5;i++)
  98.         {
  99.                 receBuf[i]=0;
  100.         }
  101. }*/
  102. /************************************
  103. 主函数
  104. ************************************/
  105. void main()
  106. {
  107.         Init_Com();//串口初始化
  108. //        add=IapReadByte(0);//add=0x00;
  109.         P1=IapReadByte(0x00);
  110.         while(1)
  111.         {
  112.                 if(RI)                        //如果有接收
  113.                 {
  114.                         RI=0;                //接收标志清零
  115.                         P1=SBUF;        //获取接收寄存器数据
  116.                         SBUF=P1;        //数据返回上位机
  117.                         while(!TI);        //等待发送完成
  118.                         TI=0;                //发送标志位清0
  119.                         IapEraseSector(0x00);  //擦除扇区
  120.                         IapProgramByte(0x00,P1);//写入新数据
  121.                 }
  122. /*
  123.                 if(RI)//如果有接收
  124.                 {
  125.                         RI=0;//接收标志清零
  126.                         receBuf[r]=SBUF;//把接收的数据存到BUT数组中
  127.                         if(receBuf[0]==0xaa)//验证数据头,否则下次接收覆盖receBuf[0]
  128.                         {
  129.                                 r++;
  130.                                 if(r>=5)
  131.                                 {
  132.                                         r=0;
  133.                                         flag_zx=1;
  134.                                 }
  135.                         }
  136.                 }
  137.                 if(flag_zx==1)
  138.                 {
  139.                         flag_zx=0;
  140.        
  141.                         //  0        1       2        3       4                           
  142.                         //起始位   地址位  功能位   数据位  结束位
  143.                         if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add))//如果开始位和结束位,还有地址都正确,进行下一步判断
  144.                         {
  145.                                 if(receBuf[2]==0x01)  //修改板子地址
  146.                                 {
  147.                                         add=receBuf[3];
  148.                                         IapEraseSector(0);  //擦除扇区
  149.                                         IapProgramByte(0,add);//写入新的地址
  150.                                         sendBuf[0]=0xaa;
  151.                                         sendBuf[1]=add;
  152.                                         sendBuf[2]=0x00;
  153.                                         sendBuf[3]=add;
  154.                                         sendBuf[4]=0xbb;
  155.                                         senduart2();
  156.                                 }
  157.                                 else if(receBuf[2]==0x02)  //打开单路继电器
  158.                                 {
  159.                                         switch(receBuf[3])
  160.                                         {
  161.                                                 case 0x01: K1=0; break;
  162.                                                 case 0x02: K2=0; break;
  163.                                                 case 0x03: K3=0; break;
  164.                                                 case 0x04: K4=0; break;
  165.                                                 case 0x05: K5=0; break;
  166.                                                 case 0x06: K6=0; break;
  167.                                                 case 0x07: K7=0; break;
  168.                                                 case 0x08: K8=0; break;
  169.                                         }
  170.                                 }
  171.                                 else if(receBuf[2]==0x03)  //关闭单路继电器
  172.                                 {
  173.                                         switch(receBuf[3])
  174.                                         {
  175.                                                 case 0x01: K1=1; break;
  176.                                                 case 0x02: K2=1; break;
  177.                                                 case 0x03: K3=1; break;
  178.                                                 case 0x04: K4=1; break;
  179.                                                 case 0x05: K5=1; break;
  180.                                                 case 0x06: K6=1; break;
  181.                                                 case 0x07: K7=1; break;
  182.                                                 case 0x08: K8=1; break;
  183.                                         }                                 
  184.                                 }
  185.                                 else if(receBuf[2]==0x04)  //打开全部继电器
  186.                                 {
  187.                                         if(receBuf[3]==0xff)
  188.                                         {
  189.                                                 K1=0;
  190.                                                 K2=0;
  191.                                                 K3=0;
  192.                                                 K4=0;
  193.                                                 K5=0;
  194.                                                 K6=0;
  195.                                                 K7=0;
  196.                                                 K8=0;
  197.                                                 sendBuf[0]=0xaa;
  198.                                                 sendBuf[1]=add;
  199.                                                 sendBuf[2]=0xff;
  200.                                                 sendBuf[3]=0x00;
  201.                                                 sendBuf[4]=0xbb;
  202.                                                 senduart2();
  203.                                         }
  204.                                 }
  205.                                 else if(receBuf[2]==0x05)  //关闭全部继电器
  206.                                 {
  207.                                         if(receBuf[3]==0x00)
  208.                                         {
  209.                                                 K1=1;
  210.                                                 K2=1;
  211.                                                 K3=1;
  212.                                                 K4=1;
  213.                                                 K5=1;
  214.                                                 K6=1;
  215.                                                 K7=1;
  216.                                                 K8=1;
  217.                                                 sendBuf[0]=0xaa;
  218.                                                 sendBuf[1]=add;
  219.                                                 sendBuf[2]=0x07;
  220.                                                 sendBuf[3]=0x00;
  221.                                                 sendBuf[4]=0xbb;
  222.                                                 senduart2();
  223.                                         }                                 
  224.                                 }
  225.                                 else if(receBuf[2]==0x06)  //查询继电器
  226.                                 {
  227.                                         sendBuf[0]=0xaa;
  228.                                         sendBuf[1]=add;
  229.                                         sendBuf[2]=0x07;
  230.                                         sendBuf[3]=0xfe;
  231.                                         sendBuf[4]=0xbb;
  232.                                         switch(receBuf[3])
  233.                                         {
  234.                                                 case 0x01: if(K1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  235.                                                 case 0x02: if(K2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  236.                                                 case 0x03: if(K3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  237.                                                 case 0x04: if(K4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  238.                                                 case 0x05: if(K5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  239.                                                 case 0x06: if(K6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  240.                                                 case 0x07: if(K7==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  241.                                                 case 0x08: if(K8==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  242.                                                 default:break;
  243.                                         }
  244.                                         senduart2();
  245.                                 }                                          
  246.                         }
  247.                         if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
  248.                         {
  249.                                 add=0x00;
  250.                                 IapEraseSector(0);  //擦除扇区
  251.                                 IapProgramByte(0,0);//写入新的地址   
  252.                                 sendBuf[0]=0xaa;
  253.                                 sendBuf[1]=add;
  254.                                 sendBuf[2]=0x07;
  255.                                 sendBuf[3]=0x00;
  256.                                 sendBuf[4]=0xbb;
  257.                                 senduart2();
  258.                         }
  259.                         clear_receBuf();
  260.                 }*/
  261.         }
  262. }
  263. /*----------------------------
  264. Disable ISP/IAP/EEPROM function
  265. Make MCU in a safe state
  266. ----------------------------*/
  267. void IapIdle()
  268. {
  269.     IAP_CONTR = 0;                  //Close IAP function
  270.     IAP_CMD = 0;                    //Clear command to standby
  271.     IAP_TRIG = 0;                   //Clear trigger register
  272.     IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
  273.     IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
  274. }

  275. /*----------------------------
  276. Read one byte from ISP/IAP/EEPROM area
  277. Input: addr (ISP/IAP/EEPROM address)
  278. Output:Flash data
  279. ----------------------------*/
  280. BYTE IapReadByte(WORD addr)
  281. {
  282.     BYTE dat;                       //Data buffer

  283.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  284.     IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
  285.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  286.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  287.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  288.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  289.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  290.     dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
  291.     IapIdle();                      //Close ISP/IAP/EEPROM function

  292.     return dat;                     //Return Flash data
  293. }

  294. /*----------------------------
  295. Program one byte to ISP/IAP/EEPROM area
  296. Input: addr (ISP/IAP/EEPROM address)
  297.        dat (ISP/IAP/EEPROM data)
  298. Output:-
  299. ----------------------------*/
  300. void IapProgramByte(WORD addr, BYTE dat)
  301. {
  302.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  303.     IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
  304.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  305.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  306.     IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
  307.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  308.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  309.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  310.     IapIdle();
  311. }

  312. /*----------------------------
  313. Erase one sector area
  314. Input: addr (ISP/IAP/EEPROM address)
  315. Output:-
  316. ----------------------------*/
  317. void IapEraseSector(WORD addr)
  318. {
  319.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  320.     IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
  321.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  322.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  323.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  324.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  325.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  326.     IapIdle();
  327. }

复制代码
回复

使用道具 举报

6#
ID:839438 发表于 2021-12-10 15:32 | 只看该作者
楼主这是某一个宝买的?
回复

使用道具 举报

7#
ID:989451 发表于 2021-12-14 22:03 | 只看该作者
wulin 发表于 2021-12-10 07:22
不要试图一次调试全部功能都成功。先简化程序,基本功能调试成功再逐步完善。
  1. #include <reg51.h>
  2. #include <intrins.H>
  3. //#include <EEPROM.h>
  4. #define uchar unsigned char

  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;

  7. /*Declare SFR associated with the IAP */
  8. sfr AUXR   = 0x8E;
  9. sfr IAP_DATA    =   0xE2;           //Flash data register
  10. sfr IAP_ADDRH   =   0xE3;           //Flash address HIGH
  11. sfr IAP_ADDRL   =   0xE4;           //Flash address LOW
  12. sfr IAP_CMD     =   0xE5;           //Flash command register
  13. sfr IAP_TRIG    =   0xE6;           //Flash command trigger
  14. sfr IAP_CONTR   =   0xE7;           //Flash control register
  15. /*Define ISP/IAP/EEPROM command*/
  16. #define CMD_IDLE    0               //Stand-By
  17. #define CMD_READ    1               //Byte-Read
  18. #define CMD_PROGRAM 2               //Byte-Program
  19. #define CMD_ERASE   3               //Sector-Erase
  20. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz
  21. #define IAP_ADDRESS 0x0000

  22. sbit K1=P1^0;
  23. sbit K2=P1^1;
  24. sbit K3=P1^2;
  25. sbit K4=P1^3;
  26. sbit K5=P1^4;
  27. sbit K6=P1^5;
  28. sbit K7=P1^6;
  29. sbit K8=P1^7;

  30. uchar dat;
  31. uchar t,r,ii;
  32. uchar add;//掉电保持485地址
  33. uchar j=0;
  34. bit flag_zx=0;

  35. uchar sendBuf[10];
  36. uchar receBuf[10];
  37. bit busy;
  38. bit bz1=0;
  39. bit bz2=0;
  40. bit bz3=0;
  41. bit bz4=0;
  42. bit bz5=0;
  43. bit bz6=0;
  44. bit bz7=0;
  45. bit bz8=0;

  46. void Delay(BYTE n);
  47. void IapIdle();
  48. BYTE IapReadByte(WORD addr);
  49. void IapProgramByte(WORD addr, BYTE dat);
  50. void IapEraseSector(WORD addr);

  51. /*********************************************
  52. 延时函数
  53. *********************************************/

  54. void delay(uchar t)
  55. {
  56.         uchar i,j;
  57.         for(i=0;i<t;i++)
  58.                 for(j=13;j>0;j--);
  59. }
  60. /*********************************************
  61. 串口初始化,波特率9600,方式1
  62. **********************************************/
  63. void Init_Com(void)                //9600bps@11.0592MHz
  64. {
  65.         PCON &= 0x7F;                //波特率不倍速
  66.         SCON = 0x50;                //8位数据,可变波特率
  67.         AUXR &= 0xBF;                //定时器时钟12T模式
  68.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  69.         TMOD &= 0x0F;                //设置定时器模式
  70.         TMOD |= 0x20;                //设置定时器模式
  71.         TL1 = 0xFD;                //设置定时初始值
  72.         TH1 = 0xFD;                //设置定时重载值
  73.         ET1 = 0;                //禁止定时器%d中断
  74.         TR1 = 1;                //定时器1开始计时
  75. //  ES=1;//查询方式不需开中断
  76. //  EA=1;
  77. }
  78. /***********发送函数***************************/

  79. void senduart2()
  80. {
  81.         //RS485_DIR=1;
  82.         SBUF=sendBuf[0];while(!TI);TI=0;
  83.         SBUF=sendBuf[1];while(!TI);TI=0;
  84.         SBUF=sendBuf[2];while(!TI);TI=0;
  85.         SBUF=sendBuf[3];while(!TI);TI=0;
  86.         SBUF=sendBuf[4];while(!TI);TI=0;
  87. }
  88. /******************清空发送缓冲区***************/

  89. void clear_receBuf()
  90. {
  91.         uchar i;
  92.         for(i=0;i<5;i++)
  93.         {
  94.                 receBuf[i]=0;
  95.         }
  96. }
  97. /************************************
  98. 主函数
  99. ************************************/
  100. void main()
  101. {

  102. delay(10);
  103.      clear_receBuf();

  104.         Init_Com();//串口初始化
  105.    add=IapReadByte(0);//add=0x00;
  106.        //      P1=IapReadByte(0x00);
  107.         while(1)
  108.         {
  109.               if(RI)                        //如果有接收
  110.                 {
  111.                         RI=0;                //接收标志清零
  112.                         P1=SBUF;        //获取接收寄存器数据
  113.                         SBUF=P1;        //数据返回上位机
  114.                         while(!TI);        //等待发送完成
  115.                         TI=0;                //发送标志位清0
  116.                         IapEraseSector(0x00);  //擦除扇区
  117.                         IapProgramByte(0x00,P1);//写入新数据*/
  118.                

  119.                  /*          if(RI)//如果有接收
  120.                 {
  121.                         RI=0;//接收标志清零
  122.                         receBuf[r]=SBUF;//把接收的数据存到BUT数组中*/
  123.                         if(receBuf[0]==0xaa)//验证数据头,否则下次接收覆盖receBuf[0]
  124.                         {
  125.                                 r++;
  126.                                 if(r>=5)
  127.                                 {
  128.                                         r=0;
  129.                                         flag_zx=1;
  130.                                 }
  131.                         }
  132.                 }
  133.                 if(flag_zx==1)
  134.                 {
  135.                         flag_zx=0;
  136.       
  137.                         //  0        1       2        3       4                           
  138.                         //起始位   地址位  功能位   数据位  结束位
  139.                         if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add))//如果开始位和结束位,还有地址都正确,进行下一步判断
  140.                         {
  141.                                 if(receBuf[2]==0x01)  //修改板子地址
  142.                                 {
  143.                                         add=receBuf[3];
  144.                                         IapEraseSector(0);  //擦除扇区
  145.                                         IapProgramByte(0,add);//写入新的地址
  146.                                         sendBuf[0]=0xaa;
  147.                                         sendBuf[1]=add;
  148.                                         sendBuf[2]=0x00;
  149.                                         sendBuf[3]=add;
  150.                                         sendBuf[4]=0xbb;
  151.                                         senduart2();
  152.                                 }
  153.                                 else if(receBuf[2]==0x02)  //打开单路继电器
  154.                                 {
  155.                                         switch(receBuf[3])
  156.                                         {
  157.                                                 case 0x01: K1=0; break;
  158.                                                 case 0x02: K2=0; break;
  159.                                                 case 0x03: K3=0; break;
  160.                                                 case 0x04: K4=0; break;
  161.                                                 case 0x05: K5=0; break;
  162.                                                 case 0x06: K6=0; break;
  163.                                                 case 0x07: K7=0; break;
  164.                                                 case 0x08: K8=0; break;
  165.                                         }
  166.                                 }
  167.                                 else if(receBuf[2]==0x03)  //关闭单路继电器
  168.                                 {
  169.                                         switch(receBuf[3])
  170.                                         {
  171.                                                 case 0x01: K1=1; break;
  172.                                                 case 0x02: K2=1; break;
  173.                                                 case 0x03: K3=1; break;
  174.                                                 case 0x04: K4=1; break;
  175.                                                 case 0x05: K5=1; break;
  176.                                                 case 0x06: K6=1; break;
  177.                                                 case 0x07: K7=1; break;
  178.                                                 case 0x08: K8=1; break;
  179.                                         }                                 
  180.                                 }
  181.                                 else if(receBuf[2]==0x04)  //打开全部继电器
  182.                                 {
  183.                                         if(receBuf[3]==0xff)
  184.                                         {
  185.                                                 K1=0;
  186.                                                 K2=0;
  187.                                                 K3=0;
  188.                                                 K4=0;
  189.                                                 K5=0;
  190.                                                 K6=0;
  191.                                                 K7=0;
  192.                                                 K8=0;
  193.                                                 /*sendBuf[0]=0xaa;
  194.                                                 sendBuf[1]=add;
  195.                                                 sendBuf[2]=0xff;
  196.                                                 sendBuf[3]=0x00;
  197.                                                 sendBuf[4]=0xbb;
  198.                                                 senduart2();*/
  199.                                         }
  200.                                 }
  201.                                 else if(receBuf[2]==0x05)  //关闭全部继电器
  202.                                 {
  203.                                         if(receBuf[3]==0x00)
  204.                                         {
  205.                                                 K1=1;
  206.                                                 K2=1;
  207.                                                 K3=1;
  208.                                                 K4=1;
  209.                                                 K5=1;
  210.                                                 K6=1;
  211.                                                 K7=1;
  212.                                                 K8=1;
  213.                                                /* sendBuf[0]=0xaa;
  214.                                                 sendBuf[1]=add;
  215.                                                 sendBuf[2]=0x07;
  216.                                                 sendBuf[3]=0x00;
  217.                                                 sendBuf[4]=0xbb;
  218.                                                 senduart2();*/
  219.                                         }                                 
  220.                                 }
  221.                                 else if(receBuf[2]==0x06)  //查询继电器
  222.                                 {
  223.                                         sendBuf[0]=0xaa;
  224.                                         sendBuf[1]=add;
  225.                                         sendBuf[2]=0x07;
  226.                                         sendBuf[3]=0xfe;
  227.                                         sendBuf[4]=0xbb;
  228.                                         switch(receBuf[3])
  229.                                         {
  230.                                                 case 0x01: if(K1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  231.                                                 case 0x02: if(K2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  232.                                                 case 0x03: if(K3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  233.                                                 case 0x04: if(K4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  234.                                                 case 0x05: if(K5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  235.                                                 case 0x06: if(K6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  236.                                                 case 0x07: if(K7==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  237.                                                 case 0x08: if(K8==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  238.                                                 default:break;
  239.                                         }
  240.                                         senduart2();
  241.                                 }                                          
  242.                         }
  243.                         if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
  244.                         {
  245.                                 add=0x00;
  246.                                 IapEraseSector(0);  //擦除扇区
  247.                                 IapProgramByte(0,0);//写入新的地址   
  248.                                 sendBuf[0]=0xaa;
  249.                                 sendBuf[1]=add;
  250.                                 sendBuf[2]=0x07;
  251.                                 sendBuf[3]=0x00;
  252.                                 sendBuf[4]=0xbb;
  253.                                 senduart2();
  254.                         }
  255.                         clear_receBuf();
  256.                 }
  257.         }
  258. }
  259. /*----------------------------
  260. Disable ISP/IAP/EEPROM function
  261. Make MCU in a safe state
  262. ----------------------------*/
  263. void IapIdle()
  264. {
  265.     IAP_CONTR = 0;                  //Close IAP function
  266.     IAP_CMD = 0;                    //Clear command to standby
  267.     IAP_TRIG = 0;                   //Clear trigger register
  268.     IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
  269.     IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
  270. }

  271. /*----------------------------
  272. Read one byte from ISP/IAP/EEPROM area
  273. Input: addr (ISP/IAP/EEPROM address)
  274. Output:Flash data
  275. ----------------------------*/
  276. BYTE IapReadByte(WORD addr)
  277. {
  278.     BYTE dat;                       //Data buffer

  279.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  280.     IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
  281.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  282.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  283.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  284.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  285.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  286.     dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
  287.     IapIdle();                      //Close ISP/IAP/EEPROM function

  288.     return dat;                     //Return Flash data
  289. }

  290. /*----------------------------
  291. Program one byte to ISP/IAP/EEPROM area
  292. Input: addr (ISP/IAP/EEPROM address)
  293.        dat (ISP/IAP/EEPROM data)
  294. Output:-
  295. ----------------------------*/
  296. void IapProgramByte(WORD addr, BYTE dat)
  297. {
  298.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  299.     IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
  300.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  301.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  302.     IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
  303.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  304.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  305.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  306.     IapIdle();
  307. }

  308. /*----------------------------
  309. Erase one sector area
  310. Input: addr (ISP/IAP/EEPROM address)
  311. Output:-
  312. ----------------------------*/
  313. void IapEraseSector(WORD addr)
  314. {
  315.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  316.     IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
  317.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  318.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  319.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  320.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  321.     _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
  322.     IapIdle();
  323. }
复制代码

/****************适当的调整后,调试没有报错。 在Debug时,只在if(RI)和if(flag_zx==1)跳转;此外用STC-IAP烧录后出现控制紊乱,继电器灯一会亮一会不亮;反复修改再烧录,开发板闪一下后;STC-IAP显示正在检测单片机。。。再也连不上了*****/
回复

使用道具 举报

8#
ID:989451 发表于 2021-12-14 22:05 | 只看该作者
我会想你的 发表于 2021-12-10 15:32
楼主这是某一个宝买的?

买了一个触摸屏幕准备做开关,配套的一个继电器模块,我想改一下里面的反馈代码;
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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