📄 93c46.c
字号:
/***********************************************************
实验名称:93C46的读写
程序说明:通过数码管显示,先将0到9这几个数据存进93C46,然后再依次读出来,实现EEPROM功能,断电之后,仍然可以再读出来,并显示出来。
作者:RF-X1开发板团队
日期:2008-07-30
***********************************************************/
#include <reg52.h>
sbit CS=P1^0;
sbit CLK=P1^1;
sbit DI=P1^2;
sbit DO=P1^3;
unsigned char data SendBuffer[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90};
/***************************************/
/* 延时子程序 */
/***************************************/
delay10ms()
{
unsigned i,j;
for(i=200;i>0;i--)
for(j=200;j>0;j--);
}
/********************************************************
**名称:Ewen(void)
**功能:擦除/写入允许指令 Write enable must precede all programming modes.
**输入:
**返回:
*******************************************************/
void Ewen(void) {
unsigned char temp,InData;
CS=0;
CLK=0;
CS=1;
InData=0x98; // 10011XXXX
for(temp=9;temp!=0;temp--)
{ // 9位的指令(当93c46选择为16结构时,93c46有7条9位的指令
DI=InData&0x80; // 将InData按位输入
CLK=1; CLK=0;
InData<<=1; //InData=InData<<1;
}
CS=0;
}
/********************************************************
**名称:Ewds(void)
**功能:禁止指令 Disables all programming instructions.
**输入:
**返回:
*******************************************************/
void Ewds(void) {
unsigned char temp,InData;
CS=0;
CLK=0;
CS=1;
InData=0x80; // 10000XXXX
for(temp=9;temp!=0;temp--)
{ // 9位的指令(当93c46选择为16结构时,93c46有7条9位的指令
DI=InData&0x80; // 将InData按位输入
CLK=1; CLK=0;
InData<<=1; //InData=InData<<1;
}
CS=0;
}
/********************************************************
**名称:unsigned int Read(unsigned char address)
**功能:Reads data stored in memory, at specified address.
将address后六位指向的在93C46中的地址的一个字节(16位)
读出来放入result中
**输入:address(xx xxxxxx后面六位起作用)
**返回:result
*******************************************************/
unsigned int Read(unsigned char address)
{
unsigned char temp;
unsigned int result;
Ewen();
CLK=0; DI=1; // 110 A5-A0
CS=0; CS=1;
CLK=1; CLK=0; // 先输入一个1
address=address&0x3f|0x80; // address变成10xxxxxx
for(temp=8;temp!=0;temp--) // 接下来连续输入8位(在93C46中的地址 指令形式 110 A5-A0)
{ // 8
DI=address&0x80;
CLK=1; CLK=0;
address<<=1;
}
DO=1;
for(temp=16;temp!=0;temp--) //读取16位的数据(一字节)
{ // 16
CLK=1; //在下降沿输出数据到DO
result=(result<<1)|DO; //将数据按位存入result中
CLK=0;
}
CS=0;
Ewds();
return(result);
}
/********************************************************
**名称:void Write(unsigned char address,unsigned int InData)
**功能:Writes memory location An - A0.
将InData写入address
**输入:unsigned char address,unsigned int InData
**返回:
*******************************************************/
void Write(unsigned char address,unsigned int InData)
{
unsigned char temp;
Ewen();
CLK=0; DI=1; // 101 A5-A0
CS=0; CS=1;
CLK=1; CLK=0; // 先输入一个1
address=address&0x3f|0x40; // address变成10xxxxxx
for(temp=8;temp!=0;temp--) // 接下来连续输入8位(在93C46中的地址 指令形式 101 A5-A0)
{ // 8
DI=address&0x80;
CLK=1; CLK=0;
address<<=1;
}
for(temp=16;temp!=0;temp--) // 写入16位的数据(一字节)
{ // 16
DI=InData&0x8000;
CLK=1; CLK=0; //上升沿
InData<<=1; //InData=InData<<1;
}
CS=0; DO=1;
CS=1; CLK=1; //CS不片选芯片(为0)的时间要大于Tcsmin
while(DO==0)
{ // busy test
CLK=0; CLK=1; //如果繁忙状态,则CLK=0,CS=1
}
CLK=0; CS=0; // 结束
Ewds();
}
/*
*/
/********************************************************
**名称:void Erase(unsigned char address)
**功能:Erase memory location An - A0.
擦除操作指令,将address的内容擦除
在不需要擦除时,将此函数注释
**输入:unsigned char address
**返回:
*******************************************************
void Erase(unsigned char address) {
unsigned char temp;
Ewen();
CLK=0; DI=1; // 111 A5-A0
CS=0; CS=1;
CLK=1; CLK=0; // 1
address|=0xc0;
for(temp=8;temp!=0;temp--) { // 8
DI=address&0x80;
CLK=1; CLK=0;
address<<=1;
}
CS=0; DO=1;
CS=1; CLK=1;
while(DO==0) {
CLK=0; CLK=1;
}
CLK=0; CS=0;
Ewds();
}
*/
/********************************************************
**名称:void Eral(void)
**功能:Erases all memory locations. Valid only at VCC = 4.5V to 5.5V.
全部擦除操作指令,93C46所有的内容擦除
在不需要擦除时,将此函数注释
**输入:
**返回:
*******************************************************
void Eral(void) {
unsigned char temp,InData;
Ewen();
CS=0;
CLK=0;
CS=1;
InData=0x90; // 10010XXXX
for(temp=9;temp!=0;temp--) { // 9
DI=InData&0x80;
CLK=1; CLK=0;
InData<<=1;
}
CS=0; DO=1;
CS=1; CLK=1;
while(DO==0) {
CLK=0; CLK=1;
}
CLK=0; CS=0;
Ewds();
}
/*
/********************************************************
// Writes all memory locations. Valid only at VCC = 4.5V to 5.5V.
*******************************************************
void Wral(unsigned int InData) {
unsigned char temp,address;
Ewen();
CS=0;
CLK=0;
CS=1;
address=0x88; // 10001XXXX
for(temp=9;temp!=0;temp--) { // 9
DI=address&0x80;
CLK=1; CLK=0;
address<<=1;
}
for(temp=16;temp!=0;temp--) { // 16
DI=InData&0x8000;
CLK=1; CLK=0;
InData<<=1;
}
CS=0; DO=1;
CS=1; CLK=1;
while(DO==0) {
CLK=0; CLK=1;
}
CLK=0; CS=0;
Ewds();
}
*/
/********************************************************
**名称:unsigned char ReadChar(unsigned char address)
**功能:address 为8位的地址,
address 为 x xxxxxx x
第一个x是没什么用的,中间六个xxxxxx是真正的地址
最后一个x是表示取一个字节(16位)中的高8位还是低8位(1为高8位,0为低8位?**输入:unsigned char address
**返回:(unsigned char)(Read(temp)) or (unsigned char)(Read(temp)>>8)
*******************************************************/
unsigned char ReadChar(unsigned char address)
{
unsigned char temp=address>>1;
if(address&0x01) //address的最后一位是否为1(xxxx xxx1)
return( (unsigned char)(Read(temp)>>8) ); //如果address的最后一位是1,则反回16位中的高8位
else
return( (unsigned char)(Read(temp)) ); //否则反回16位中的低8位
}
/********************************************************
**名称:void WriteChar(unsigned char address,unsigned char InData)
**功能:将InData 写入 address
address 为8位的地址,
address 为 x xxxxxx x
第一个x是没什么用的,中间六个xxxxxx是真正的地址
最后一个x是表示取一个字节(16位)中的高8位还是低8位(1为高8位,0为低8位?
**输入:unsigned char address,unsigned char InData
**返回:
*******************************************************/
void WriteChar(unsigned char address,unsigned char InData)
{
unsigned char temp=address>>1;
if(address&0x01) //address的最后一位是否为1(xxxx xxx1)
Write(
temp,( unsigned int)(Read(temp)&0x00ff|(InData<<8) )
); //如果address的最后一位是1,则写入16位中的高8位
else
Write(
temp,(unsigned int)( Read(temp)&0xff00|InData)
); //否则写入16位中的低8位
}
/********************************************************
**名称:void ReadString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
**功能:读多字节 将Number个字节写入 RamAddress为93C46中的地址 RomAddress为读出来后的数据存放区
在这个程序中没有用到,注释掉
**读93C46中RomAddress地址中的内容到CPU地址RamAddress中去
**输入:unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number
**返回:
*******************************************************/
void ReadString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
{
while(Number!=0) {
*RamAddress=ReadChar(RomAddress);
RamAddress++;
RomAddress++;
Number--;
}
}
/********************************************************
**名称:void WriteString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
**功能:写多字节
在这个程序中没用到,注释掉
**将CPU中RamAddress中的内容写到93C46RomAddress中去
**输入:unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number
**返回:
*******************************************************/
void WriteString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
{
unsigned int temp;
if(Number==0) return;
if(RomAddress&0x01)
{
WriteChar(RomAddress,*RamAddress);
RamAddress++;
RomAddress++;
Number--;
}
if(Number==0) return;
while(Number>>1)
{
temp=*RamAddress;
RamAddress++;
temp=temp|(*RamAddress)<<8;
RamAddress++;
Write(RomAddress>>1,temp);
RomAddress++;
RomAddress++;
Number--;
Number--;
}
if(Number) WriteChar(RomAddress,*RamAddress);
}
void main()
{
unsigned char i;
unsigned char temp[10];
// Eral();
WriteString(SendBuffer,0x46,10);
ReadString(temp,0x46,10);
while(1)
{
for(i=0;i<10;i++)
{
P2=0xf0; //4位全部选通
P0=temp[i]; //显示一样的数据
delay10ms();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -