辉芒微教程第四篇《EEPROM-断电记忆开关状态》

13 篇文章

已下架不支持订阅

目录

一、本节课目标

二、电路原理

三、编程

(1)任务1:实现按键开关灯

(2)任务2:实现EEPROM的读写

(3)任务3:断电保存灯的开关状态

四、最后注意事项


第0篇:  辉芒微开源电路板链接.立创PCB

第1篇:  辉芒微教程第一篇《软件的安装与程序下载》

第2篇:  辉芒微教程第二篇《程序基本结构与点灯,延时函数》

第3篇:  辉芒微教程第三篇《IO口输入设置与按键切换继电器状态》

第4篇:  辉芒微教程第四篇《EEPROM-断电记忆开关状态》

第5篇:  辉芒微教程第五篇《定时器0实现LED灯的闪烁》

第6篇:  辉芒微教程第六篇《定时器1和定时器2多个定时器混用》

第7篇:  辉芒微教程第七篇《PWM是什么与PWM3调节LED灯的亮度》

第8篇:  辉芒微教程第八篇《PWM4/PWM5调节舵机的角度》

第9篇:  辉芒微教程第九篇《模拟串口打印数据》

第10篇:辉芒微教程第十篇《串口打印实战-EEPROM记忆日志数据打印》

第11篇:辉芒微教程第十一篇《ADC读取电压并且打印出来-简易万用表》

第12篇:辉芒微教程第十二篇《项目综合开发结构布置ADC的程序》

第13篇:辉芒微教程第十三篇《看门狗的设置》

第14篇:辉芒微教程第十四篇《辉芒微外部中断实验》

第15篇:辉芒微教程第十五篇《辉芒微IIC实验》

第16篇:辉芒微教程第十六篇《辉芒微SPI实验》

第17篇:辉芒微教程第十七篇《辉芒微量产工作需要用哪些软件与做哪些工作》

第18篇:辉芒微教程第十八篇《辉芒微开发其他芯片说明》

前言

        EEPROM作为一个断电不会丢失的数据的单片机功能,在有些产品中起到很重要的功能,假设客户要求你的产品能够进行断电保存记忆,比如你做一个电机产品,它现在是运行的,但是设备断电了,客户要求来电的时候,如果设备断电前是开着的,那么来电的时候就要打开电机运行。那这时候EEPROM就起到很重要的功能了!!!        

        (此段新手能理解就理解,不能理解就算了)做过STM32的老表一般会把这种数据保存到Flash中,但是每次写入都不是一个个字节写入,而是先擦除几百字节或者上千字节,再一个个写入,这样写入很不方便,因为需要建立一个很大的数组(不然会擦除其他数据),这样就很占运行内存,特别是8位单片机这种,并且我也不需要保存那么多数据,不过辉芒微相对于其他国外或者国产单片机就非常有优势,芯片内置EEPROM,无需额外购买EEPROM,并且它可以实现一个个写入,这样就很省运行空间了!

一、本节课目标

        掌握辉芒微EEPROM的使用,并且实现断电记忆灯的开关状态。

二、电路原理

        我们的KEY键接在PC2上,直接接地,需要做软件消抖,我们的LED接着PC4上,需要使用高电平点亮,低电平熄灭。

三、编程

(1)任务1:实现按键开关灯
#include	"SYSCFG.h"                //这个芯片的必要头文件
 
/*------------------------------------------------- 
* 函数名称:DelayUs
* 功能:    短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time us
* 返回参数:无 
 -------------------------------------------------*/
void DelayUs(unsigned char Time)
{
	unsigned char a;
	for(a=0;a<Time;a++)
	{
		NOP();
	}
}                  
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能:    短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无 
 -------------------------------------------------*/
void DelayMs(unsigned char Time)
{
	unsigned char a,b;
	for(a=0;a<Time;a++)
	{
		for(b=0;b<5;b++)
		{
		 	DelayUs(197); 	//快1%
		}
	}
}
 
void interrupt ISR(void)              //中断函数,本节无需要
{
}
 
void SingleChipConfig(void)		      //单片机配置函数
{
	OSCCON = 0B01110001;	//IRCF=111=16MHz/2T=8MHz,0.125us
	INTCON = 0;  			//暂禁止所有中断
	PORTA = 0B00000000;		
	TRISA = 0B00000000;		//PA输入输出 0-输出 1-输入
    
	PORTC = 0B00000000; 	
	TRISC = 0B00000100;		//PC输入输出 0-输出 1-输入
      
	WPUA  = 0B00000000;     //PA端口上拉控制 1-开上拉 0-关上拉
	WPUC  = 0B00000100;     //PC端口上拉控制 1-开上拉 0-关上拉
 
	OPTION = 0B00001000;	//Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
    MSCKCON = 0B00000000;
    //Bit6->0,禁止PA4,PC5稳压输出
	//Bit5->0,TIMER2时钟为Fosc
	//Bit4->0,禁止LVR       
	CMCON0 = 0B00000111; 	//关闭比较器,CxIN为数字IO口
	ANSEL  = 0B00000000;    
}
 
void main(void)                       //主函数
{
	SingleChipConfig();
	while(1)
    {
		if(!PC2)
        {
			DelayMs(50);
            if(!PC2)
            {
				PC4 = !PC4;
                while(PC2 == 0)
                {
                
                };
            }
        }
    }
}

        这个程序跟上节课差不多,不理解的朋友可以看上一篇章,接下来我们可以看一下效果;

DJI

(2)任务2:实现EEPROM的读写
void Eeprom_Write(unsigned char address,unsigned char value)//EEPROM写函数
{
    CLRWDT();
	EEADR = address;
	asm("nop");
	EEDAT = value;
	EECON1 = 0x34;
	WR = 1;
	asm("nop");	
	asm("nop");
	asm("nop");
	while(WR==1)CLRWDT();
	WREN1 = 0;
	WREN2 = 0;
	WREN3 = 0;
}
unsigned char Eeprom_Read(unsigned char address)//EEPROM读函数
{
	unsigned char EepromData;
	CLRWDT();
	EEADR = address;
	RD = 1;
	EepromData = EEDAT;
	RD = 0;
	return(EepromData);
}

        这个是EEPROM的写函数和读函数,其在辉芒微系列的8位单片机中,基本通用,其中的address是需要操作的地址,因为我们的芯片的EEPROM大小是256字节,因此其地址为0-255(对应16进制地址是0x00-0xff);

        在编程软件里面,我们可以看到其EEPROM的初始化地址

        由此看出,该芯片的EEPROM有256字节,默认每个字节的初始化大小为0xff,我们可以对单独的某个字节进行写入。

        现在我们实验一下,在之前的程序上,加入我们的读写程序,并且程序运行一开始,在地址0xfe写入value值为0x8的数值。

#include	"SYSCFG.h"                //这个芯片的必要头文件
 
void Eeprom_Write(unsigned char address,unsigned char value)//EEPROM写函数
{
    CLRWDT();
	EEADR = address;
	asm("nop");
	EEDAT = value;
	EECON1 = 0x34;
	WR = 1;
	asm("nop");	
	asm("nop");
	asm("nop");
	while(WR==1)CLRWDT();
	WREN1 = 0;
	WREN2 = 0;
	WREN3 = 0;
}
unsigned char Eeprom_Read(unsigned char address)//EEPROM读函数
{
	unsigned char EepromData;
	CLRWDT();
	EEADR = address;
	RD = 1;
	EepromData = EEDAT;
	RD = 0;
	return(EepromData);
}
/*------------------------------------------------- 
* 函数名称:DelayUs
* 功能:    短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time us
* 返回参数:无 
 -------------------------------------------------*/
void DelayUs(unsigned char Time)
{
	unsigned char a;
	for(a=0;a<Time;a++)
	{
		NOP();
	}
}                  
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能:    短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无 
 -------------------------------------------------*/
void DelayMs(unsigned char Time)
{
	unsigned char a,b;
	for(a=0;a<Time;a++)
	{
		for(b=0;b<5;b++)
		{
		 	DelayUs(197); 	//快1%
		}
	}
}
 
void interrupt ISR(void)              //中断函数,本节无需要
{
}
 
void SingleChipConfig(void)		      //单片机配置函数
{
	OSCCON = 0B01110001;	//IRCF=111=16MHz/2T=8MHz,0.125us
	INTCON = 0;  			//暂禁止所有中断
	PORTA = 0B00000000;		
	TRISA = 0B00000000;		//PA输入输出 0-输出 1-输入
    
	PORTC = 0B00000000; 	
	TRISC = 0B00000100;		//PC输入输出 0-输出 1-输入
      
	WPUA  = 0B00000000;     //PA端口上拉控制 1-开上拉 0-关上拉
	WPUC  = 0B00000100;     //PC端口上拉控制 1-开上拉 0-关上拉
 
	OPTION = 0B00001000;	//Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
    MSCKCON = 0B00000000;
    //Bit6->0,禁止PA4,PC5稳压输出
	//Bit5->0,TIMER2时钟为Fosc
	//Bit4->0,禁止LVR       
	CMCON0 = 0B00000111; 	//关闭比较器,CxIN为数字IO口
	ANSEL  = 0B00000000;    
}
 
void main(void)                       //主函数
{
	SingleChipConfig();
    Eeprom_Write(0xfe,0x08);
	while(1)
    {
		if(!PC2)
        {
			DelayMs(50);
            if(!PC2)
            {
				PC4 = !PC4;
                while(PC2 == 0)
                {
                
                };
            }
        }
    }
}

        当我们编译并且下载到板子的时候,旁边的EEPROM框会变成这样

        其中的0xfe的value值变成了0x08,当然,因为我这行代码是放在While外面的,所以它算是程序的初始化,如果你试图在while里面进行动态改变,如果想要查看EEPROM的数值变化,那这样的方式是查看不了的。
 

        那么如果我们调试的程序一定想要看到现在的EEPROM值是多少怎么办呢,方法有很多种,这里我们只介绍一种,我常用的,这里我们就用到我们前面安装的FMDProgrammer软件。我们先在程序里面写一个变量增加,每隔一秒写入一次。然后我们运行了一段时间,再用这个软件进行查看。

我们把上面的while程序变动下:

unsigned char count;
void main(void)                       //主函数
{
	SingleChipConfig();
	while(1)
    {
		if(!PC2)
        {
			DelayMs(50);
            if(!PC2)
            {
				PC4 = !PC4;
                count++;
                Eeprom_Write(0xfe,count);
                while(PC2 == 0)
                {
                
                };
            }
        }
    }
}

        每当我们按一下的时候,地址0xfe的value值增加1,记住我们按下去的次数,然后再去这个软件里面读取。

     

最终我们看到按下11(0x0b)次,具体是多少,要看你们自己按了多少次。

(3)任务3:断电保存灯的开关状态

        接下来我们来写本节课的主题程序,即记录按键按下灯的状态到EEPROM中,当设备断电或者开机的时候,可以读取对应的地址值,从而初始化的时候对灯进行开或者关的状态。

#include	"SYSCFG.h"                //这个芯片的必要头文件
 
void Eeprom_Write(unsigned char address,unsigned char value)//EEPROM写函数
{
    CLRWDT();
	EEADR = address;
	asm("nop");
	EEDAT = value;
	EECON1 = 0x34;
	WR = 1;
	asm("nop");	
	asm("nop");
	asm("nop");
	while(WR==1)CLRWDT();
	WREN1 = 0;
	WREN2 = 0;
	WREN3 = 0;
}
unsigned char Eeprom_Read(unsigned char address)//EEPROM读函数
{
	unsigned char EepromData;
	CLRWDT();
	EEADR = address;
	RD = 1;
	EepromData = EEDAT;
	RD = 0;
	return(EepromData);
}
/*------------------------------------------------- 
* 函数名称:DelayUs
* 功能:    短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time us
* 返回参数:无 
 -------------------------------------------------*/
void DelayUs(unsigned char Time)
{
	unsigned char a;
	for(a=0;a<Time;a++)
	{
		NOP();
	}
}                  
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能:    短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无 
 -------------------------------------------------*/
void DelayMs(unsigned char Time)
{
	unsigned char a,b;
	for(a=0;a<Time;a++)
	{
		for(b=0;b<5;b++)
		{
		 	DelayUs(197); 	//快1%
		}
	}
}
 
void interrupt ISR(void)              //中断函数,本节无需要
{
}
 
void SingleChipConfig(void)		      //单片机配置函数
{
	OSCCON = 0B01110001;	//IRCF=111=16MHz/2T=8MHz,0.125us
	INTCON = 0;  			//暂禁止所有中断
	PORTA = 0B00000000;		
	TRISA = 0B00000000;		//PA输入输出 0-输出 1-输入
    
	PORTC = 0B00000000; 	
	TRISC = 0B00000100;		//PC输入输出 0-输出 1-输入
      
	WPUA  = 0B00000000;     //PA端口上拉控制 1-开上拉 0-关上拉
	WPUC  = 0B00000100;     //PC端口上拉控制 1-开上拉 0-关上拉
 
	OPTION = 0B00001000;	//Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
    MSCKCON = 0B00000000;
    //Bit6->0,禁止PA4,PC5稳压输出
	//Bit5->0,TIMER2时钟为Fosc
	//Bit4->0,禁止LVR       
	CMCON0 = 0B00000111; 	//关闭比较器,CxIN为数字IO口
	ANSEL  = 0B00000000;    
}

void main(void)                       //主函数
{
	SingleChipConfig();
    if( Eeprom_Read(0xfe)== 1 )
    {
		PC4 = 1;
    }
    else
    {
		PC4 = 0;
    }
	while(1)
    {
		if(!PC2)
        {
			DelayMs(50);
            if(!PC2)
            {
				PC4 = !PC4;
                Eeprom_Write(0xfe,PC4);
                while(PC2 == 0)
                {
                
                };
            }
        }
    }
}

        初始化的if是读取EERPOM地址0xfe的数值,然后对其进行判断,如果返回结果是1则开灯,如果返回结果是0则关灯。

        每次按键按下去的时候都会将PC4灯的状态保存到EEPROM中,这样下次设备开机的时候,就可以根据其数据对灯进行反应,我们可以看产品效果:

DJI

四、最后注意事项

        不注意有可能做项目的时候自己坑自己哦!

        无论是哪个品牌的单片机的EEPROM或者专门的EEPROM芯片,其写入都是有寿命的,不能跟无限制写入,比如我们的单片机,它可写入100K次(100 000次),因此在做项目的时候我们要考虑设备可能使用的次数,说人话就是不能频繁写入,假设我一天写100次,那你这个设备可以支持1000天,如果一天写入1000次,那么最多可写入100天(产品半年不到就可能废了,别逼你客户骂你)。

已下架不支持订阅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值