打印
[STC单片机]

stc125a60单片机 eeprom对两个扇区操作发现的问题

[复制链接]
2774|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huzb11|  楼主 | 2016-8-15 13:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
项目在最后的弄打印机程序了,项目中需要将体重数据与身高数据做成两个函数保存。然后调用两函数打印。可是主函数中单个eeprom程序能运行正常,一旦主程序里一起调用时,作显示测试时,发现两个函数显示的内容是一样的。这是怎么回事?

main()

{

.....
while(1)

{

        Disp_tg(tg_eeprom_test());  //调用eeprom显示体重,后调用打印
        Disp_sg(sg_eeprom_test());  //调用eeprom显示身高,后调用打印

}


}

以上是对eeprom调用时,作调试用。调试OK后,打印机好调用两函数。
//以下为两个eeprom程序,注意是两个字节的,可以显示四位数的。

u16 tg_eeprom_test()
{
  u8 tg_h;
  u8 tg_l;         

if((tg_test()>60)&&(sg_test()>1300))
        {   Delay3000ms();
                if((tg_test()>60)&&(sg_test()>1300))
                {
                         if(t_**==0)
                          {
                          sector_eraser(0x00, 0x00);
                          sector_eraser(0x00, 0x01);
                          byte_write(0x00, 0x00, tg_test()/10);
                          byte_write(0x00, 0x01, tg_test()%10);
                          t_**=1;
                          }
                          else
                          {
                          tg_h=byte_read(0x00, 0x00);
                          tg_l=byte_read(0x00, 0x01);
                         // tg_da=tg_h*10+tg_l;
                          t_**=0;
                          }
                }
       
        }

   return  tg_h*10+tg_l;
       
}


u16 sg_eeprom_test()
{
  u8 sg_h;
  u8 sg_l;         

if((tg_test()>60)&&(sg_test()>1300))
        {   Delay3000ms();
                if((tg_test()>60)&&(sg_test()>1300))
                {
                         if(s_**==0)
                          {       
                          sector_eraser(0x02, 0x00);
                          sector_eraser(0x02, 0x01);
                          byte_write(0x02, 0x00, sg_test()/10);
                          byte_write(0x02, 0x01, sg_test()%10);
                          s_**=1;
                          }
                          else
                          {
                          sg_h=byte_read(0x02, 0x00);
                          sg_l=byte_read(0x02, 0x01);
                         // tg_da=tg_h*10+tg_l;
                          s_**=0;
                          }
                }
       
        }

   return  sg_h*10+sg_l;
       
}

哪位搞过stc12c5a60s2对两个扇区进行读写操作,我上面的程序是对两个字节的数据进行操作。但为何显示都是一样的数据呢?两个扇区的地址也不样,难不成这样也能把内容覆盖?

相关帖子

沙发
huzb11|  楼主 | 2016-8-15 13:58 | 只看该作者
我把以上两个函数合并成一个。


u16 eeprom_test()
{
  u8 tg_h;
  u8 tg_l;         

  u8 sg_h;
  u8 sg_l;

if((tg_test()>60)&&(sg_test()>1300))
        {   Delay3000ms();
                if((tg_test()>60)&&(sg_test()>1300))
                {
                         if(t_**==0)
                          {
                          sector_eraser(0x00, 0x00);
                          sector_eraser(0x00, 0x01);

                          sector_eraser(0x00, 0x02);
                          sector_eraser(0x00, 0x03);

                          byte_write(0x00, 0x00, tg_test()/10);
                          byte_write(0x00, 0x01, tg_test()%10);

                          byte_write(0x00, 0x02, sg_test()/10);
                          byte_write(0x00, 0x03, sg_test()%10);
                          t_**=1;
                          }
                          else
                          {
                          tg_h=byte_read(0x00, 0x00);
                          tg_l=byte_read(0x00, 0x01);

                          sg_h=byte_read(0x00, 0x02);
                          sg_l=byte_read(0x00, 0x03);
                         // tg_da=tg_h*10+tg_l;
                          t_**=0;
                          }
                }
       
        }

   //return  tg_h*10+tg_l;
   Disp_tg( tg_h*10+tg_l);
   Disp_sg( sg_h*10+sg_l);
       
}

在主程序里调用这个,就可以显示两个正常的数据。这是什么问题。。。

使用特权

评论回复
板凳
itxyuan| | 2016-12-15 07:47 | 只看该作者
问题就是第二次写数据把原来的覆盖掉了,我也遇到过。当时没明白怎么回事,是把地址隔的很远解决的,

使用特权

评论回复
地板
lgming2000| | 2017-2-18 21:48 | 只看该作者
给初学者发一个自己用的STC专用EEPROM操作模块代码,简单改一下适合大多数STC芯片。

/*******************************************************************************/
/************ STC15W408AS单片机 EEPROM 操作模块头文件 "STC_EEPROM.H" ************/
/*******************************************************************************/
/**********************        注意事项: 内部时钟频率12.000MHZ  ************************/
/*******************************************************************************/
#ifndef __STC_EEPROM_H__
        #define __STC_EEPROM_H__
/*-----------------------------------------------------------------------------*/
/*                                 加载用到的头文件                             */
/*-----------------------------------------------------------------------------*/
        #ifndef __INTRINS_H__
                #include <INTRINS.H>                                 //加载系统应用头文件INTRINS.H
        #endif
       
        #ifndef __STC15W408AS_H__
                #include "STC15W408AS.H"                             //加载STC单片机STC15W408AS专用头文件
        #endif

/*-----------------------------------------------------------------------------*/
/*                                 数据类型缩写定义                             */
/*-----------------------------------------------------------------------------*/
        #ifndef _DATA_TYPE_ABBREVIATIONS_                            //如果没有宏定义“数据类型缩写”标示将进行“_DATA_TYPE_ABBREVIATIONS_”标示宏定义
                #define _DATA_TYPE_ABBREVIATIONS_                    //宏定义“_DATA_TYPE_ABBREVIATIONS_”标示
                #define int8    signed char                          //重定义8位字符型数据类型为:int8(-128~127)
                #define int16   signed short int                     //重定义16位短整数型数据类型为:int16(-32768~32767)
                #define int32   signed long int                      //重定义32位长整数型数据类型为:int32(-2147483648~2147483647)
                #define int64   signed long long int                 //重定义64位超级整数型数据类型为:int64(-xxx~xxx)
                #define uint8   unsigned char                        //重定义8位正字符型数据类型为:uint8(0~255)
                #define uint16  unsigned short int                   //重定义16位正短整数型数据类型为:uint16(0~65535)
                #define uint32  unsigned long int                    //重定义32位正长整型数据类型为:uint32(0~4294967295)
                #define uint64  unsigned long long int               //重定义64位正超级整数型数据类型为:uint64(0~xxxx)
                #define float32 float                                //重定义浮点小数数据类型为:float32(3.4e-38~3.4e38)
                #define float64 double                               //重定义双精度浮点小数数据类型为:float64(1.7e-308~1.7e308)
                #define TRUE    1                                    //宏定义真常量
                #define FALSE   0                                    //宏定义假常量
        #endif

/*-----------------------------------------------------------------------------*/
/*                     声明SFR类型寄存器地址与IAP的关系                         */
/*-----------------------------------------------------------------------------*/

        //sfr IAP_DATA  = 0xC2;                                      //Flash数据寄存器
        //sfr IAP_ADDRH = 0xC3;                                      //Flash寄存器高八位地址
        //sfr IAP_ADDRL = 0xC4;                                      //Flash寄存器低八位地址
        //sfr IAP_CMD   = 0xC5;                                      //Flash读写操作控制命令寄存器
        //sfr IAP_TRIG  = 0xC6;                                      //Flash触发命令寄存器
        //sfr IAP_CONTR = 0xC7;                                      //Flash控制寄存器

/*-----------------------------------------------------------------------------*/
/*                          定义可全局调用的常量                                */
/*-----------------------------------------------------------------------------*/               
        //声明 ISP/IAP/EEPROM 读写操作寄存器IAP_CMD常量值
        #define CMD_IDLE    0                                        //待机模式无操作
        #define CMD_READ    1                                        //从用户的应用程序区对"Data Flash/EEPROM"区进行字节读操作
        #define CMD_PROGRAM 2                                        //从用户的应用程序区对"Data Flash/EEPROM"区进行字节编程操作
        #define CMD_ERASE   3                                        //从用户的应用程序区对"Data Flash/EEPROM"区进行扇区擦除操作
       
        //声明 ISP/IAP/EEPROM 各扇区起始地址常量
        #define IAP_ADDRESS_A 0x0000                                 //声明STC89C58xx EEPROM 第一扇区起始地址常量
        #define IAP_ADDRESS_B 0x0200                                 //声明STC89C58xx EEPROM 第二扇区起始地址常量
       
        //声明 ISP/IAP/EEPROM CPU实际运行的系统时钟频率常量值标示
        #ifndef _SYSclk_
                #define _SYSclk_ 12000000                            //宏定义CPU实际运行的系统时钟频率(单位:Hz,根据时钟频率修改,EEPROM模块使用)
        #endif
       
        //声明 ISP/IAP/EEPROM 控制寄存器IAP_CONTR常量值
        #if (24000000 <= _SYSclk_)
                #define ENABLE_IAP 0x80                              //如果 24MHz <= SYSCLK < 30MHz
        #elif (20000000 <= _SYSclk_)
                #define ENABLE_IAP 0x81                              //如果 20MHz <= SYSCLK < 24MHz
        #elif (12000000 <= _SYSclk_)
                #define ENABLE_IAP 0x82                              //如果 12MHz <= SYSCLK < 20MHz
        #elif ( 6000000 <= _SYSclk_)
                #define ENABLE_IAP 0x83                              //如果 6 MHz <= SYSCLK < 12MHz
        #elif ( 3000000 <= _SYSclk_)
                #define ENABLE_IAP 0x84                              //如果 3 MHz <= SYSCLK < 6 MHz
        #elif ( 2000000 <= _SYSclk_)
                #define ENABLE_IAP 0x85                              //如果 2 MHz <= SYSCLK < 3 MHz
        #elif ( 1000000 <= _SYSclk_)
                #define ENABLE_IAP 0x86                              //如果 1 MHz <= SYSCLK < 2 MHz
        #else
                #define ENABLE_IAP 0x87                              //如果 1 KHz <= SYSCLK < 1 MHz
        #endif

/*-----------------------------------------------------------------------------*/
/*                          声明可全局调用的变量                                */
/*-----------------------------------------------------------------------------*/


/*-----------------------------------------------------------------------------*/
/*                          声明可全局调用的函数                                */
/*-----------------------------------------------------------------------------*/
        /*******************************************************************************
        * 函数名称: Iap_Idle(void)
        * 函数功能: 置寄存器状态为闲置函数
        * 函数输入: 无
        * 函数输出: 无
        * 函数说明:
        *******************************************************************************/
        extern void Iap_Idle(void)
        {
                IAP_CONTR = 0;          //Flash控制寄存器清空,禁止ISP/IAP操作
                IAP_CMD   = 0;          //Flash读写操作控制命令寄存器,去除ISP/IAP命令
                IAP_TRIG  = 0;          //Flash触发命令寄存器,防止ISP/IAP命令误触发
                IAP_ADDRH = 0xFF;       //Flash地址寄存器高八位,指向非EEPROM区,防止误操作
                IAP_ADDRL = 0xFF;       //Flash地址寄存器低八位,指向非EEPROM区,防止误操作
        }
       
        /*******************************************************************************
        * 函数名称: uint8 Iap_Read_Byte(uint16 addr)
        * 函数功能: 读取相应地址处字节函数
        * 函数输入: 有  addr = 字节位置
        * 函数输出: 有  返回字节内容
        * 函数说明:
        *******************************************************************************/
        extern uint8 Iap_Read_Byte(uint16 addr)
        {
                uint8 dat;
               
                IAP_CONTR = ENABLE_IAP; //设置等待时间
                IAP_CMD   = CMD_READ;   //设置操作控制为读取命令
                IAP_ADDRL = addr;       //设置要读操作的高位地址
                IAP_ADDRH = addr >> 8;  //设置要读操作的低位地址
                IAP_TRIG  = 0x5A;       //
                IAP_TRIG  = 0xA5;       //
                _nop_();                //
                dat       = IAP_DATA;   //读出地址处的数据
                Iap_Idle();             //置寄存器状态为闲置
                return dat;             //返回值
        }
       
        /*******************************************************************************
        * 函数名称: Iap_Program_Byte(uint16 addr,uint8 dat)
        * 函数功能: 写入程序字节函数
        * 函数输入: 有  addr = 要写入数据的位置  dat = 要写入的数据内容
        * 函数输出: 无
        * 函数说明:
        *******************************************************************************/
        extern void Iap_Program_Byte(uint16 addr,uint8 dat)
        {
                IAP_CONTR = ENABLE_IAP;  //设置允许操作FLASH等待时间
                IAP_CMD   = CMD_PROGRAM; //设置操作控制为写入命令
                IAP_ADDRL = addr;        //设置要写入操作的高位地址
                IAP_ADDRH = addr >> 8;   //设置要写入操作的低位地址
                IAP_DATA  = dat;         //写入数据
                IAP_TRIG  = 0x5A;        //
                IAP_TRIG  = 0xA5;        //
                _nop_();                 //
                Iap_Idle();              //置寄存器状态为闲置函数
        }
       
        /*******************************************************************************
        * 函数名称: Eeprom_Delete_Sector(uint16 addr)
        * 函数功能: 擦除EEPROM扇区函数
        * 函数输入: 有  addr = 要删除扇区的初始地址
        * 函数输出: 无
        * 函数说明:
        *******************************************************************************/
        extern void Eeprom_Delete_Sector(uint16 addr)
        {
                IAP_CONTR = ENABLE_IAP;  //设置等待时间
                IAP_CMD   = CMD_ERASE;   //设置操作控制为擦除扇区命令
                IAP_ADDRL = addr;        //设置要写入操作的高位地址
                IAP_ADDRH = addr >> 8;   //设置要写入操作的低位地址
                IAP_TRIG  = 0x5A;        //
                IAP_TRIG  = 0xA5;        //
                _nop_();                 //
                Iap_Idle();              //置寄存器状态为闲置函数
        }

        /*******************************************************************************
        * 函数名称: Eeprom_Read_All(bit s,uint8 *dat,uint16 z)
        * 函数功能: 读取EEPROM扇区内全部数据的函数
        * 函数输入: 有  s = 扇区号(0为一扇区;1为二扇区) *dat = 数据数组指针  z = 数组长度
        * 函数输出: 无
        * 函数说明:
        *******************************************************************************/
        extern void Eeprom_Read_All(bit s,uint8 *dat,uint16 z)
        {
                uint8 i,y;
                uint16 x;
               
                if (s == 0)
                {
                        for (i=0;i<z;i++)
                        {
                                x = IAP_ADDRESS_A + i;
                                y = Iap_Read_Byte(x);
                                if (y == 0xFF) dat[i] = 0x00;
                                dat[i] = y;       
                        }
                }
                else
                {
                        for (i=0;i<z;i++)
                        {
                                x = IAP_ADDRESS_B + i;
                                y = Iap_Read_Byte(x);
                                if (y == 0xFF) dat[i] = 0x00;
                                dat[i] = y;       
                        }
                }
        }

        /*******************************************************************************
        * 函数名称: Save_All_Data(bit s,uint8 *dat,uint16 n)
        * 函数功能: 存储全部参数函数
        * 函数输入: 有  s = 扇区号(0为一扇区;1为二扇区) *dat = 数据数组指针 n = 数组长度
        * 函数输出: 有  0->失败  1->成功
        * 函数说明:
        *******************************************************************************/
        extern bit Save_All_Data(bit s,uint8 *dat,uint16 n)
        {
                uint16 i,x;
               
                if (s == 0)
                {
                        EA = 0;                                                   //禁止中断
                        Eeprom_Delete_Sector(IAP_ADDRESS_A);                      //擦除第一扇区全部数据
                       
                        for (i=0;i<512;i++)
                        {
                                if (Iap_Read_Byte(IAP_ADDRESS_A + i) != 0xFF)     //检测扇区中每个地址位的数据是否被擦除
                                {
                                        EA = 1;                                   //重新允许中断
                                        return FALSE;                             //如果第一扇区数据未真正擦除返回错误信息
                                }
                        }
                       
                        for (i=0;i<n;i++)
                        {
                                        x = IAP_ADDRESS_A + i;
                                        Iap_Program_Byte(x,dat[i]);
                        }
                       
                        EA = 1;                                                   //重新允许中断
                        return TRUE;                                              //正确存储数据后返回1
                }
                else
                {
                        EA = 0;                                                   //禁止中断
                        Eeprom_Delete_Sector(IAP_ADDRESS_B);                      //擦除第二扇区全部数据
                       
                        for (i=0;i<512;i++)
                        {
                                if (Iap_Read_Byte(IAP_ADDRESS_B + i) != 0xFF)
                                {
                                        EA = 1;                                   //重新允许中断
                                        return FALSE;                             //如果第二扇区数据未真正擦除返回错误信息
                                }
                        }
                       
                        for (i=0;i<n;i++)
                        {
                                        x = IAP_ADDRESS_B + i;
                                        Iap_Program_Byte(x,dat[i]);
                        }
                       
                        EA = 1;                                                   //重新允许中断
                        return TRUE;
                }
        }       
       
/*******************************************************************************/
#endif
/*******************************************************************************/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

粉丝