#include     "reg52.h"
              #include     "intrins.h"
              #define      uchar    unsigned char
              #define      uint     unsigned int
              sfr          IAP_TPS=0xF5;
              sbit         KEY_0=P3^2;            //
              sbit         KEY_1=P3^3;            //
              sbit         KEY_2=P3^4;            //
              sbit         KEY_3=P3^5;            //
              uchar        kcounter,kstatus;     //按键计数标志 按键状态标志
/**************Delay*******************************/
              void     Delay_50ms(unsigned int Del_50ms)        //
              {
              unsigned int m;
              for(;Del_50ms>0;Del_50ms--)
              for(m=62450;m>0;m--);
              }
/***********************************/
              void IapIdle()
              {
              IAP_CONTR = 0;                              //关闭IAP功能
              IAP_CMD = 0;                                //清除命令寄存器
              IAP_TRIG = 0;                               //清除触发寄存器
              IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
              IAP_ADDRL = 0;
              }
/***********************************/
              char IapRead(int addr)
              {
              char dat;
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_TPS = 12;                               //设置等待参数12MHz
              IAP_CMD = 1;                                //设置IAP读命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();
              dat = IAP_DATA;                             //读IAP数据
              IapIdle();                                  //关闭IAP功能
              return dat;
              }
/***********************************/
              void IapProgram(int addr, char dat)
              {
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_TPS = 12;                               //设置等待参数12MHz
              IAP_CMD = 2;                                //设置IAP写命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_DATA = dat;                             //写IAP数据
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();
              IapIdle();                                  //关闭IAP功能
              }
/***********************************/
              void IapErase(int addr)
              {
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_TPS = 12;                               //设置等待参数12MHz
              IAP_CMD = 3;                                //设置IAP擦除命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();                                    //
              IapIdle();                                  //关闭IAP功能
              }
/****************按键计数器状态寄存器归零*************/
              void RstKey()
              {
              kcounter=0;                        //按键计数器归零
              kstatus=0;                         //状态寄存器归零
              }
/*****************按键低电平检测函数*****************/
              void   LowVoltKey(void)            //按键计数器状态标志加一
              {
              kcounter++;                       
              kstatus++;     
              }
/*****************按键高电平检测函数*****************/
              void    HighVoltKey(void)          //按键计数器加一 状态标志归零
              {
              kcounter++;                        //按键计数器加一
              kstatus=0;                         //按键状态标志归零
              }
/***********************************/
              void main()
              {
              P0M0 = 0x00;
              P0M1 = 0x00;
              P1M0 = 0x00;
              P1M1 = 0x00;
              P2M0 = 0x00;
              P2M1 = 0x00;
              P3M0 = 0x00;
              P3M1 = 0x00;
              P4M0 = 0x00;
              P4M1 = 0x00;
              P5M0 = 0x00;
              P5M1 = 0x00;
              Delay_50ms(20);
              P2 =0X00;
              Delay_50ms(20);
              P2 =0XFF;
              Delay_50ms(20);
              P2 =0X00;
                Delay_50ms(20);
              P2 =0XFF;
              Delay_50ms(20);
              P2 =0X00;
              Delay_50ms(20);
              P2 =0XFF;
              P2 = IapRead(0x0000);                      
              Delay_50ms(20);
              while (1)
              {
                  RstKey();
                for(;kcounter<10;)               //按键循环5次
                 {
                  if(!KEY_0)                    //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!KEY_0)              //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=8)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                  IapErase(0x0000);
                  IapProgram(0x0000, 0xEF);
                 }
//                 
                RstKey();
                for(;kcounter<10;)               //按键循环5次
                 {
                  if(!KEY_1)                    //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!KEY_1)              //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=8)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 IapErase(0x0000);
                 IapProgram(0x0000, 0x7F);
                 }
//                 
                RstKey();
                for(;kcounter<10;)               //按键循环5次
                 {
                  if(!KEY_2)                    //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!KEY_2)              //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=8)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 IapErase(0x0000);
                 IapProgram(0x0000, 0xFE);
                 }
//                                 
                RstKey();
                for(;kcounter<10;)               //按键循环5次
                 {
                  if(!KEY_3)                    //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!KEY_3)              //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=8)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 P2=IapRead(0x0000);            //P1=0x12
                 }
//                 
               }
              }

              #include "reg51.h"
              #include "intrins.h"
              #include "stdio.h"
