久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8542|回復: 7
打印 上一主題 下一主題
收起左側

STC8G單片機的片上EEPROM程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:162691 發表于 2021-3-20 16:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 407871699 于 2021-3-20 16:40 編輯

最近研究了STC8G的片上EEPROM,比片外ROM方便多了。
但剛開始使用STC官網下載的例程時候老報錯,還是不熟悉啊。
然后和官方的手冊上的例程比較:手冊提供了3個函數,寫1個字節函數void IapProgramByte(WORD addr, BYTE dat),讀1個字節函數BYTE IapReadByte(WORD addr),擦除扇區函數void IapEraseSector(WORD addr)。   手冊上這3個函數不方便與主函數進行數據交換,還要在編數據交換函數;因此結合手冊例程,把官網下載的EEPROM例程改動了一下,編成EEPROM.H,就可以直接調用
片上EEPROM寫入時,重點是必須先用扇區擦除,否則寫入的數值錯誤。

單片機源程序如下:
#include<STC8xxxx.h>      //建議到官網下載,則包含sfr IAP_TPS = 0xF5;
//sfr  IAP_TPS = 0xF5;         //這個是STC8新增的寄存器,按CPU頻率計算等待時間
#define  EEPROM_ADD_0  0x0000           //EROM ADDRESS  起始地址,大家可以根據需要改存儲位置,但是要符合MCU手冊
#define  MAIN_Fosc                11059200L        //定義MCU頻率;這句可以放在初始化配置中或主程序中
#define  IAP_EN          (1<<7)                   //啟動IAP;等價于IAP_EN=0X80;
#define  IAP_ENABLE()        IAP_CONTR = IAP_EN; IAP_TPS = MAIN_Fosc / 1000000   //使能+等待


void        DisableEEPROM(void)                //禁止IAP操作
{
        IAP_CONTR = 0;                //禁止IAP操作
        IAP_CMD   = 0;                //去除IAP命令
        IAP_TRIG  = 0;                //防止IAP命令誤觸發
        IAP_ADDRH = 0xff;        //清0地址高字節
        IAP_ADDRL = 0xff;        //清0地址低字節,指向非EEPROM區,防止誤操作
}


void EEPROM_Trig(void)   //觸發EEPROM
{
        F0 = EA;    //保存全局中斷
        EA = 0;     //禁止中斷, 避免觸發命令無效
        IAP_TRIG = 0x5A; //先送5AH,再送A5H到IAP觸發寄存器,每次都需要如此
        IAP_TRIG = 0xA5; //送完A5H后,IAP命令立即被觸發啟動//CPU等待IAP完成后,才會繼續執行程序。
        _nop_();        _nop_();     //2個空指令等待一下
        EA = F0;    //恢復全局中斷
}

// 參數: EE_address:  讀取EEPROM的首地址.
//       DataAddress: 讀取數據后給到 數組首地址.
//       number:      讀取的字節長度.
void EEPROM_read_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)      
{
IAP_ENABLE();             //設置等待時間,允許IAP操作,送一次就夠
IAP_CMD = 1;              //=1讀;送字節讀命令,命令不需改變時,不需重新送命令
do
  {
        IAP_ADDRH = EE_address / 256;  //送地址高字節(地址需要改變時才需重新送地址)
        IAP_ADDRL = EE_address % 256;       //送地址低字節
        EEPROM_Trig();                      //觸發EEPROM操作
        *DataAddress = IAP_DATA;            //讀出的數據送往
        EE_address++;
        DataAddress++;
  }while(--number);
DisableEEPROM();
}
void EEPROM_SectorErase(unsigned int EE_address)
{
        IAP_ENABLE();  //設置等待時間,允許IAP操作,送一次就夠
        IAP_CMD = 3;   //宏調用, =3,送扇區擦除命令,命令不需改變時,不需重新送命令
                        //只有扇區擦除,沒有字節擦除,512字節/扇區。
                        //扇區中任意一個字節地址都是扇區地址。
        IAP_ADDRH = EE_address / 256; //送扇區地址高字節(地址需要改變時才需重新送地址)
        IAP_ADDRL = EE_address % 256;  //送扇區地址低字節
        EEPROM_Trig();                 //觸發EEPROM操作
        DisableEEPROM();               //禁止EEPROM操作
}

