📄 s51.c
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////
//FID=02:AT89S51系列编程器
//实现编程的读,写,擦等细节
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <iom8v.h>
#include <macros.h>
#include<signal.h>
#include<e51pro.h>
#define uchar unsigned char
BYTE OutBuf[4];//发送命令缓冲
BYTE InBuf[4];//接收缓冲
void SendInstrc(uchar nByte)//用MOSI串行发送命令的同时用MISO接收相关数据
{
uchar n=0;
DDRB=(1<<PB5)|(1<<PB3)|(1<<PB2);
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);//SCK时钟为fosc/16
for (n=0;n<nByte;n++)
{
SPDR=OutBuf[n];
while (!(SPSR&(1<<SPIF)))
;
InBuf[n]=SPDR;
}
}
void InitPro02()//编程前的准备工作
{
DDRB=0xff;
PORTB&=~BIT(PB2);
Delay_ms(10);
PORTB|=BIT(PB2);
PORTC|=BIT(PB1);
PORTC&=~BIT(PB0);
Delay_ms(10);
nAddress=0x0000;
OutBuf[0]=0xac;//正好在这里可以安排DataSheet上所规定的
OutBuf[1]=0x53;//Eanable Programming命令
OutBuf[2]=0;
OutBuf[3]=0;
SendInstrc(4);
}
void ProOver02()//编程结束后的工作,设置合适的引脚电平
{
PORTC|=BIT(PB0);
PORTC&=~BIT(PB1);
DDRB=0x00;
}
uchar ComBuf[18];
uchar Read02()
{
OutBuf[0]=0x20;
OutBuf[1]=((uchar*)&nAddress)[1];
OutBuf[2]=((uchar*)&nAddress)[0];
SendInstrc(4);
return InBuf[3];
}
void ReadSign02()//读特征字
{
InitPro02();//先设置成编程状态
//-----------------------------------------------------------------------------
//根据器件的DataSheet,设置相应的编程控制信号
OutBuf[0]=0x28;
OutBuf[1]=0x00;
OutBuf[2]=0x00;
OutBuf[3]=0x00;
SendInstrc(4);
ComBuf[2]=InBuf[3];
OutBuf[1]=0x01;
SendInstrc(4);
ComBuf[3]=InBuf[3];
OutBuf[1]=0x02;
SendInstrc(4);
ComBuf[4]=InBuf[3];
//-----------------------------------------------------------------------------
ProOver02();
}
void Erase02()//擦除器件
{
InitPro02();
//-----------------------------------------------------------------------------
//根据器件的DataSheet,设置相应的编程控制信号
OutBuf[0]=0xac;
OutBuf[1]=0x80;
SendInstrc(4);
Delay_ms(50);
//-----------------------------------------------------------------------------
ProOver02();
}
BOOL Write02(BYTE Data)//写器件
{
//-----------------------------------------------------------------------------
//根据器件的DataSheet,设置相应的编程控制信号
//写一个单元
OutBuf[0]=0x40;
OutBuf[1]=((BYTE*)&nAddress)[1];
OutBuf[2]=((BYTE*)&nAddress)[0];
OutBuf[3]=Data;
SendInstrc(4);
nTimeOut=0;
while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同
{
nTimeOut++;
if(nTimeOut>1000)//超时了
{
return 0;
}
}
//-----------------------------------------------------------------------------
return 1;
}
void Lock02()//写锁定位
{
//-----------------------------------------------------------------------------
//根据器件的DataSheet,设置相应的编程控制信号
if(ComBuf[2]>=1)//ComBuf[2]为锁定位
{
InitPro02();
OutBuf[0]=0xac;
OutBuf[1]=0xe1;
SendInstrc(4);
Delay_ms(1);
}
if(ComBuf[2]>=2)
{
InitPro02();
OutBuf[0]=0xac;
OutBuf[1]=0xe2;
SendInstrc(4);
Delay_ms(1);
}
if(ComBuf[2]==3)
{
InitPro02();
OutBuf[0]=0xac;
OutBuf[1]=0xe3;
SendInstrc(4);
Delay_ms(1);
}
//-----------------------------------------------------------------------------
ProOver02();
}
void PreparePro02()//设置pw中的函数指针,让主程序可以调用上面的函数
{
pw.fpInitPro=InitPro02;
pw.fpReadSign=ReadSign02;
pw.fpErase=Erase02;
pw.fpWrite=Write02;
pw.fpRead=Read02;
pw.fpLock=Lock02;
pw.fpProOver=ProOver02;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -