学过51单片机的回过头来都会觉得51还是比较简单的,在此我将贴出在我的学习过程中,把对各种外设所进行的操作,封装成函数库的形式,以供新手学习。
注:使用的单片机是stc12c5a60s2,该系列单片机属于加强51,在运行速度上是普通51的8-12倍,有关时序的操作需要加以注意。
注2:使用示例:
void main()
{
unsigned int i;
unsigned char dataNum;
Delay(10);
IapEraseSector(IAP_ADDRESS); //擦除eeprom扇区,512字节
// for(i=0; i<512; i++)
// {
// if(IapReadByte(IAP_ADDRESS+i)!= 0xff) //是否擦除成功
// goto Error;
// }
// P1 = 0xfc;
// Delay(10);
for(i=0; i<512; i++)
{
IapProgramByte(IAP_ADDRESS+i, (unsigned char)i); //写入数据
}
// P1 = 0xf8;
// Delay(10);
// for(i=0; i<512; i++)
// {
// if(IapReadByte(IAP_ADDRESS+i)!=(unsigned char)i) //验证数据是否正确
// goto Error;
// }
// P1 = 0xf0;
// while(1);
// Error:
// P1 &= 0x7f;
// while(1);
dataNum = EepromReadByte(IAP_ADDRESS+2); //读取曾经写入的数据
while(1)
{
displayInteger(dataNum);
}
}
申明:本系列全部例程通过单片机开发板,实验亲测有效!
/* eeprom */
/*
*-------文档说明--------
*说明:eeprom.h文件实现了对stc12c5a60s2单片机内部eeprom的使用
*作者:Brunon
*创建日期:2017.5.5
*备注:根据stc12c5a60s2手册创建
*/
#include <reg52.h>
sfr IAP_DATA = 0xC2; //Flash data register
sfr IAP_ADDRH = 0xC3; //Flash address HIGH
sfr IAP_ADDRL = 0xC4; //Flash address LOW
sfr IAP_CMD = 0xC5; //Flash command register
sfr IAP_TRIG = 0xC6; //Flash command trigger
sfr IAP_CONTR = 0xC7; //Flash control register
#define CMD_IDLE 0 //Stand-By
#define CMD_READ 1 //Byte-Read
#define CMD_PROGRAM 2 //Byte-Program
#define CMD_ERASE 3 //Sector-Erase
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
//Start address for STC12C5A60S2 series EEPROM
#define IAP_ADDRESS 0x0000
#define USING_CHAR_NUM 11
void IapIdle()
{
IAP_CONTR = 0; //Close IAP function
IAP_CMD = 0; //Clear command to standby
IAP_TRIG = 0; //Clear trigger register
IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
IAP_ADDRL = 0; //Clear IAP address to prevent misuse
}
unsigned char IapReadByte(unsigned int addr)
{
unsigned char dat; //Data buffer
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _nop_(); //MCU will hold here until ISP/IAP/EEPROM
//operation complete
dat = IAP_DATA; //Read ISP/IAP/EEPROM data
IapIdle(); //Close ISP/IAP/EEPROM function
return dat; //Return Flash data
}
unsigned char EepromReadByte(unsigned char addr)
{
return(IapReadByte(addr));
}
void EepromWriteByte(unsigned char addr, unsigned char dat)
{
unsigned char eepromBUF[USING_CHAR_NUM];
unsigned char i;
for(i=0; i< USING_CHAR_NUM; i++)
{
eepromBUF[IAP_ADDRESS+i] = IapReadByte(IAP_ADDRESS+i);
}
if(addr < USING_CHAR_NUM)
{
eepromBUF[IAP_ADDRESS+addr] = dat;
IapEraseSector(IAP_ADDRESS);
for(i=0; i< USING_CHAR_NUM; i++)
{
IapProgramByte(IAP_ADDRESS+i, eepromBUF[IAP_ADDRESS+i]);
}
}
}
void IapProgramByte(unsigned int addr, unsigned char dat)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_DATA = dat; //Write ISP/IAP/EEPROM data
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _nop_(); //MCU will hold here until ISP/IAP/EEPROM
//operation complete
IapIdle();
}
void IapEraseSector(unsigned int addr)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _nop_(); //MCU will hold here until ISP/IAP/EEPROM
//operation complete
IapIdle();
}
void Delay(unsigned char n)
{
unsigned int x;
while(n--)
{
x=0;
while(++x);
}
}
这篇博客分享了作者在学习51单片机过程中,如何将外设操作封装为函数库,特别是针对EEPROM的部分。文章指出,使用的单片机型号为stc12c5a60s2,这是一款速度较快的增强型51单片机,需要注意时序问题。所有例程已在开发板上经过实际测试并验证有效。
1538

被折叠的 条评论
为什么被折叠?



