找回密码
 立即注册
查看: 524|回复: 3

AI8H2K12U EEPROM 程序

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:585
  • 最近打卡:2025-10-16 07:20:54
已绑定手机

86

主题

6279

回帖

1万

积分

超级版主

积分
11748
发表于 2025-5-23 14:39:43 | 显示全部楼层 |阅读模式
  1. #include <absacc.h>
  2. #define                IAP_TPS_        24                //等待参数
  3. #define                IAP_OFFSET        0x2E00        //EEPROM地址
  4. void Iap_Idle(void)
  5. {
  6.         IAP_CONTR&=~IAPEN;
  7.         IAP_CMD=IAP_IDL;
  8.         IAP_TRIG=0x00;
  9.         IAP_ADDRH=0x80;
  10.         IAP_ADDRL=0x00;
  11. }
  12. unsigned char Iap_Read_Byte(unsigned char sector,unsigned int addr)
  13. {
  14.         return *(CBYTE+IAP_OFFSET+sector*0x0200+addr);
  15. }
  16. //unsigned char Iap_Read_Byte(unsigned char sector,unsigned int addr)
  17. //{
  18. //        unsigned char dat;
  19. //        unsigned int add;
  20. //        add=sector*0x0200+addr;
  21. //        IAP_CONTR|=IAPEN;
  22. //        IAP_TPS=IAP_TPS_;
  23. //        IAP_CMD=IAP_READ;
  24. //        IAP_ADDRL=add;
  25. //        IAP_ADDRH=add>>8;
  26. //        IAP_TRIG=0x5A;
  27. //        IAP_TRIG=0xA5;
  28. //        _nop_();
  29. //        dat=IAP_DATA;
  30. //        Iap_Idle();
  31. //        return dat;
  32. //}
  33. void Iap_Program_Byte(unsigned char sector,unsigned int addr,unsigned char dat)
  34. {
  35.         unsigned int add;
  36.         add=sector*0x0200+addr;
  37.         IAP_CONTR|=IAPEN;
  38.         IAP_TPS=IAP_TPS_;
  39.         IAP_CMD=IAP_WRITE;
  40.         IAP_ADDRL=add;
  41.         IAP_ADDRH=add>>8;
  42.         IAP_DATA=dat;
  43.         IAP_TRIG=0x5A;
  44.         IAP_TRIG=0xA5;
  45.         _nop_();
  46.         Iap_Idle();
  47. }
  48. void Iap_Erase_Sector(unsigned char sector)
  49. {
  50.         unsigned int add;
  51.         add=sector*0x0200;
  52.         IAP_CONTR|=IAPEN;
  53.         IAP_TPS=IAP_TPS_;
  54.         IAP_CMD=IAP_ERASE;
  55.         IAP_ADDRL=add;
  56.         IAP_ADDRH=add>>8;
  57.         IAP_TRIG=0x5A;
  58.         IAP_TRIG=0xA5;
  59.         _nop_();
  60.         Iap_Idle();
  61. }
复制代码


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:209
  • 最近打卡:2025-10-16 08:03:21

787

主题

1万

回帖

1万

积分

管理员

积分
19784
发表于 2025-5-23 21:26:30 | 显示全部楼层
烧录时要选择 EEPROM 的大小
截图202505232126265963.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:539
  • 最近打卡:2025-10-15 21:55:03

33

主题

2600

回帖

5729

积分

论坛元老

积分
5729
发表于 2025-5-24 09:17:58 | 显示全部楼层
其实之前有想过直接使用MOVC的方式读取EEPROM的数据,但是目前来看,这种方式不具有普适性。因为EEPROM的大小是可以设置的,而且好像手册中页没有说明可以通过什么寄存器读取这个设置的EEPROM大小或者关于EEPROM的起始位置之类的(如果存在的,记得回来踢我一脚)。。如果调试人员对EEPROM的配置修改了,和程序里面的宏定义不匹配极可能会导致程序出现问题,增加调试成本。。

最后就还是选择了IAP的方式读取EEPROM数据,这样把无论设置EEPROM的大小是多少,只要是够用,就都能正确读取
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-09-23 00:23:35
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 2025-9-22 01:28:13 | 显示全部楼层
请教下,AI8H2K12U的EEPROM地址0x0000和其它地址是否有区别,目前发现0x0000程序中无法正常写入读取,换成其它地址就一切正常,在主程序开始前做写入和读取操作测试又正常
#include <AI8H.H>
#include "Delay.h"
#include "STC8H_PWM.h"
#include "INT0and1.h"               
#include "STC8_EEPROM.h"

#define PWM6_E  0x0001  //PWM6档位的EEPROM存储地址(0x0000无法使用原因不明)


u8 Key1;            //档位变量
u8 PWM6_MOD;        //PWM6初始占空比
bit PWM6_KG = 0;    //PWM6开关状态
bit PWM6_UP = 0;    //PWM6更新标识位
bit EEPROM_UP = 0;  //EEPROM更新标识位


void main()
{
    INT0and1_Init();                //外部中断初始化,一定要加在main主程序前
    STC8H_PWM_Init();               //初始化硬件PWM
    P3M0 &= ~0x0c; P3M1 &= ~0x0c;   //P32/33设为准双向口
   
//    IapEraseSector(IAP_ADDRESS1);   //擦除第1扇区(写入地址所在扇区)
//    IapProgramByte(0x0000,5);       //在地址0x00F1写入Key1的值
//    switch(IapReadByte(0x0000))     //读取EEPROM数据
    switch(IapReadByte(PWM6_E))     //读取EEPROM数据
    {
        case 2:Key1 = 2;PWM6_MOD = 40;break;
        case 3:Key1 = 3;PWM6_MOD = 50;break;
        case 4:Key1 = 4;PWM6_MOD = 60;break;
        case 5:Key1 = 5;PWM6_MOD = 70;break;
        case 6:Key1 = 6;PWM6_MOD = 80;break;
        case 7:Key1 = 7;PWM6_MOD = 90;break;
        case 8:Key1 = 8;PWM6_MOD = 100;break;
        default:Key1 = 1;PWM6_MOD = 30;break;
    }
        
    while (1)
    {
        if(PWM6_UP)
        {
            PWM6_UP = 0;//清除更新标识位
            
            if(PWM6_KG)//判断开关状态
            {
                PWM_Set(6,PWM6_MOD);
            }else
            {
                PWM_Set(6,0);
            }
        }
        if(EEPROM_UP)
        {
            EEPROM_UP = 0;                  //清除更新标识位
            IapEraseSector(IAP_ADDRESS1);   //擦除第1扇区(写入地址所在扇区)
            IapProgramByte(PWM6_E,Key1);    //在地址0x00F1写入Key1的值
        }
    }
}


void INT_0(void) interrupt 0                                //外部中断P32接口
{
    Delay(50);//延时消抖
    if(P32 == 0)
    {
        while(P32==0);      //松手检测
        PWM6_KG = ~PWM6_KG; //翻转开关状态
        PWM6_UP = 1;        //开启PWM6更新
    }
}

void INT_1(void) interrupt 2                                //外部中断P33接口
{
    Delay(50);//延时消抖
    if(P33==0)
    {
        while(P33 == 0);//松手检测
        Key1++;
        EEPROM_UP = 1;//开启EEPROM更新
        switch(Key1)//判断档位
        {
            case 2:PWM6_MOD = 40;break;
            case 3:PWM6_MOD = 50;break;
            case 4:PWM6_MOD = 60;break;
            case 5:PWM6_MOD = 70;break;
            case 6:PWM6_MOD = 80;break;
            case 7:PWM6_MOD = 90;break;
            case 8:PWM6_MOD = 100;break;
            default:Key1 = 1;PWM6_MOD = 30;break;
        }
        if(PWM6_KG) //如果PWM6开启,则开启PWM6更新
        {
            PWM6_UP = 1;
        }
    }
}
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-17 01:22 , Processed in 0.156426 second(s), 64 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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