找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC12C5A60S2单片机8路输入输出可编程晶体管控制通讯程序 带具体要求

[复制链接]
跳转到指定楼层
楼主
要求:
1. 8di 8do在上位机软件上面能够读取
2. 485通信
3. 第一路DO 软件上发送吸合指令,吸合XmsX为吸合时间可以在软件上设定),然后自动断开。
4. 第二路至第8DO 软件设定开就开,设定关就关。
5. 通信协议和其他仪器仪表相干扰。
6. 波特率 9600 8 n 1
7. 能设置二十个参数在板子的中间寄存器
8. 232通信
9. 通信样例:5a a5 13 82 00 00 0064*8
10. 其中 5A A5 是固定的后面参数由485参数设定
11. 第三位数值 13表示数据长度 表示13 后面有19字节16进制数字。如果设置位9则,发送指令为5a a5 09 82 00 00 0064*3 。(0064*3表示有30064,也就是十进制100)。此数值为多少,总字节长度+3为总发送数据。如为1316进制表示发送8个数值。为9表示发送3个数值。
12. 其中由第三位数值开始由上位机设定。
13. 可以设置的参数可以单独设定,也可以多个参数同时设定。
14. 建议第一个参数为设置单脉冲ms时间(单独设定)。后面可设置参数为数据长度,数值等(同时设定)。

电路原理图如下:

八路输入检测命令:
上位机发送:AA 01 00 BB     
AA 报头 01功能码,代表查询输入状态,00 无效,BB报尾
下位机返回:CC 01 00 DD
        CC 报头 01功能码,代表返回的是输入状态 ,00代表全开,11代表全关,DD报尾
八路输出检测命令:
上位机发送:AA 02 00 BB     
AA 报头 02功能码,代表查询输出状态,00 无效,BB报尾
下位机返回:CC 02 00 DD
        CC 报头 02功能码,代表返回的是输出状态 ,00代表全开,11代表全关,DD报尾
八路输出控制:
        上位机发送:AA 03 01 BB  01命令比较特殊,是吸合几秒钟自动断开,所以第一路没有关闭的指令,只有开的指令
AA 报头 03功能码,代表控制输出开,01代表第一路,02代表第二路,…… BB报尾
        下位机返回:CC 03 01 DD
        CC 报头 03功能码,代表控制的路数控制开成功,01代表第一路,02代表第二路,……DD报尾
上位机发送:AA 04 01 BB
AA 报头 04功能码,代表控制输出关,01代表第一路,02代表第二路,…… BB报尾
        下位机返回:CC 04 01 DD
        CC 报头 04功能码,代表控制的路数控制关成功,01代表第一路,02代表第二路,……DD报尾
设置第一路吸合的时间
        上位机发送:AA 05 01 00 00 00 09 BB
                AA 报头 05功能码,01代表设置第一路吸合的时间 00 00 00 09
代表一共9毫秒的,00 00 FF FF 代表510毫秒 FF FF FF FF 代表1020毫秒 BB报尾 时间四个十六进制输相加
下位机返回:CC 05 01 DD
        CC 报头 05功能码,代表设置时间成功,01代表第一路……DD报尾

单片机485输入232输出
        5a a5 13 82 00 00 00 64 00 64 00 64 00 64 00 64 00 64 00 64 00 64
        5a a5 为报头
        13为长度,十六进制的数值,转换过来是19,代表后面的长度为19个字节
        该命令通过485发送,发送之后232直接传出

00 00 00 09
代表1000毫秒 BB是报尾

