maitreya 发表于 2013-4-24 00:37:46

关于STC89C52RC 单片机EEPROM的例程

本人比较笨搞了两天终于调出来一点,分享给大家 以方便学习之用

maitreya 发表于 2013-4-24 00:38:43

#include<AT89X52.H>
#include"eeprom.h"
#include<intrins.h>


#define ERROR   0
#define OK      1

//#define WAIT_TIME0x00    //mcu clock 40mhz
//#define WAIT_TIME0x01    //mcu clock 20mhz
#define WAIT_TIME0x02    //mcu clock 10mhz
//#define WAIT_TIME0x03    //mcu clock 5mhz


void ISP_EN(void)
{
EA = 0;               //关中断   
ISP_CONTR = ISP_CONTR & 0x18;      // 0001,1000
ISP_CONTR = ISP_CONTR | WAIT_TIME;
ISP_CONTR = ISP_CONTR | 0x80;      // 1000,0000
}

void ISP_DI(void)
{
ISP_CONTR = ISP_CONTR & 0x7f;   // 0111,1111
ISP_TRIG = 0x00;
EA   =   1;                  // 开中断
}

unsigned char Byte_read(unsigned int byte_addr)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD= ISP_CMD & 0xf8;         // 1111,1000
ISP_CMD= ISP_CMD | 0x01;          // 0000,0001字节读数据存储区
ISP_EN();
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
ISP_DI();
return (ISP_DATA);
}

void Sector_erase(unsigned int Sector_addr)
{
unsigned char addre;
addre   = (unsigned char)(Sector_addr >> 8);// 1111,1110,0000,0000; 取扇区地址
ISP_ADDRH = addre&0xfe;
ISP_ADDRL = 0x00;

ISP_CMD = ISP_CMD & 0xf8;       // 1111,1000
ISP_CMD = ISP_CMD | 0x03;       // 0000,0011扇区擦除数据存储区

ISP_EN();

ISP_TRIG = 0x46;               // 触发ISP_IAP命令
ISP_TRIG = 0xb9;            // 触发ISP_IAP命令
_nop_();
ISP_DI();
}

void Byte_program(unsigned int byte_addr, unsigned char DataBuf)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD= ISP_CMD & 0xf8;         // 1111,1000
ISP_CMD= ISP_CMD | 0x02;      // 0000,0010字节编程数据存储区
ISP_DATA = DataBuf;
ISP_EN();

ISP_TRIG = 0x46;               // 触发ISP_IAP命令
ISP_TRIG = 0xb9;               // 触发ISP_IAP命令
_nop_();
ISP_DI();
}

unsigned char ByteProgramVerify(unsigned int byte_addr, unsigned char DataBuf)
{
        ISP_ADDRH        =        (unsigned char)(byte_addr >> 8);
        ISP_ADDRL        =        (unsigned char)(byte_addr & 0x00ff);

        ISP_CMD                =        ISP_CMD        &        0xf8;      /* 1111,1000 */
        ISP_CMD                =        ISP_CMD        |        0x02;        /* 0000,0010 */
        ISP_DATA        =        DataBuf;

        ISP_EN();

        ISP_TRIG        =        0x46;
        ISP_TRIG        =        0xb9;
        _nop_();

        ISP_DATA        =        0x00;

        ISP_CMD                =        ISP_CMD        &        0xf8;      /* 1111,1000 */
        ISP_CMD                =        ISP_CMD        |        0x01;      /* 0000,0001 */

        ISP_TRIG        =        0x46;      /* 触发ISP_IAP命令 */
        ISP_TRIG        =        0xb9;      /* 触发ISP_IAP命令 */
        _nop_();

        ISP_DI();

        if(ISP_DATA        ==        DataBuf)
                return        OK;
        else
                return        ERROR;
}

maitreya 发表于 2013-4-24 00:39:09

#ifndef __EEPROM_H__
#define __EEPROM_H__

void delay_us(unsigned char i);
void ISP_EN(void);
void ISP_DI(void);
unsigned char Byte_read(unsigned int byte_addr);
void Sector_erase(unsigned int Sector_addr);
void Byte_program(unsigned int byte_addr, unsigned char DataBuf);
unsigned char ByteProgramVerify(unsigned int byte_addr, unsigned char DataBuf);




#endif

maitreya 发表于 2013-4-24 00:39:42

#include<AT89X52.H>
#include<intrins.h>
#include"eeprom.h"
#include <string.h>
#include <stdio.h>


#defineuint8_t unsigned char
#defineuint16_t unsigned int
#defineuint32_t unsigned long



volatile uint8_t sending;
unsigned char Rec_Data;
unsigned Rec_Data_Num;
uint16_t delay_time;
uint8_tRec_outimeNum = 0xff;
uint8_t Start_Counter = 0;
volatile int eeprom_data = 0;
uint8_t buff;
uint8_t verify_flag = 0;


//uint32_t Fclk = 24000000;
uint32_t Fclk = 22118400;
uint32_t BitRate = 9600;   //实际BITRATE = 9600*12//

void InitUART(void);
void InitTime0(void);
void Ser_ReceFun(void);
void Ser_Printf(void);
void UartPutChar(uint8_t d);
void Prints(uint8_t *pd);
void TI_Interrupt(void);
void RI_Interrupt(void);
void delay(unsigned int a);

void main(void)
{

InitUART();
InitTime0();

delay(65500);
eeprom_data = (int) Byte_read(0x2000);

Sector_erase(0x2000);
sprintf(buff,"this is %dth start\r\n",eeprom_data);
Prints(buff);
eeprom_data = eeprom_data+1;
// Byte_program(0x2000, eeprom_data);
if(ByteProgramVerify(0x2000, eeprom_data) == 1);
P2_7 = 1;

while(1)
{
   if(Rec_outimeNum == 0)
   {
    Prints(Rec_Data);
        Rec_outimeNum = 0xff;
        Start_Counter = 0;
        Rec_Data_Num = 0;
   }

}


}
void delay(uint16_t i)
{
for(i;i>0;i--) ;
}





void InitUART(void)
{


       TMOD&=0X0f;
       TMOD|=0X20;
       SCON=0X50;
       TH1=(256-Fclk/(BitRate*12*16*2));
       TL1=(256-Fclk/(BitRate*12*16*2));
//       PCON|=0X80;
       ES=1;
       TR1=1;
       REN=1;
       EA = 1;







}



void InitTime0(void)//10ms溢出一次
{
       TF0 = 0;
       ET0 = 1;
       TMOD &= 0xF0;
       TMOD |= 0x02;
       TH0=0;
       TL0=0;
       TR0 = 1;
}



void TimeInterrupt(void) interrupt 1
{
        TF0 = 0;
        TH0=0;
        TL0=0;
        Ser_ReceFun();
//delay_time--;

}




void UartInitInterrupt(void) interrupt 4
{
        if(RI)
        {
                RI_Interrupt();
        }
        else
        {
                TI_Interrupt();
        }
}




void UartPutChar(uint8_t d)
{
       SBUF = d;
       sending = 1;
       while(sending);
}

void Prints(uint8_t *pd)
{
        while((*pd)!='\0')
        {
                UartPutChar(*pd);
                pd++;
        }
}




voidRI_Interrupt(void)
{
        RI = 0;

        if(Rec_outimeNum )
        {
                Rec_Data = SBUF;
                Start_Counter = 1;
                Rec_outimeNum = 0xff;
        }

}


voidTI_Interrupt(void)
{
TI = 0;
sending = 0;

}

void Ser_ReceFun(void)
{
        if(Start_Counter)
                Rec_outimeNum--;

}

yanghongbb 发表于 2013-5-21 10:25:24

不错,赞一个。

1066950103 发表于 2013-6-20 23:50:54

不晓得宏晶官网上是否有 , 不用谢谢分享 。

clarkewayne 发表于 2013-6-22 12:07:53

不錯 支持一下!

br113 发表于 2013-10-16 11:13:49

问几个问题哈:
1、延时只用NOP就够用?擦除都要10ms吧?
2、AT89X52.H头文件内有ISP定义么?
页: [1]
查看完整版本: 关于STC89C52RC 单片机EEPROM的例程