/*************  本程序功能说明  **************

对STC内部自带的EEPROM(FLASH)进行读写测试。

对FLASH做扇区擦除、写入、读出的操作。

通过串口打印读取EEPROM结果。

注意:下载时,下载界面"硬件选项"中设置用户EEPROM大小,

并确保擦除、写入、读出的地址在EEPROM设置的大小范围之内。

下载时, 选择时钟 11.0592MHz (用户可自行修改频率)。

******************************************/
              #define     MAIN_Fosc       11059200L   //定义主时钟参数
              #define     BAUD            115200
              #define     TM              (65536 -(MAIN_Fosc/BAUD/4))
              typedef     unsigned char   u8;
              typedef     unsigned int    u16;
              typedef     unsigned long   u32;
              sfr     TH2     =   0xD6;
              sfr     TL2     =   0xD7;
              sfr     AUXR    =   0x8E;
              sfr     P_SW2   =   0xBA;
              sfr     P0M1    =   0x93;
              sfr     P0M0    =   0x94;
              sfr     P1M1    =   0x91;
              sfr     P1M0    =   0x92;
              sfr     P2M1    =   0x95;
              sfr     P2M0    =   0x96;
              sfr     P3M1    =   0xb1;
              sfr     P3M0    =   0xb2;
              sfr     P4M1    =   0xb3;
              sfr     P4M0    =   0xb4;
              sfr     P5M1    =   0xc9;
              sfr     P5M0    =   0xca;
              sfr     IAP_DATA    =   0xC2;
              sfr     IAP_ADDRH   =   0xC3;
              sfr     IAP_ADDRL   =   0xC4;
              sfr     IAP_CMD     =   0xC5;
              sfr     IAP_TRIG    =   0xC6;
              sfr     IAP_CONTR   =   0xC7;
              sfr     IAP_TPS     =   0xF5;
              #define P0PU     (*(unsigned char  volatile xdata *)  0xFE10)
              #define P1PU     (*(unsigned char  volatile xdata *)  0xFE11)
              #define P2PU     (*(unsigned char  volatile xdata *)  0xFE12)
              #define P3PU     (*(unsigned char  volatile xdata *)  0xFE13)
              #define OFFSET      0
              sbit    KEY1 = P3^2;
              u16     Key1_cnt;
              bit     Key1_Flag;
              bit     Key1_Function;
              void    KeyScan(void);
              void    delay_ms(u8 ms);

              void PrintfInit(void)
              {
              SCON = (SCON & 0x3f) | 0x40; 
              AUXR |= 0x40;        //定时器时钟1T模式
              AUXR &= 0xFE;        //串口1选择定时器1为波特率发生器
              TL1  = TM;
              TH1  = TM>>8;
              TR1 = 1;                //定时器1开始计时
//    SCON = (SCON & 0x3f) | 0x40; 
//    T2L  = TM;
//    T2H  = TM>>8;
//    AUXR |= 0x15;   //串口1选择定时器2为波特率发生器
              }
 
              void UartPutc(unsigned char dat)
              {
              SBUF = dat; 
              while(TI == 0); 
              TI = 0;
              }
 
              char putchar(char c)
              {
              UartPutc(c);
              return c;
              }

              void IapIdle()
              {
              IAP_CONTR = 0;                              //关闭IAP功能
              IAP_CMD = 0;                                //清除命令寄存器
              IAP_TRIG = 0;                               //清除触发寄存器
              IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
              IAP_ADDRL = 0;
              }

              unsigned char IapRead(int addr)
              {
              char dat;
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_CMD = 1;                                //设置IAP读命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();
              dat = IAP_DATA;                             //读IAP数据
              IapIdle();                                  //关闭IAP功能
              return dat;
              }

              void IapProgram(int addr, unsigned char dat)
              {
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_CMD = 2;                                //设置IAP写命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_DATA = dat;                             //写IAP数据
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();
              IapIdle();                                  //关闭IAP功能
              }

              void IapErase(int addr)
              {
              IAP_CONTR = 0x80;                           //使能IAP
              IAP_CMD = 3;                                //设置IAP擦除命令
              IAP_ADDRL = addr;                           //设置IAP低地址
              IAP_ADDRH = addr >> 8;                      //设置IAP高地址
              IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
              IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
              _nop_();                                    //
              IapIdle();                                  //关闭IAP功能
              }

              void main()
              {
              unsigned char i;
              unsigned char a[10];
              P_SW2 |= 0x80;        //使能XFR访问
              P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
              P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
              P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
               P3M1 = 0x0c;   P3M0 = 0x00;   //设置P3.2,P3.3为高阻输入
              P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
              P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
              P3PU = 0x0c;        //使能P3.2,P3.3口上拉
              IAP_TPS = 11;                   //设置EEPROM操作等待参数(11.0592MHz),初始化设置一次即可
              PrintfInit();
              while (1)
              {
               delay_ms(1);
               KeyScan();
               if(Key1_Function)
               {
                Key1_Function = 0;
                printf("Key1 pressed.\r\n");
                printf("Read1=");   //读取EEPROM原先的内容
                for(i=0;i<10;i++)
                 {
                 a[i] = IapRead(OFFSET+i);
                 printf("0x%02bx ",a[i]);
                 if(a[i] == 0xff) a[i] = i;  //如果内容为空,则写入初始化数据
                 else a[i]++;    //如果内容非空,在原先基础上加1
                 }
                 printf("\r\n");
                 IapErase(OFFSET);
                 printf("Read2=");   //擦除、重写后,读取EEPROM现在的内容
                 for(i=0;i<10;i++)
                 {
                 IapProgram(OFFSET+i, a[i]);
                 a[i] = IapRead(OFFSET+i);
                 printf("0x%02bx ",a[i]);
                 }
                 printf("\r\n");
                 }
                }
               }
//========================================================================
// 函数: void KeyScan(void)
// 描述: 按键扫描函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 
//========================================================================
              void KeyScan(void)
              {
               if(!KEY1)
               {
               if(!Key1_Flag)
                {
                   Key1_cnt++;
                if(Key1_cnt >= 50)      //50ms防抖
                 {
                 Key1_Flag = 1;      //设置按键状态,防止重复触发
                 Key1_Function = 1;
                 }
                }
               }
               else
               {
               Key1_cnt = 0;
               Key1_Flag = 0;
               }
              }
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 
//========================================================================
              void delay_ms(u8 ms)
              {
               u16 i;
                do
               {
                i = MAIN_Fosc / 10000;
                  while(--i);   //10T per loop
               }
               while(--ms);
              }

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