// 參數: EE_address:  寫入EEPROM的首地址.
//       DataAddress: 寫入源數據的緩沖的首地址. 就是從數組讀取數據,
//       number:      寫入的字節長度.

void EEPROM_write_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)
{
        IAP_ENABLE();       //設置等待時間,允許IAP操作,送一次就夠
        IAP_CMD = 2;        //宏調用, =2,送字節寫命令
        do
        {
        IAP_ADDRH = EE_address / 256; //送地址高字節(地址需要改變時才需重新送地址)
        IAP_ADDRL = EE_address % 256;     //送地址低字節
        IAP_DATA  = *DataAddress;         //送數據到IAP_DATA,只有數據改變時才需重新送
        EEPROM_Trig();                    //觸發EEPROM操作
        EE_address++;                     //下一個地址
        DataAddress++;                    //下一個數據
        }while(--number);                   //直到結束
        DisableEEPROM();
}

調用舉例:(建議定義一個數組)
unsigned char ROM_num[6];        //存儲數據的數組,最后與EEPROM進行數據交換

EEPROM_read_n(EEPROM_ADD_0,ROM_num,6);          //讀取ROM信息到數組

void _write_ROM()      //編制專門的寫入函數
{
EEPROM_SectorErase(EEPROM_ADD_0);           //必須先擦除數據(由MCU自動,512字節被擦除),之后再寫入,才能寫正確
ROM_num[0]=test_1/256;                           //將4個測試數值分別給到臨時交換數組。
ROM_num[1]=test_1%256;
ROM_num[2]=test_2;                               //test_1、3是16位的數據(2個字節);
ROM_num[3]=test_3/256;
ROM_num[4]=test_3%256;
ROM_num[5]=test_4;                               //test_2、test_4是單字節數據(8位)
EEPROM_write_n(EEPROM_ADD_0,ROM_num,6);        //從數組寫如到ROM中
}



評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:162691 發表于 2021-3-20 17:01 | 只看該作者
自己頂一個
回復

使用道具 舉報

板凳
ID:250631 發表于 2021-3-23 23:39 | 只看該作者
我選用的是8h8k64u芯片,希望能用上。感謝樓主無私分享
回復

使用道具 舉報

地板
ID:307493 發表于 2024-1-23 17:37 | 只看該作者
為啥我 照著寫 沒有把數據保存住
回復

使用道具 舉報

5#
ID:771630 發表于 2024-1-24 22:34 | 只看該作者
qq378912453 發表于 2024-1-23 17:37
為啥我 照著寫 沒有把數據保存住

要加延時,靠他自動延時存不住數據
回復

使用道具 舉報

6#
ID:1149881 發表于 2025-6-30 12:29 | 只看該作者
XLinliY.Zhang 發表于 2024-1-24 22:34
要加延時,靠他自動延時存不住數據

在哪里延時啊,我卡在讀取數據那里了,debug運行不下去
回復

使用道具 舉報

7#
ID:996773 發表于 2025-7-15 09:00 | 只看該作者
發送A5之后不需要nop也能存,我也沒細看pdf有沒有這個延時,而且讀取可以直接movc,加上程序占用
的2000H地址就行
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产成人a亚洲精品 | a级片www| 337p日本欧洲亚洲大胆鲁鲁 | 91在线色视频| 亚洲国产成人精品女人久久久 | 一区二区三区在线免费观看视频 | 中文字幕韩在线第一页 | 天堂久| 精品久久久久久久久久久 | 亚洲 欧美 综合 | 91国产在线视频在线 | 欧美激情在线一区二区三区 | 操人网 | 国产精品成人一区二区 | 一区二区日本 | 精品日韩一区二区 | 另类a v| 久久久视| 亚洲天堂男人的天堂 | 午夜伦理影院 | 操操日| 九九亚洲精品 | 午夜国产在线 | 免费毛片网 | 国产伦精品一区二区三区高清 | 国产激情视频网站 | 国产精品成人一区二区 | 成人伊人网 | 精品国产一区二区三区久久久蜜月 | av在线免费观看网址 | 欧美精品tv | 一级黄色录像片子 | 91免费在线 | 亚洲黄色片免费观看 | 成人国产精品入口免费视频 | 亚洲一视频 | 亚洲一区二区三区四区五区午夜 | 日韩欧美在线一区二区 | 精品一区二区三区在线播放 | 欧美成人精品欧美一级 | 国精品一区二区 |