自學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;
}
//--------------------------------------------------------------------------------------
|