📄 main.c
字号:
#include <atmel\REG2051.H>
#include <INTRINS.H>
//引脚定义,可以自行定义使用
#define IC_P1 P1_1 //cs
#define IC_P2 P1_2 //sk
#define IC_P3 P1_3 //DI
#define IC_P4 P1_4 //DO
#define IC_P5 P1_5 //GND
#define IC_P6 P1_6 //nc
#define IC_P7 P1_7 //nc
#define LED P3_7 //VCC
/*这个需要改,因为25xx320指令不一样
#define EWEN 0x98
#define ERAL 0x90
#define EWDS 0x80 //93CXX用 0x98 EWEN写允许 0x80EWDS写禁止 0x90擦除
*/
#define EWEN 0x06 //0x06 WREN写允许 25XX用
//#define ERAL 0x90 //0x90擦除,25XX没有这个
#define EWDS 0x04 //0x04 WRDI写禁止
static unsigned char Pack[4]; //数据包数组
static unsigned char PN = 0; //接收指针
void InitCom(void); //串口初始化 晶振为11.0592M 方式1 波特率57600
//void InitIC(void);
void ComOutChar(unsigned char OutData); //向串口输出一个字符(非中断方式)
void Init_93C(void); //引脚初始化
void Read_93C(unsigned char AH,AL); //读
void Write_93C(unsigned char AH,AL,Data); //写
void COM_93C(unsigned char Data); //93C命令函数
void Erasure_93C(void); //擦除
void main(void)
{
unsigned int TempCyc;
InitCom();
while(1)
{
for (TempCyc=0; TempCyc<30000; TempCyc++) //状态灯闪
LED = 1;
for (TempCyc=0; TempCyc<20000; TempCyc++)
LED = 0;
}
}
//串口初始化 晶振为11.0592M 方式1 波特率57600
void InitCom(void)
{
SCON = 0x50; //串口方式1,允许接收
TMOD = 0x21; //定时器1定时方式2,定时0为模式1,16位模式
TCON = 0x40; //设定时器1开始计数
TH1 = 255; //设波特率为57600
TL1 = 255;
PCON = 0x80; //波特率加倍控制,SMOD位
RI = 0; //清收发标志
TI = 0;
TR1 = 1; //启动定时器
EA = 1; //开总中断
ES = 1; //开串口中断
}
//向串口输出一个字符(非中断方式)
void ComOutChar(unsigned char OutData)
{
SBUF = OutData; //输出字符
while(!TI); //空语句判断字符是否发完
TI = 0; //清TI
}
//串口接收中断
void ComInINT(void) interrupt 4
{
if (RI) //判断是不是收完字符
{
RI = 0; //RI清零
Pack[PN] = SBUF; //存数据
PN++; //指针加1
if (PN == 4)
{
PN = 0; //指针清零 一帧数据收完后
switch (Pack[0])
{
case 0: Read_93C(Pack[1],Pack[2]); break;
case 1: Write_93C(Pack[1],Pack[2],Pack[3]); break;
case 2: Erasure_93C(); break;
}
}
}
}
////////MicroWire 93CXX芯片函数////////////////
////////SPI 25XX320芯片函数////////////////
//引脚初始化
void Init_93C(void)
{
IC_P5 = 0; //GND
IC_P1 = 0; //CS
IC_P2 = 0; //SK
IC_P3 = 0; //DI
IC_P4 = 1; //DO 置1让MCU为可读
IC_P6 = 0; //选择为8位数据模式
IC_P7 = 0; //
}
//93C命令函数
void COM_93C(unsigned char Data)
{
unsigned char TempCyc;
unsigned int TempCycB;
TempCycB = Data; //Data: 0x98 EWEN写允许 0x80EWDS写禁止 0x90擦除
Init_93C(); //初始化引脚
IC_P1 = 1; //CS
// for(TempCyc=10; TempCyc!=0; TempCyc--) //94C64的8位模式起始位+命令代码+地址位是共10位
for(TempCyc=8; TempCyc!=0; TempCyc--) //25XX320 SI 数据
{
IC_P3 = Data & 0x80; //数据 DI
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //时钟 /SK
Data <<= 1; //左移
}
IC_P1 = 0; //CS
if (TempCycB==ERAL) //擦除命令
{
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //SK
IC_P1 = 1; //CS
_nop_();
for (TempCycB=0; TempCycB<0xFFFF; TempCycB++)
{
IC_P2 = 1;
_nop_();
_nop_();
IC_P2 = 0;
if (IC_P4)
{
break; //检测就绪信号
}
}
IC_P1 = 0;
if (TempCycB!=0)
ComOutChar(0); //成功返回0
else
ComOutChar(1); //失败返回1
}
}
//擦除
void Erasure_93C(void)
{
COM_93C(EWEN);
// COM_93C(ERAL);
Write_93C(0x00,0x00,0xFF);
COM_93C(EWDS);
}
//写
void Write_93C(unsigned char AH,AL,SData)
{
unsigned int Data=0, TempCycB;
COM_93C(EWEN); //写允许
Init_93C();
IC_P1 = 1; //CS
Data = AH*0x100+AL;
// Data = Data<<6; //地址组合、移动
// Data |= 0xA000; //加上起始位和操作码
for(TempCycB=16; TempCycB!=0; TempCycB--) //发送地址码
{
IC_P3 = Data & 0x8000; //数据 DI
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //时钟 /SK
Data <<= 1; //左移
}
Data = SData*0x100; //数据
for(TempCycB=8; TempCycB!=0; TempCycB--) //发送8位数据
{
IC_P3 = Data & 0x8000; //数据 DI
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //时钟 /SK
Data <<= 1; //左移
}
IC_P1 = 0; //CS
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //SK
IC_P1 = 1; //CS
_nop_();
for (TempCycB=0; TempCycB<0xFFFF; TempCycB++)
{
IC_P2 = 1;
_nop_();
_nop_();
IC_P2 = 0;
if (IC_P4)
{
break; //检测就绪信号
}
}
if (TempCycB!=0) //当TempCycB=0说明没有出现过BUY
ComOutChar(0); //成功返回
else
ComOutChar(1); //失败返回1
COM_93C(EWDS); //写禁止
}
//读
void Read_93C(unsigned char AH,AL)
{
unsigned char TempCycB;
unsigned int Data=0;
Init_93C();
IC_P1 = 1; //CS
Data = AH*0x100+AL;
// Data = Data<<6; //地址组合、移动
// Data |= 0xC000; //加上起始位和操作码
for(TempCycB=8; TempCycB!=0; TempCycB--) //地址码
{
IC_P3 = Data & 0x8000; //数据 DI
IC_P2 = 1; //SK
_nop_();
IC_P2 = 0; //时钟 /SK
Data <<= 1; //左移
}
for(TempCycB=0; TempCycB<8; TempCycB++) //读数据
{
IC_P2 = 1; //SK
_nop_();
_nop_();
Pack[3] = Pack[3] << 1;
if (IC_P4)
Pack[3]++;
IC_P2 = 0; //时钟 /SK1
}
IC_P1 = 0; //CS
ComOutChar(Pack[3]); //返回
}
void WIPCHK(void) //reentrant //检查WIP位,判断是否写入完成
{
unsigned char Temp,TempCyc;
for(TempCyc=0;TempCyc<50;TempCyc++)
{
Temp = RSDR(); //读状态寄存器
if (Temp&0x01==0)
TempCyc = 50;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -