自学51中,用到了93c46。网上公布的93c46驱动程序不多,找大神的程序修修改改,希望帮到初学者。
/*/-------------主程序93c46main--举例--------------------
/*/-------------主程序93c46main----------------------
cwei(1); //16位存储模式
// cwei(0); 8位存储模式
En_93C46(); //写入允许
EE_93C46(); //擦除93C46所有数据函数
for(ia=0;ia<10;ia++) //从0地址开始写入10个数据
{
W93c46Data(ia,datacode16[ia]); //写93C46(地址,数据)函数
}
for(ia=0;ia<10;ia++)
{
num= Read93c46(ia); //读93C46(地址,数据)函数 */
//*****************************************************************/
//=================93c46.h====================
#ifndef __93C46_H__
#define __93C46_H__
//extern org;
// sbit OG=P1^7;//存储结构选择
//sbit org=P1^0;
//bit org;
void En_93C46(void); //写入允许
void W93c46pc_addr(unsigned char opcode,unsigned char addr); //合并操作码和地址写入
void E_93C46(unsigned char eraseaddr); //擦除93C46某地址数据函数
void EE_93C46(void); //擦除93C46所有数据函数
void W93c46Data(unsigned char waddr,unsigned int wdata); //写93C46(地址,数据)函数
unsigned int Read93c46(unsigned int raddr); //读93C46(地址,数据)函数
void cwei(unsigned char idata ww); //数据结构设置,0=8位存储结构,1=16位存储结构
#endif
//============子程序93c46.c====================
#include <reg52.h>
#include "delay.h"
#include "93c46.h"
sbit CS=P1^7;//片选,高电平有效
sbit SK=P1^6;//时钟a
sbit DI=P1^5;//数据输入
sbit DO=P1^4;//数据输出
//sbit org=P1^3;
bit org; //extern org;//存储结构选择
#define uchar unsigned char
#define uint unsigned int
unsigned int raddr;
void En_93C46(void); //写入允许
void W93c46pc_addr(uchar opcode,uchar addr); //合并操作码和地址写入
void E_93C46(uchar eraseaddr);//擦除93C46某地址数据函数
void EE_93C46(void); //擦除93C46所有数据函数
void W93c46Data(uchar waddr,uint wdata); //写93C46(地址,数据)函数
unsigned int Read93c46 (unsigned int raddr); //读93C46(地址,数据)函数
void cwei(unsigned char idata ww) //数据结构设置,0=8位存储结构,1=16位存储结构
{org=ww;}
//--------------93C46写使能函数--------------------------------------
void En_93C46(void) //93C46写使能函数:
{ uchar wad=0x60; //8位结构地址码01100000
if (org==1)
wad=0X30; //16位结构地址码110000
CS=1;//选通
W93c46pc_addr(0x04,wad);//使能写允许100 ,110000
CS=0;//选通禁止
}
//----------------------------------------------------------------------
//------------擦除93C46某地址数据函数--------------------------------
void E_93C46(unsigned char eraseaddr)//擦除93C46某地址数据函数
{
if(org==1)
eraseaddr= eraseaddr&0x3f; //16位结构擦除地址xxxxxx
CS=1;//选通
W93c46pc_addr(0x07,eraseaddr);//操作码1000 ,擦除地址xxxxxxx
CS=0;//选通禁止
CS=1;//选通
while(!DO);//等待擦除完成
CS=0;
}
//-------------------------------------------------------------------------
//---------------擦除93C46所有数据函数-----------------------------
void EE_93C46(void) //擦除93C46所有数据函数
{
uchar wad=0x40; //8位结构擦除所有地址码 1000000
if (org==1)
wad=0X20; //16位结构擦除所有地址码 100000
CS=1;//选通
W93c46pc_addr(0x04,wad);//使能写允许100 ,110000
CS=0;//选通禁止
CS=1;//选通
while(!DO);//等待擦除完成
CS=0;
}
//-----------------------------------------------------------------------
//---------------合并操作码和地址写入----------------------------------
void W93c46pc_addr(unsigned char opcode,unsigned char addr) //合并操作码和地址写入
{
unsigned char i;
unsigned int temp;
uchar wt=7,wi=10; //OG=0表示8位结构 地址7位合成10位操作数
uint wd=0x0200;
if (org==1) //16
{
wt=6;wi=9;wd=0x0100; } //OG=1表示16位结构 地址6位合成9位操作数
temp=opcode; //操作码
temp=(temp<<wt)|addr; //把起始位、操作码和地址合成一个数置入int型数
for(i=0;i<wi;i++)
{
//注意:93C56/66芯片地址是9位,合并以后是一个12位的int型数据
DI=(temp&wd)?1:0; //OG=0从int型数据的第10位(0x0200)开始取数
SK=0;//产生时钟 //OG=1从int型数据的第9位(0x0100)开始取数
SK=1; //如果是12位数,从int型数据的第11位(0x0800)开始取数
temp<<=1;//取下一位
}
}
//---------------写93C46数据函数----------------------------------------
void W93c46Data(unsigned char waddr,unsigned int wdata) //写93C46(地址,数据)函数
{
uchar i, wi=16; //OG=1 16位结构
uint wd=0x8000; //
if (!org==1)
{ //8位结构
wi=8; wd=0x80;
wdata=wdata&0xff;
}
CS=1;//选通
W93c46pc_addr(0x05,waddr);//写入写操作码101和地址
for(i=0;i<wi;i++)//写入8位数据
{
DI=(wdata&wd)?1:0;//逐位写入
SK=0;//产生时钟
SK=1;
wdata<<=1;//取下一位
}
CS=0;//选通禁止
CS=1;
while(!DO);//等待写完
CS=0;
}
//-------------------------------------------------------------------------
//----------------读93C46(地址,数据)函数--------------------------------
unsigned int Read93c46(unsigned int raddr) //读93C46(地址,数据)函数
{
uchar i, wi=8; //OG=1 16位结构
uint rdata=0;
if (org==1)
{wi=16; } //8位结构
CS=1;
W93c46pc_addr(0x06,raddr);//写入写操作码110和地址
for(i=0;i<wi;i++)//读取8/16位数据
{
SK=0;//
SK=1;
rdata<<=1;//存下一位
if(DO==1)rdata|=0x01;//逐位读取数据并处理
else rdata&=(~0x01);
}
CS=0;//选通禁止
if (!org==1)
rdata=rdata&0x00ff;
return rdata;
}
//--------------------------------------------------------------------------------------
|