51单片机入门经验分享5-STC15W1K16PWM内部EEPROM的使用

发布者:PositiveVibes最新更新时间:2020-07-12 来源: 51hei关键字:51单片机  STC15W1K16PWM  内部EEPROM 手机看文章 扫描二维码
随时随地手机看文章

在实际开发中,经常会遇到某些需要断电需要再次上电记忆的场合,这就需要掉电存储芯片了,最常用的EEPROM芯片就是AT24C02了,几乎成了每一块开发板的标配,但是有些时候,在一些低成本的场合,需要用类EEPROM或者flash来模拟EEPROM进行存储,AT24C02是可以进行字节擦写的,STC内部的EEPROM是不可以字节擦写的,他是按照512byte一个扇区来组织的,如下图所示,我们开发板选择的这块芯片分为了22个扇区。如果你要擦除数据,那么必须要一次性的擦除512字节才可以,这么难用,难用总比没有强吧,在好多产品上,我都见到过,好多掉电了上电依然保持的参数,有没有外置EEPROM芯片,只能用内部的或者来模拟了,我们来写一个程序,程序的结果是记忆上电次数,每上电一次,就累加一次,显示在数码管上面,OK,写好的代码如下所示:

  1. /*******************************************************************************

  2. * 文件名: 数码管显示上电计数值

  3. * 描  述: 上电计数

  4. * 功  能:数码管的使用

  5. * 作  者:大核桃 597627977

  6. * 版本号:1.0.1(2018.09.21)

  7. *******************************************************************************/

  8. #include "stc15w.h"//头文件

  9. #include "intrins.h"


  10. /*******************************************************************************

  11. * 文件名: 重定义

  12. * 描  述:   

  13. * 功  能:

  14. * 作  者:大核桃

  15. * 版本号:1.0.1(2018.09.21)

  16. *******************************************************************************/

  17. typedef unsigned char uint8;

  18. typedef unsigned int  uint16;

  19. typedef unsigned long uint32;


  20. /*******************************************************************************

  21. * 文件名:共阳数码管真值表

  22. * 描  述:

  23. * 功  能:

  24. * 作  者:大核桃

  25. * 版本号:1.0.1(2018.09.21)

  26. *******************************************************************************/

  27. code uint8 LedChar[] = {

  28.         0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

  29.         0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e

  30. };


  31. uint16 counter;        //记忆上电次数,最大65535


  32. /*******************************************************************************

  33. * 文件名:单独位定义

  34. * 描  述:   

  35. * 功  能:

  36. * 作  者:大核桃

  37. * 版本号:1.0.1(2018.09.21)

  38. *******************************************************************************/

  39. sbit LED0 = P1^0;//第1组LED

  40. sbit LED1 = P1^1;//第2组LED

  41. sbit LED2 = P1^2;//第3组LED                                 

  42. sbit LED3 = P1^3;//第4组LED

  43. sbit LED4 = P1^4;//第5组LED

  44. sbit LED5 = P3^2;//第6组LED

  45. sbit LED6 = P0^0;//第7组LED

  46. sbit LED7 = P0^1;//第8组LED


  47. sbit LEDS1 = P3^3;//数码管1

  48. sbit LEDS2 = P3^4;//数码管2

  49. sbit LEDS3 = P3^6;//数码管3

  50. sbit LEDS4 = P3^7;//数码管4


  51. /*******************************************************************************

  52. * 文件名:全局变量定义区域

  53. * 描  述:

  54. * 功  能:

  55. * 作  者:大核桃

  56. * 版本号:1.0.1(2017.05.23)

  57. *******************************************************************************/

  58. #define CMD_IDLE    0               //空闲模式

  59. #define CMD_READ    1               //IAP字节读命令

  60. #define CMD_PROGRAM 2               //IAP字节编程命令

  61. #define CMD_ERASE   3               //IAP扇区擦除命令


  62. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz

  63. /*******************************************************************************

  64. * 文件名:函数前置声明

  65. * 描  述:   

  66. * 功  能:

  67. * 作  者:大核桃

  68. * 版本号:1.0.1(2017.05.23)

  69. *******************************************************************************/

  70. void Mcu_Port_Init();

  71. void LedScan();

  72. void Delay500ms(); //24MHZ

  73. void Time0_Init();//定时器0

  74. void IapIdle();

  75. uint8 IapReadByte(uint16 addr);

  76. void IapProgramByte(uint16 addr, uint8 dat);

  77. void IapEraseSector(uint16 addr);

  78. #define Delay()                {_nop_();_nop_();_nop_();_nop_();}


  79. /*******************************************************************************

  80. * 文件名

  81. * 描  述: 主函数  

  82. * 功  能:入口

  83. * 作  者:大核桃

  84. * 版本号:1.0.1(2017.05.23)

  85. *******************************************************************************/

  86. void main(void)

  87. {                                       

  88.         counter = IapReadByte(0x0000);//读取数据

  89.         counter++;//写


  90.         Mcu_Port_Init();//IO上电初始化

  91.         Time0_Init();


  92.         IapEraseSector(0x0000);//擦除数据

  93.         IapProgramByte(0x0000, counter);//写入数据



  94.         while(1);

  95. }


  96. /*******************************************************************************

  97. * 文件名:void LedScan()

  98. * 描  述: LED刷新

  99. * 功  能:

  100. * 作  者:大核桃

  101. * 版本号:1.0.1(2017.05.23)

  102. *******************************************************************************/

  103. void LedScan()

  104. {

  105.         static uint8 i = 0;


  106.         P2 = 0Xff;

  107.         switch(i)

  108.         {

  109.                 case 0: LEDS4 = 0;LEDS1 = 1;P2 = LedChar[counter / 1000 % 10];i++;break;

  110.                 case 1: LEDS1 = 0;LEDS2 = 1;P2 = LedChar[counter / 100 % 10];i++;break;

  111.                 case 2: LEDS2 = 0;LEDS3 = 1;P2 = LedChar[counter / 10 % 10];i++;break;

  112.                 case 3: LEDS3 = 0;LEDS4 = 1;P2 = LedChar[counter % 10];i = 0;break;


  113.                 default:break;

  114.         }

  115. }

  116. /*******************************************************************************

  117. * 文件名:void Time0_Init()

  118. * 描  述: 定时器0初始化

  119. * 功  能:10毫秒@11.0592MHz

  120. * 作  者:大核桃

  121. * 版本号:1.0.1(2017.05.23)

  122. *******************************************************************************/

  123. void Time0_Init(void)

  124. {

  125.         AUXR &= 0x7F;                //定时器时钟12T模式

  126.         TMOD &= 0xF0;                //设置定时器模式

  127.         TMOD |= 0X01;      //确保不干扰其他配置

  128.         TH0 = 0xDC;                //设置定时初值

  129.         TL0 = 0x00;                //设置定时初值

  130.         ET0 = 1;

  131.         TR0 = 1;                //定时器0开始计时

  132.         EA = 1;               

  133. }

  134. /*******************************************************************************

  135. * 文件名:

  136. * 描  述: 中断函数

  137. * 功  能:10毫秒@11.0592MHz

  138. * 作  者:大核桃

  139. * 版本号:1.0.1(2017.05.23)

  140. *******************************************************************************/

  141. void ET0_IRQHandler() interrupt 1

  142. {

  143.         TH0 = 0xDC;                //设置定时初值

  144.         TL0 = 0x00;                //设置定时初值

  145.         LedScan();               

  146. }

  147. /*******************************************************************************

  148. * 文件名:void Mcu_Port_Init()

  149. * 描  述: io初始化

  150. * 功  能:

  151. * 作  者:大核桃

  152. * 版本号:1.0.1(2017.05.23)

  153. *******************************************************************************/

  154. void Mcu_Port_Init()

  155. {

  156.         //将P0口低二位配置为推挽输出

  157.         //234567位配置位高阻输入

  158.         P0M1 = 0xFC;//1111 1100

  159.         P0M0 = 0X03;//0000 0011

  160.         //P0 = 0X01;//第6个

  161.         //P0 = 0X02;//第7个

  162.         //高3位配置高阻输入,用作模拟口

  163.         //其他配置推挽输出,驱动LED

  164.         P1M1 = 0xE0;//1110 0000

  165.         P1M0 = 0X1F;//0001 1111

  166.         //P2口配置准双向口

  167.         P2M1 = 0X00;

  168.         P2M0 = 0X00;

  169.         P2 = 0Xff; //上电为1111 1111


  170. //        //P54,P55口为推挽输出

  171.         P5M1 = 0X00;

  172.         P5M0 = 0X00;

  173.         P5 = 0xFF;


  174.         //P37,P36,3.2,P3.3 P3.4口为推挽输出

  175.         P3M1 = 0X00;

  176.         P3M0 = 0XFC;

  177.         P3 = 0X23; //0010 0111//第5个LED端口

  178.         

  179.         LED0 = 0;//第1组LED,如果使能请置为1

  180.         LED1 = 0;

  181.         LED2 = 0;

  182.         LED3 = 0;

  183.         LED4 = 0;

  184.         LED5 = 0;

  185.         LED6 = 0;

  186.         LED7 = 0;        

  187. }


  188. /*******************************************************************************

  189. * 文件名:void Delay500ms()                //@24.000MHz

  190. * 描  述:Y5内核延时

  191. * 功  能:

  192. * 作  者:大核桃

  193. * 版本号:1.0.1(2017.05.23)

  194. *******************************************************************************/

  195. void Delay500ms()                //@24.000MHz

  196. {

  197.         unsigned char i, j, k;


  198.         _nop_();

  199.         _nop_();

[1] [2]
关键字:51单片机  STC15W1K16PWM  内部EEPROM 引用地址:51单片机入门经验分享5-STC15W1K16PWM内部EEPROM的使用

上一篇:51单片机入门经验分享6-利用STC单片机的ADC采集电压
下一篇:51单片机入门经验分享3-通过流水灯讲解for循环语句

推荐阅读最新更新时间:2024-11-11 01:18

单片机的动手实践篇--51单片机玩转12864
12864液晶的驱动和1602的类似,只不过是多了几个扩展的功能,不如画图功能: 这里讲一下:不要简单的认为12864是y轴64,x为128,那是点阵的分布,不是读写的分布,如正图表示,y轴的32行,从0到31,x轴的16 从0到15,0到7为上半个屏幕,8到15在下半个屏幕,所以绘图的时候,有两个部分要进行书写 在12864上载入任意一幅图: 示例代码: #include reg52.h #define uint unsigned int #define uchar unsigned char sbit lcdrs = P2^4;//数据还是指令的选择端口 sbit lcdwr = P2^5;//读写操作端口 sb
[单片机]
单片机的动手实践篇--<font color='red'>51单片机</font>玩转12864
8051单片机内部的结构及运行过程解析
1.ROM:只读存储器,单片机的只读存储区大多用于存储程序固又称程序存储器。 51单片机是EPROM,所谓的EPROM是可擦除的只读存储器。可以把原来的程序擦除了,再写一个新的进去。 断电后是可以保存的,数据存储器(RAM)是不能保存的。 RAM只能在程序执行的时候不断地重新存储定义的变量。如int x,int y 可以通过code这个指令来将定义的变量放在ROM,而不是RAM中,节省RAM资源 2.RAM:随机存取存储器,用于存储定义的变量等,速度快 51单片机的RAM存储容量远小于ROM,但是速度非常之快 内部详细图示 内部的结构看似十分复杂,但是大致上可以分为两个部分:运算器(红色框)和控制器(蓝色框)。 运算器
[单片机]
80<font color='red'>51单片机</font>的<font color='red'>内部</font>的结构及运行过程解析
51单片机-asm与C混合编程
  一是源程序中直接混合嵌入,二是做成库函数调用,三是做成是中间文件在链接中加入。   在单片机应用系统设计中,过去主要采用汇编语言开发程序。汇编语言编写的程序对单片机硬件操作很方便,编写的程序代码短,效率高,但系统设计的周期长,可读性和可移植性都很差。C语言程序开发是近年来单片机系统开发应用所采用的主要开发方式之一,C 语言功能丰富、表达能力强、使用灵活方便、开发周期短、可读性强、可移植性好。但是,采用C 语言编程还是存在着如对硬件没有汇编方便、效率没有汇编高、编写延时程序精确度不高等缺点,因而现在单片机系统开发中经常用到C 语言与汇编语言混合编程技术。混合编程技术可以把C 语言和汇编语言的优点结合起来,编写出性能优良的程序
[单片机]
<font color='red'>51单片机</font>-asm与C混合编程
基于51单片机+DS18B20温度测温器+LCD1602显示
DS18B20特性 1.独特的单总线接口,就需一条线则可实现双向通信(测温) 2.测温范围:-55℃~+125℃,可通过编程设定9—12位分辨率,对应分辨温度分别为0.5、0.25、0.125、0.0625℃。 3.支持多点组网(可连接多个DS18B20温度传感器),多个DS18B20可以并联(3或2线)实现多个组网测温,但注意超过8个要解决好供电问题,否则电压过低会导致传输不稳定,从而数据不准确。 4.工作电压:3.0~5.5V (寄生电源方式下可由数据线供电) 5.在使用过程中不需要外围电路,全部传感元件及转换电路都在芯片内了。(上拉电阻) 6.测温结果直接是数字量输出,单总线串行传送方式,同时可传送CRC校验码(校验数据采集
[单片机]
基于<font color='red'>51单片机</font>+DS18B20温度测温器+LCD1602显示
51单片机内部E2ROM
/*main.c源程序*/ #include reg52.h #include E2ROM.c #include key.c sfr WDT_CONTR = 0xE1;//定义STC单片机中新加入的看门狗寄存器 code uchar seven_seg = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};//共阳数码管0--9(0时为有效断) code uchar scan_bit = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf}; //数码管位选 6 5 4 3 2 1 uchar
[单片机]
基于51单片机的串口通信(PC发字符)
串口通信 选用芯片:AT89S52 函数功能:见如下代码。 /******************************************************************* 函数功能:PC机发送数据给单片机,每次发送3个字节(每字节为8位)的数据, 每个字节的内容为0~99无符号整数中的一个;单片机接收PC机串口发送过来的 这3个字节数据,并将它们依次以十进制方式显示在6位数码管中(每两个数码管 显示一个字节数据,例如发送数据为11,9,70,则数码管上显示11 09 70); 显示采用共阳极数码管,采用动态扫描显示方式。 作者:Crazy Wind 日期:2020.10.22 version:1
[单片机]
8051单片机教程第五课:延时程序分析
上一次课中,我们已经知道,程序中的符号R7、R6是代表了一个个的RAM单元,是用来放一些数据的,下面我们再来看一下其它符号的含义。 DELAY:MOVR7,#250;(6) D1:MOVR6,#250;(7) D2:DJNZR6,D2;(8) DJNZR7,D1;(9) RET;(10) MOV:这是一条指令,意思是传递数据。说到传递,我们都很清楚,传东西要从一个人的手上传到另一个人的手上,也就是说要有一个接受者,一个传递者和一样东西。从指令MOVR7,#250中来分析,R7是一个接受者,250是被传递的数,传递者在这条指令中被省略了(注意:并不是每一条传递指令都会省的,事实上大部份数据传递指令都会有传递者
[单片机]
80<font color='red'>51单片机</font>教程第五课:延时程序分析
51单片机定时器总结
1.定时器TMOD寄存器 C/T这一位用来控制定时器工作方式。本来T上面有一横表示低电平有效。c为计数,也即是及外部脉冲的个数,也会是定时器溢出及中断。GATE这一位用来设定外部中断脉冲是否可启动定时器。 意思就是当GATE=1时,定时器的启动有二个位控制,即TR0和int0(这是对定时器0来说的,T1的话上二位就是1)。定时器只有在上二位都是一的情况下才会启动。我们就可以利用这个功能来测量脉冲的宽度。 我们知道在其他单片机中我们测脉冲宽度可以利用外部中断在上升沿河下降沿各读取一次定时器值来测定。但51单片机没有上升沿中断,也就没有办法测出高电平宽度。现在我们可以这样做,令TR0=1,GATE=1,这时定时器的启动只有INT0
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved