#include "qs_config.h"
#include "qs_eeprom.h"
#include "qs_log.h"
#include "qs_sched.h"
//#define QS_SIMPLE_CHECKSUM
/*************************************************************
* 在掉电休眠模式下的EEPROM写操作
* 若程序执行掉电指令时EEPROM 的写操作正在进行, EEPROM 的写操作将继续,并在指定的写访问时间之前完成。
* 但写操作结束后,振荡器还将继续运行,芯片并非处于完全的掉电模式。
* 因此在执行掉电指令之前应结束EEPROM 的写操作。
*
* 防止EEPROM 数据丢失
* 若电源电压过低,CPU 和EEPROM 有可能工作不正常,造成EEPROM 数据的毁坏( 丢失)。这种情况在使用独立的EEPROM 器件时也会遇到。因而需要使用相同的保护方案。
* 由于电压过低造成EEPROM 数据损坏有两种可能:一是电压低于EEPROM 写操作所需 要的最低电压;二是CPU 本身已经无法正常工作。
* EEPROM 数据损坏的问题可以通过以下方法解决:
* 当电压过低时保持AVR RESET 信号为低。
* 这可以通过使能芯片的掉电检测电路BOD 来实现。如果BOD 电平无法满足要求则可以使用外部复位电路。若写操作过程当中发生了复位,只要电压足够高,写操作仍将正常结束。
**************************************************************/
//只能定义为全局变量
//char ss __attribute__((section(".eeprom")));
void EEPROM_write(unsigned int uiAddress, unsigned char ucData) {
// cli(); //关总中断
/* 等待上一次写操作结束 */
while (EECR & (1 << EEWE))
;//等待写入周期的完成,EEWE为EEPROM写使能
/* 设置地址和数据寄存器*/
EEAR = uiAddress;
EEDR = ucData;
/* 置位EEMWE */
EECR |= (1 << EEMWE);
/* 置位EEWE 以启动写操作*/
EECR |= (1 << EEWE);
// sei(); //开总中断
// qs_sched_delay_ms(2);
}
unsigned char EEPROM_read(unsigned int uiAddress) {
// cli(); //关总中断
/* 等待上一次写操作结束 */
while (EECR & (1 << EEWE))
;
/* 设置地址寄存器*/
EEAR = uiAddress;
/* 设置EERE 以启动读操作*/
EECR |= (1 << EERE);
/* 自数据寄存器返回数据 */
// sei(); //开总中断
// qs_sched_delay_ms(1);
return EEDR;
}
void qs_eeprom_write_bytes(unsigned int addr, const void* p_data, uint8_t data_len)
{
const char* p_data_char = (const char*)p_data;
for(uint8_t i = 0; i < data_len; i ++ ) {
EEPROM_write(addr+i, p_data_char[i]);
asm("WDR");
}
}
void qs_eeprom_read_bytes(unsigned int addr, void* p_data, uint8_t data_len)
{
char* p_buffer_char = (char*)p_data;
for(unsigned int i = 0; i < data_len; i ++ ) {
p_buffer_char[i] = EEPROM_read(i+addr);
asm("WDR");
}
}
unsigned char eeprom_check_sum_cal(char* p_buffer,unsigned int size)
{
unsigned char i;
unsigned char sum;
sum = 0;
for (i = 0; i < size; i++)
{
sum += p_buffer[i];
}
return ~sum;
}
void qs_eeprom_checksum_update(void* p_buffer,unsigned int numBytes)
{
uint8_t check_sum_cal = eeprom_check_sum_cal(p_buffer, numBytes);
EEPROM_write(QS_CHECKSUM_ADDR, check_sum_cal);
//qs_log_print("check_sum_cal %d", check_sum_cal);
}
void qs_eeprom_load(void* p_buffer,unsigned int numBytes, on_settings_reset_handler_t p_settings_reset)
{
if(numBytes < 1) {
return;
}
qs_eeprom_read_bytes(QS_SETTINGS_DATA_ADDR, p_buffer, numBytes);
uint8_t check_sum_mem = EEPROM_read(QS_CHECKSUM_ADDR);
uint8_t check_sum_cal = eeprom_check_sum_cal(p_buffer, numBytes);
//qs_log_print("crc [%d, %d]", check_sum_mem, check_sum_cal);
if(check_sum_mem != check_sum_cal && p_settings_reset) {
p_settings_reset();
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
atmega8 内部256字节的eeprom读写
共2个文件
h:1个
c:1个
需积分: 5 2 下载量 196 浏览量
2023-09-23
22:03:36
上传
评论
收藏 2KB RAR 举报
温馨提示
atmega8 内部512字节的eeprom读写例子。参数值配置在起始地址0,求和校验码存储在地址0x1FA.初始化时,调用qs_eeprom_load,校验失败后,回调函数p_settings_reset。重置参数。正常写操作qs_eeprom_write_bytes,需要调用qs_eeprom_checksum_update更新校验,正常读操作qs_eeprom_read_bytes
资源推荐
资源详情
资源评论
收起资源包目录
eeprom.rar (2个子文件)
qs_eeprom.c 3KB
qs_eeprom.h 870B
共 2 条
- 1
资源评论
wayne2018
- 粉丝: 130
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功