⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 93c46.c

📁 SPI总线的学习――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 + -