搜索
bottom↓
回复: 27

!!!痛苦,AVR内部EEPROM读写失败,已经严格按照官方手册规定的步骤来写,极其精简仍然不成功,

[复制链接]

出0入0汤圆

发表于 2011-11-20 16:31:11 | 显示全部楼层 |阅读模式
代码极其简单的EEPROM读写程序,调试良久,仍不成功,已经无语了。求助各位高手,指点一二!

硬件电路连接:(很简单的,就不贴电路图出来了)
1、使用4位共阳数码管显示数值。
2、使用外部晶振8MHz。
3、+5V外部电源供电。
4、使用标准的ISP下载口下载程序。(本人有并行打印口和USB下载器,两者都能正常下载程序)

软件和程序设置:
1、使用AVR Studio 4.12编程软件,下载到单片机的软件是:ProgISP V1.66版。
2、AVR Studio 4.12设置频率为8MHz,优化程度选:00(即没有优化)。
3、单纯为了测试EEPROM有没有成功,除了显示函数外,其它函数和功能一概没有。
4、严格按照官方手册规定的步骤来写。


(原文件名:GCC中的频率设置.jpg)


下载软件ProgISP V1.66的设置:
1、勾选:外部晶振(3.0--MHz)起动时间16K CK+64ms[...省略N字...]
2、不勾选:使能JTAG接口。 JTAGEN
3、勾选:使能ISP编程。  SPIEN
4、勾选:执行芯片擦除时保留EEPROM的内容。  EESAVE
5、其它选项使用默认值。
6、时钟校正框选择:1.0MHz。(1.0MHz-8.0MHz都试过了不成功)
7、编程框选择:“芯片擦除”、“编程FLASH”、“校验FLASH”、“编程熔丝”、“数据自动重载”,其它不选。

熔丝低位:(1=未被编程,0=被编程)
1 BODLEVEL: BOD触发电平,默认值:1
1 BODEN:      BOD使能,默认值:1
1 SUT1:        选择启动时间,默认值:1
1 SUT0:        选择启动时间,默认值:0
1 CKSEL3:     选择时钟源,默认值:0
1 CKSEL2:     选择时钟源,默认值:0
1 CKSEL1:     选择时钟源,默认值:0
1 CKSEL0:     选择时钟源,默认值:1

熔丝高位:
1 OCDEN:     使能OCD,默认值:1
1 JTAGEN:    JTAG仿真调试接口,默认值:0
0 SPIEN:       SPI下载允许,使能串行程序和数据下载,默认值:0
1 CKOPT:      振荡器选项,默认值:1
0 EESAVE:    执行芯片擦除时EEPROM的内容保留,默认值:1(1:不保留;0:保留)
0 BOOTSZ1:  选择BOOT区大小,默认值:0
0 BOOTSZ0:  选择BOOT区大小,默认值:0
1 BOOTRST:  选择复位向量,默认值:1


(原文件名:下载器抓图01.jpg)


(原文件名:下载器抓图02.jpg)


下面是程序源码:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>

//*************************************************************************
//   定义LED数码管的位选端和小数点位置
//*************************************************************************
...省略N字...(地球人都知道数码管的管脚定义方法,在此就不贴出来了)

#ifndef  FREQ
#define  FREQ    (8)  // 单片机主频为8MHz,用于延时子程序,括号(8)里面的“8”表示单片机的主频为8MHz。
#endif  

//*************************************************************************
//   精确延时定义
//*************************************************************************
#define delay_1us(x)\
_delay_loop_2((uint)((x)*FREQ/4))  //_delay_loop_2(xxx)的意思是等于=xxx*4(个cpu时钟周期)/8(M时钟)
//#define delay_1us(x)中的括号(x)里面的“x”表示延时x uS。例如:x为1表示延时1uS,x为550表示延时550uS。

#define uchar  unsigned char
#define uint   unsigned int
uchar scandata[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xfe,0xf7,0xbf};//共阳极数码管段码,为0-9,10:空白和11:上标-,12:下标_,13:中间-

//*************************************************************************
//   显示函数
//*************************************************************************
void Display(uint i)
{
...省略N字...(很简单的显示程序,地球人都知道,在此就不贴出来了)
}

//*************************************************************************
//   AVR内部EEPROM写函数
//*************************************************************************
void EEPROM_write(uint addr,uint adata) //写EEPROM函数
{
        while(EECR & (1<<EEWE));//等待上一次写操作结束
        EEAR=addr; //配置地址
        EEDR=adata;//配置数据
        EECR |= (1<<EEMWE);//置位EEMWE
        EECR |= (1<<EEWE);//置位EEWE以启动写操作
}

//*************************************************************************
//   AVR内部EEPROM读函数
//*************************************************************************
uchar EEPROM_read(uint addr) //读EEPROM函数
{
        while(EECR & (1<<EEWE)); //等待上一次写操作结束
        EEAR=addr; //配置地址
        EECR |= (1<<EERE);//设置EERE以启动读操作
        return EEDR; //直接从数据寄存器返回数据,不需要另外定义变量了。
}

//*************************************************************************
//   主程序
//*************************************************************************
int main(void)
{
        DDRA=0b11111111; //设置PA端口为输出口,1为输出,0为输入。(段码)
        DDRC|=0b00001111; //设置PC端口的第1~4个端口为输出口。(位选端)
        uint i=99;
        uint j=57;

        EEPROM_write(2,j); //在地址2的位置上,写入数据j。(把57这个数存入EEPROM,然后再读出来,以此验证读写是否成功)
        delay_1us(10); //延时10us,让写和读之间有个空隙。
        i=EEPROM_read(2); //从第2个地址读取数据。

        while(1)
        {
                Display(i); //显示EEPROM中存储的数值
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-11-20 17:10:50 | 显示全部楼层
先用库函数解决,再用自己的程序对比。
如果库函数也出错,换芯片。
换芯片仍错,换厂家或使用外置EEPROM。
还错,换工作!

出0入0汤圆

 楼主| 发表于 2011-11-20 17:27:00 | 显示全部楼层
回复【1楼】cock
先用库函数解决,再用自己的程序对比。
......
-----------------------------------------------------------------------

什么是“库函数”??

出0入0汤圆

发表于 2011-11-20 17:43:48 | 显示全部楼层
我用m8的eeprom很好用,cvavr下很方便。

出0入0汤圆

发表于 2011-11-20 18:00:16 | 显示全部楼层
我用的M64内部EEPROM,就照抄手册上的那段汇编程序。现在稳如磐石。操作EEPROM,最好关中断。另外还要记得打开BOD哦。

出0入0汤圆

发表于 2011-11-20 18:21:47 | 显示全部楼层
回复【楼主位】Ilove51andAVR  
-----------------------------------------------------------------------

#include <avr/eeprom.h>  .....都已经引用了却不用,好好看看手册。

出0入0汤圆

发表于 2011-11-20 20:01:40 | 显示全部楼层
做这种无用功!为何不直接用库函数,而且具有通用性,多好啊

出0入0汤圆

发表于 2011-11-20 20:46:13 | 显示全部楼层
参考一下iar的自带的

写数据
#define __EEPUT(ADR,VAL)  {while (EECR & 0x02); \
EEAR = (ADR); EEDR = (VAL); EECR = 0x04; EECR = 0x02;}

读数据
#define __EEGET(VAR, ADR) {while (EECR & 0x02); \
        EEAR = (ADR); EECR = 0x01; (VAR) = EEDR;}

出0入0汤圆

 楼主| 发表于 2011-11-20 22:09:49 | 显示全部楼层
回复【5楼】huayuliang 花生
回复【楼主位】ilove51andavr   
-----------------------------------------------------------------------
#include &lt;avr/eeprom.h&gt;  .....都已经引用了却不用,好好看看手册。
-----------------------------------------------------------------------

回复【6楼】jason1927
做这种无用功!为何不直接用库函数,而且具有通用性,多好啊
-----------------------------------------------------------------------


我汗啊,原来AVR Studio 4.12(GCC)编程软件已经自带了读写语句,只需要三句就搞定了:
i=eeprom_read_byte((uchar *)0x02); //从EEPROM读取0x02地址处的数据赋给i。
eeprom_busy_wait();//等待EEPROM读写空闲
eeprom_write_byte((uchar *)0x02,j); //把j的值写入EEPROM地址0x02处。

以上三句就搞定了一切,根本用不着按ATMega16的官方手册来编写EEPROM的程序。看来对GCC编程软件自带的库函数还不熟悉。

已经调试成功,谢谢大家!

出0入0汤圆

发表于 2011-11-20 22:53:44 | 显示全部楼层
回复【楼主位】ilove51andavr   

按ATMega16的官方手册来编写EEPROM的程序,
-----------------------------------------------------------------------
因为手册写EEPROM的程序时序有误。

