关于STC89C52RC 单片机EEPROM的例程
本人比较笨搞了两天终于调出来一点,分享给大家 以方便学习之用 #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;
}
#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
#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--;
}
不错,赞一个。 不晓得宏晶官网上是否有 , 不用谢谢分享 。 不錯 支持一下! 问几个问题哈:
1、延时只用NOP就够用?擦除都要10ms吧?
2、AT89X52.H头文件内有ISP定义么?
页:
[1]