单片机源程序如下:
  1. #include <STC12C5A60S2.H>
  2. #include <intrins.h>
  3. #define uchar unsigned char//宏定义无符号字符型
  4. #define uint unsigned int  //宏定义无符号整型
  5. unsigned char T0RH = 0;  //T0重载值的高字节
  6. unsigned char T0RL = 0;  //T0重载值的低字节
  7. bit flagFrame = 0;  //帧接收完成标志,即接收到一帧新数据
  8. bit flagTxd = 0;    //单字节发送完成标志,用来替代TXD中断标志位
  9. unsigned char cntRxd = 0;   //接收字节计数器
  10. unsigned char pdata bufRxd[100];  //接收字节缓冲区
  11. bit flagFrame2 = 0;  //帧接收完成标志,即接收到一帧新数据
  12. bit flagTxd2 = 0;    //单字节发送完成标志,用来替代TXD中断标志位
  13. unsigned char cntRxd2 = 0;   //接收字节计数器
  14. unsigned char pdata bufRxd2[100];  //接收字节缓冲区
  15. void UartDriver();//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用
  16. void UartAction(unsigned char *buf, unsigned char len);//在接收到的数据帧后添加换车换行符后发回
  17. void UartWrite(unsigned char *buf, unsigned char len);//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  18. unsigned char UartRead(unsigned char *buf, unsigned char len);//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度
  19. void UartDriver2();//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用
  20. void UartAction2(unsigned char *buf2, unsigned char len2);//在接收到的数据帧后添加换车换行符后发回
  21. void UartWrite2(unsigned char *buf2, unsigned char len2);//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  22. unsigned char UartRead2(unsigned char *buf2, unsigned char len2);//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度
  23. void UartRxMonitor(unsigned char ms);//串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔
  24. void ConfigUART(unsigned int baud);//串口配置函数,baud-通信波特率
  25. void ConfigTimer0(unsigned int ms);//配置并启动T0,ms-T0定时时间
  26. uchar Byte_Read(uint add);              //读一字节,调用前需打开IAP 功能
  27. void Byte_Program(uint add, uint ch);  //字节编程,调用前需打开IAP 功能
  28. void Sector_Erase(uint add);            //擦除扇区
  29. void IAP_Disable();                       //关闭IAP 功能
  30. void Delay();
  31. #define ENABLE_ISP 0x81 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
  32. unsigned char paths;
  33. char buf0add7;

  34. sbit ins01=P0^0;
  35. sbit ins02=P0^1;
  36. sbit ins03=P0^2;
  37. sbit ins04=P0^3;
  38. sbit ins05=P0^4;
  39. sbit ins06=P0^5;
  40. sbit ins07=P0^6;
  41. sbit ins08=P0^7;

  42. /*定义八位输出为单片机P2口*/
  43. sbit out01=P2^6;
  44. sbit out02=P2^7;
  45. sbit out03=P5^1;
  46. sbit out04=P5^0;
  47. sbit out05=P4^6;
  48. sbit out06=P4^1;
  49. sbit out07=P4^5;
  50. sbit out08=P4^4;
  51. sbit b485Send=P2^4;        //485接口发送接收控制
  52. unsigned char ck1=0x00;
  53. uint time1=0,time2=0;
  54. bit timef1=0;
  55. uchar num11=0,num12=0,num1=0;
  56. uchar num21=0,num22=0,num2=0;
  57. uchar num31=0,num32=0,num3=0;
  58. uchar num41=0,num42=0,num4=0;
  59. uchar time21=0,time22=0;
  60. uchar ls=0,ls1=0,ls2=0;
  61. void UartAction(unsigned char *buf, unsigned char len){//在接收到的数据帧后添加换车换行符后发回
  62.                 UartWrite(buf, len);
  63. }
  64. void UartAction2(unsigned char *buf2, unsigned char len2){//在接收到的数据帧后添加换车换行符后发回
  65.         if((buf2[0]==0x5A)&&(buf2[1]==0xA5)){
  66.                         ls1=buf2[2]/10;
  67.                         ls2=buf2[2]%10;
  68.                         ls=ls1*10+ls2+3;
  69.                         if(len2==ls){               
  70.                                 UartWrite(buf2, len2);
  71.                         }
  72.         }
  73.         if((buf2[0]==0xAA)&&(buf2[1]==0x05)&&(buf2[7]==0xBB)&&(len2==8)){
  74.                 if(buf2[2]==0x01){
  75.                         num11=buf2[3]/10;
  76.                         num12=buf2[3]%10;
  77.                         num1=num11*10+num12;
  78.                         num21=buf2[4]/10;
  79.                         num22=buf2[4]%10;
  80.                         num2=num21*10+num22;
  81.                         num31=buf2[5]/10;
  82.                         num32=buf2[5]%10;
  83.                         num3=num31*10+num32;
  84.                         num41=buf2[6]/10;
  85.                         num42=buf2[6]%10;
  86.                         num4=num41*10+num42;               
  87.                         time2=num1+num2+num3+num4;
  88.                         time21=time2/100;//把int型的值拆分到char型
  89.                         time22=time2%100;
  90.                                 Sector_Erase(0);              
  91.                                 Byte_Program(0x01,time21);
  92.                                 Byte_Program(0x02,time22);
  93.                                 buf2[0]=0xCC;
  94.                                 buf2[1]=0x05;
  95.                                 buf2[2]=buf2[2];
  96.                                 buf2[3]=0xDD;
  97.                                 len2=4;
  98.                                 UartWrite2(buf2, len2);
  99.                 }
  100.         }
  101.         if((buf2[0]==0xAA)&&(buf2[3]==0xBB)&&(len2==4)){
  102.                 switch (buf2[1]){//按指令位执行操作
  103.                         case 0x01://查询输入状态命令
  104.                         ck1=0xFF;
  105.                                 if(ins01){ck1|=0x80;}else{ck1&=0x7f;}
  106.                                 if(ins02){ck1|=0x40;}else{ck1&=0xbf;}
  107.                                 if(ins03){ck1|=0x20;}else{ck1&=0xdf;}
  108.                                 if(ins04){ck1|=0x10;}else{ck1&=0xef;}
  109.                         if(ins05){ck1|=0x08;}else{ck1&=0xf7;}
  110.                                 if(ins06){ck1|=0x04;}else{ck1&=0xfb;}
  111.                         if(ins07){ck1|=0x02;}else{ck1&=0xfd;}
  112.                                 if(ins08){ck1|=0x01;}else{ck1&=0xfe;}
  113.                                 buf2[0]=0xCC;
  114.                                 buf2[1]=0x01;
  115.                                 buf2[2]=ck1;
  116.                                 buf2[3]=0xDD;
  117.                                 len2=4;
  118.                                 UartWrite2(buf2, len2);
  119.                                 break;
  120.                         case 0x02://查询输出状态命令
  121.                         ck1=0xFF;
  122.                                 if(out01){ck1|=0x80;}else{ck1&=0x7f;}
  123.                                 if(out02){ck1|=0x40;}else{ck1&=0xbf;}
  124.                                 if(out03){ck1|=0x20;}else{ck1&=0xdf;}
  125.                                 if(out04){ck1|=0x10;}else{ck1&=0xef;}
  126.                         if(out05){ck1|=0x08;}else{ck1&=0xf7;}
  127.                                 if(out06){ck1|=0x04;}else{ck1&=0xfb;}
  128.                         if(out07){ck1|=0x02;}else{ck1&=0xfd;}
  129.                                 if(out08){ck1|=0x01;}else{ck1&=0xfe;}
  130.                                 buf2[0]=0xCC;
  131.                                 buf2[1]=0x02;
  132.                                 buf2[2]=ck1;
  133.                                 buf2[3]=0xDD;
  134.                                 len2=4;
  135.                                 UartWrite2(buf2, len2);
  136.                                 break;
  137.                         case 0x03://输出开控制
  138.                         if(buf2[2]==0x01){timef1=1;out01=0;}
  139.                         if(buf2[2]==0x02){out02=0;}
  140.                         if(buf2[2]==0x03){out03=0;}
  141.                         if(buf2[2]==0x04){out04=0;}
  142.                         if(buf2[2]==0x05){out05=0;}
  143.                         if(buf2[2]==0x06){out06=0;}
  144.                         if(buf2[2]==0x07){out07=0;}
  145.                         if(buf2[2]==0x08){out08=0;}
  146.                                 buf2[0]=0xCC;
  147.                                 buf2[1]=0x03;
  148.                                 buf2[2]=buf2[2];
  149.                                 buf2[3]=0xDD;
  150.                                 len2=4;
  151.                                 UartWrite2(buf2, len2);
  152.                                 break;
  153.                         case 0x04://输出关控制
  154.                         if(buf2[2]==0x02){out02=1;}
  155.                         if(buf2[2]==0x03){out03=1;}
  156.                         if(buf2[2]==0x04){out04=1;}
  157.                         if(buf2[2]==0x05){out05=1;}
  158.                         if(buf2[2]==0x06){out06=1;}
  159.                         if(buf2[2]==0x07){out07=1;}
  160.                         if(buf2[2]==0x08){out08=1;}
  161.                                 buf2[0]=0xCC;
  162.                                 buf2[1]=0x04;
  163.                                 buf2[2]=buf2[2];
  164.                                 buf2[3]=0xDD;
  165.                                 len2=4;
  166.                                 UartWrite2(buf2, len2);
  167.                                 break;
  168.                 }               
  169.         }
  170. }
  171. void main(){
  172.         P4SW|=0x70;
  173.     b485Send=0; //接收模式
  174.         EA = 1;            //开总中断
  175.     ConfigTimer0(1);   //配置T0定时1ms
  176.     ConfigUART(9600);  //配置波特率为9600
  177.         time21=Byte_Read(0x01);//掉电存储用到
  178.         time22=Byte_Read(0x02);//掉电存储用到
  179.         time2=time21*100+time22;
  180.         while(1){
  181.                 UartDriver();  //调用串口驱动
  182.                 UartDriver2();  //调用串口驱动
  183.         }
  184. }
  185. void InterruptTimer0() interrupt 1{//T0中断服务函数,执行串口接收监控
  186.     TH0 = T0RH;  //重新加载重载值
  187.     TL0 = T0RL;
  188.     UartRxMonitor(1);  //串口接收监控
  189.         if(timef1){
  190.                 out01=0;
  191.                 time1++;
  192.                 if(time1>time2){
  193.                         time1=0;
  194.                         timef1=0;
  195.                         out01=1;
  196.                 }
  197.         }
  198. }
  199. void InterruptUART() interrupt 4{//串口中断服务函数
  200.     if (RI) { //接收到新字节
  201.         RI = 0;  //清零接收中断标志位
  202.         if (cntRxd < sizeof(bufRxd)) {//接收缓冲区尚未用完时,保存接收字节,并递增计数器
  203.             bufRxd[cntRxd++] = SBUF;        // cntRxd++这个很重要,一开始 cntRxd < sizeof(bufRxd)当进入函数的次数增加,cntRxd慢慢变大,当传入的数据不满的时候就        用时间检测,判断是否是传输完成
  204.         }
  205.     }
  206.     if (TI) { //字节发送完毕
  207.         TI = 0;   //清零发送中断标志位
  208.         flagTxd = 1;  //设置字节发送完成标志
  209.     }
  210. }
  211. void uart2_isr()  interrupt 8{//发送接收中断函数
  212.         if( S2CON & 0x01 ){
  213.                 S2CON &= ~0x01;
  214.                 if (cntRxd2 < sizeof(bufRxd2)){ //接收缓冲区尚未用完时,保存接收字节,并递增计数器
  215.             bufRxd2[cntRxd2++] = S2BUF;        // cntRxd++这个很重要,一开始 cntRxd < sizeof(bufRxd)当进入函数的次数增加,cntRxd慢慢变大,当传入的数据不满的时候就        用时间检测,判断是否是传输完成
  216.         }
  217.          }
  218.         if( S2CON & 0x02 ){
  219.                 S2CON &= ~0x02;
  220.                 flagTxd2 = 1;  //设置字节发送完成标志
  221.         b485Send=0;//发送完毕设置为接收
  222.     }
  223. }

  224. void ConfigTimer0(unsigned int ms){//配置并启动T0,ms-T0定时时间
  225.     unsigned long tmp;  //临时变量   
  226.     tmp = 11059200 / 12;      //定时器计数频率
  227.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  228.     tmp = 65536 - tmp;        //计算定时器重载值
  229.     tmp = tmp + 33;           //补偿中断响应延时造成的误差
  230.     T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
  231.     T0RL = (unsigned char)tmp;
  232.     TMOD &= 0xF0;   //清零T0的控制位
  233.     TMOD |= 0x01;   //配置T0为模式1
  234.     TH0 = T0RH;     //加载T0重载值
  235.     TL0 = T0RL;
  236.     ET0 = 1;        //使能T0中断
  237.     TR0 = 1;        //启动T0
  238. }
  239. void ConfigUART(unsigned int baud){//串口配置函数,baud-通信波特率
  240.     SCON  = 0x50;  //配置串口为模式1
  241.     TMOD &= 0x0F;  //清零T1的控制位
  242.     TMOD |= 0x20;  //配置T1为模式2
  243.     TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
  244.     TL1 = TH1;     //初值等于重载值
  245.     ET1 = 0;       //禁止T1中断
  246.     ES  = 1;       //使能串口中断
  247.     TR1 = 1;       //启动T1
  248.         S2CON = 0x50;  //方式1,八位数据,可变波特率
  249.         AUXR1 = 0x00;  //1T工作方式
  250.          PCON  = 0x00;  //不倍增波特率
  251.          IP2   = 0x00;  //优先级默认
  252.          BRT   = 0XFD;  //设置波特率9600
  253.          AUXR  = 0x10;  //启动波特率发生器
  254.         IE2   = 0x01;  //开串口2中断        
  255. }
  256. void UartWrite(unsigned char *buf, unsigned char len){//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  257.     while (len--){   //循环发送所有字节
  258.         flagTxd = 0;      //清零发送标志
  259.         SBUF = *buf++;    //发送一个字节数据
  260.         while (!flagTxd); //等待该字节发送完成
  261.     }
  262. }
  263. void UartWrite2(unsigned char *buf2, unsigned char len2){//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  264.     while (len2--){   //循环发送所有字节
  265.         flagTxd2 = 0;      //清零发送标志
  266.                 b485Send=1;
  267.         S2BUF = *buf2++;    //发送一个字节数据
  268.         while (!flagTxd2); //等待该字节发送完成
  269.     }
  270. }
  271. unsigned char UartRead(unsigned char *buf, unsigned char len){//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度
  272.     unsigned char i;
  273.     if (len > cntRxd){  //指定读取长度大于实际接收到的数据长度时,读取长度设置为实际接收到的数据长度
  274.         len = cntRxd;
  275.     }
  276.     for (i=0; i<len; i++){  //拷贝接收到的数据到接收指针上
  277.         *buf++ = bufRxd[i];
  278.     }
  279.     cntRxd = 0;  //接收计数器清零
  280.     return len;  //返回实际读取长度
  281. }
  282. void UartDriver(){//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用
  283.     unsigned char len;
  284.     unsigned char pdata buf[40];
  285.     if (flagFrame){ //有命令到达时,读取处理该命令
  286.         flagFrame = 0;
  287.         len = UartRead(buf, sizeof(buf)-2); //将接收到的命令读取到缓冲区中
  288.         UartAction(buf, len);  //传递数据帧,调用动作执行函数
  289.     }
  290. }
  291. unsigned char UartRead2(unsigned char *buf2, unsigned char len2){//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度
  292.     unsigned char i;
  293.     if (len2 > cntRxd2){  //指定读取长度大于实际接收到的数据长度时,读取长度设置为实际接收到的数据长度
  294.         len2 = cntRxd2;
  295.     }
  296.     for (i=0; i<len2; i++){  //拷贝接收到的数据到接收指针上
  297.         *buf2++ = bufRxd2[i];
  298.     }
  299.     cntRxd2 = 0;  //接收计数器清零
  300.     return len2;  //返回实际读取长度
  301. }
  302. void UartDriver2(){//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用
  303.     unsigned char len2;
  304.     unsigned char pdata buf2[40];
  305.     if (flagFrame2){ //有命令到达时,读取处理该命令
  306.         flagFrame2 = 0;
  307.         len2 = UartRead2(buf2, sizeof(buf2)-2); //将接收到的命令读取到缓冲区中
  308.         UartAction2(buf2, len2);  //传递数据帧,调用动作执行函数
  309.     }
  310. }
  311. void UartRxMonitor(unsigned char ms){//串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔
  312.     static unsigned char cntbkp = 0;
  313.     static unsigned char idletmr = 0;
  314.     if (cntRxd > 0){  //接收计数器大于零时,监控总线空闲时间
  315.         if (cntbkp != cntRxd){  //接收计数器改变,即刚接收到数据时,清零空闲计时
  316.             cntbkp = cntRxd;
  317.             idletmr = 0;
  318.         }else{                   //接收计数器未改变,即总线空闲时,累积空闲时间
  319.             if (idletmr < 30){  //空闲计时小于30ms时,持续累加
  320.                 idletmr += ms;
  321.                 if (idletmr >= 30){  //空闲时间达到30ms时,即判定为一帧接收完毕
  322.                     flagFrame = 1;  //设置帧接收完成标志
  323.                 }
  324.             }
  325.         }
  326.     }else if(cntRxd2 > 0){
  327.         if (cntbkp != cntRxd2){
  328.             cntbkp = cntRxd2;
  329.             idletmr = 0;
  330.         }else{
  331.             if (idletmr < 30){
  332.                 idletmr += ms;
  333.                 if (idletmr >= 30){  
  334.                     flagFrame2 = 1; }}
  335.         }               
  336.         }else{
  337.         cntbkp = 0;
  338.     }
  339. }
  340. union union_temp16{
  341.     uint un_temp16;
  342.     uchar  un_temp8[2];
  343. }my_unTemp16;
  344. //读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
  345. uchar Byte_Read(uint add){
  346.     IAP_DATA = 0x00;
  347.     IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
  348.     IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字节读命令

  349.     my_unTemp16.un_temp16 = add;
  350.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  351.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

  352.     //EA = 0;
  353.     IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
  354.     IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
  355.     _nop_();
  356.     //EA = 1;
  357.     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  358.                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  359.     return (IAP_DATA);
  360. }

  361. //字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
  362. void Byte_Program(uint add, uint ch){
  363.     IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
  364.     IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令

  365.     my_unTemp16.un_temp16 = add;
  366.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  367.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

  368.     IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
  369.     //EA = 0;
  370.     IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
  371.     IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
  372.     _nop_();
  373.     //EA = 1;
  374.     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  375.                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  376. }

  377. //擦除扇区, 入口:DPTR = 扇区地址
  378. void Sector_Erase(uint add){
  379.     IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
  380.     IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令

  381.     my_unTemp16.un_temp16 = add;
  382.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  383.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

  384.     //EA = 0;
  385.     IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
  386.     IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
  387.     _nop_();
  388.     //EA = 1;
  389.     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  390.                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  391. }

  392. void IAP_Disable(){
  393.     //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  394.     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  395.     IAP_CONTR = 0;      //关闭IAP 功能
  396.     IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
  397.     IAP_TRIG  = 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
  398.     IAP_ADDRH = 0;
  399.     IAP_ADDRL = 0;
  400. }
复制代码
全部资料51hei下载地址:
Desktop.rar (85.38 KB, 下载次数: 33)
8入8出可编程场效应管PNP款原理图及PCB图.rar (420.52 KB, 下载次数: 36)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:105206 发表于 2020-4-16 23:16 | 只看该作者
谢谢分享,学习了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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