问题出现在最後两句, ECR |= (1<<EEMWE);//置位EEMWE
及 EECR |= (1<<EEWE);//置位EEWE以启动写操作。ASM 程序没问题, C 程序超过了容许时限(四个周期)。

出0入0汤圆

发表于 2011-11-20 22:59:21 | 显示全部楼层
超容许时限(四个周期)是因为优化级最低时,把SFR当RAM操作,才超时的。优化到0级之外的其它级,就可以了。

出0入0汤圆

发表于 2011-11-21 00:24:21 | 显示全部楼层
都是高手

出0入0汤圆

发表于 2011-11-21 10:43:00 | 显示全部楼层
库自带的函数,好方便的

出0入0汤圆

发表于 2012-3-24 12:29:30 | 显示全部楼层
mark。。。。

出0入296汤圆

发表于 2012-3-24 15:22:51 | 显示全部楼层
winavr中,有些芯片对时序有要求的寄存器设置需要将优化等级设置为-O0以上,比较推荐-Os

出0入0汤圆

发表于 2012-3-24 21:01:50 | 显示全部楼层
不是有内部的读写函数吗?

出0入0汤圆

发表于 2012-3-24 22:54:07 | 显示全部楼层
这个。。。其实真的用内部函数就好了嘛、、

出0入0汤圆

发表于 2012-3-27 19:52:49 | 显示全部楼层
学习了,刚要用

出0入10汤圆

发表于 2012-3-28 09:15:31 | 显示全部楼层
本来内部有的,我以前也出过问题,那个DATASHEET里的要改一下也可以用的

出0入0汤圆

发表于 2013-8-16 08:52:13 | 显示全部楼层
chengtina 发表于 2012-3-28 09:15
本来内部有的,我以前也出过问题,那个DATASHEET里的要改一下也可以用的

datasheet里面的函数需要修改什么?

出0入10汤圆

发表于 2013-8-16 17:00:17 | 显示全部楼层
zhengyiqun 发表于 2013-8-16 08:52
datasheet里面的函数需要修改什么?

void EEPROM_write(uint uiAddress, uchar ucData)
{
        while(EECR & (1<<EEWE))         /* 等待上一次写操作结束 */
        ;  
        EEAR = uiAddress;         /* 设置地址和数据寄存器*/
        EEDR = ucData;
        EECR |= (1<<EEMWE);         /* 置位EEMWE */
//        EECR |= (1<<EEWE);
        EECR = (1<<EEWE) | (1<<EEMWE); //修改这里         /* 置位EEWE 以启动写操作*/
}

出0入0汤圆

发表于 2013-8-17 19:01:51 来自手机 | 显示全部楼层
chengtina 发表于 2013-8-16 17:00
void EEPROM_write(uint uiAddress, uchar ucData)
{
        while(EECR & (1

置位EEMWE前加上一句cli();写完成以后加上,sei();

出0入0汤圆

发表于 2013-9-12 11:03:18 | 显示全部楼层
chengtina 发表于 2013-8-16 17:00
void EEPROM_write(uint uiAddress, uchar ucData)
{
        while(EECR & (1

读取EEPROM的内容函数是否有这样的情况?我现在是ATMEGA328P在用datasheet中的的读取EEROM函数出现有问题!!读取一个变量的内容变成oxff;等下次上电可能就OK了~~EEPROM内存的数据没变,只是读上来有问题~~

出0入0汤圆

发表于 2014-9-5 10:30:23 | 显示全部楼层
chengtina 发表于 2013-8-16 17:00
void EEPROM_write(uint uiAddress, uchar ucData)
{
        while(EECR & (1

找到您去年的回复,解决了我的问题,谢谢!

出0入0汤圆

发表于 2014-9-5 10:38:46 来自手机 | 显示全部楼层
用CVAVR是最方便的,直接使用就行。eeprom unsigned char a;a=

出0入0汤圆

发表于 2015-10-31 10:41:34 | 显示全部楼层
搞了一个早上,看到这个帖子一下就搞好了,谢谢

出0入0汤圆

发表于 2015-10-31 11:19:17 | 显示全部楼层
M64 M128 内置eeprom有掉数据,不知道程序哪里的问题  

出0入0汤圆

发表于 2015-10-31 15:08:56 来自手机 | 显示全部楼层
这种情况,我一般先看官方汇编程序。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 08:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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