📄 93c46.c
字号:
/*****************************************************************/
/* */
/*名称: 93C46读写程序 */
/*功能: 接收串口发来的数据,写到93C46里面 */
/* 再从93C46里读出刚写进的数据,由串口发出 */
/*难度等级: 高 */
/* 作者: 51kaifa */
/* 版权: http://www.51kaifa.com */
/*编写日期: 2006.05.21 */
/*****************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SK=P1^0;//SPI时钟线
sbit DI=P1^5;
sbit DO=P1^6;//SPI数据线
sbit LCK = P3^5;
bit receive;//接收标志
bit re_finish;//接收一串字符完成标志
sbit LED = P1^2;//LED指示灯
uchar i,buffer[8],cbuffer[8];//串口缓冲区
uchar sbuffer,number;//发送字符个数
uchar sendFINS ;//发送完成标志
uchar copyOK , cmd_numb ;//发送缓冲区填充完成
void send(void);
void vGet_Send(void);
void delay(unsigned int loop);
void ReadString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number);
void WriteString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number);
/*******************************系统初始化***********************/
void initial()
{ unsigned char j;
SCON=0x50; //串口工作方式1,允许接收
PCON=0x80; //波特率翻倍
TCON=0;
TMOD=0x26; //T1用于串口波特率控制
TL1=0xfa; //初始化T1,波特率为9600(晶振11.0592M)
TH1=0xfa;
TR1=1; //开定时器
EA=1; //开总中断
ES=1; //开串口中断
copyOK = 0; //缓冲区准备好标志清零
receive = 0; //接收标志清零
re_finish = 0; //接受完成标志清零
cmd_numb = 0; //接受计数器清零
LCK = 0;
P0 = 0xf7;//关闭所有指示灯
LCK = 1;
for(j=0; j<8; j++) //串口缓冲区清空
buffer[i] = 0xff; //table[18]为空显示
}
/******************************主函数**************************/
main()
{
initial();
while(1){
if(re_finish){//接收一串字符完成
re_finish = 0;
vGet_Send();
}
}
}
/*****************************保存和串口发送**************************/
void vGet_Send(void)
{ uchar i;
WriteString(buffer,0x10,6);//数据存放初始地址为0x10
delay(1000);
for(i=0;i<8;i++)
buffer[i] = 0x5f; //用0xff填充发送缓冲区
ReadString(buffer,0x10,6);//读数据
copyOK = 1; //置准备好标志
send(); //向串口发送
}
/*****************************串口发送***************************/
void send(void)//向串口发送字符串
{
if(copyOK) //串口准备好且缓冲区准备好
{
i = 0;
REN = 0; //发送过程中禁止接收数据
copyOK = 0; //清缓冲区准备好标志
SBUF = cbuffer[i++]; //发送字符串首字符
number = 7; //置发送计数器
}
else
return; //没准备好则返回
}
/***************************串口中断响应*************************/
void serial(void) interrupt 4//串口中断响应
{
if(RI)//为接收中断
{
RI=0; //清接收中断标志
LED = ~LED; //闪串口指示LED
sbuffer = SBUF; //读取串口缓冲区数据
if((sbuffer == 's') && (receive == 0)) //判断是否为数据头 ,是数据头则准备接收
{
receive = 1; //开始接收标志
cmd_numb = 0; //清接收计数器
re_finish = 0; //清接收完成标志
}
else if(sbuffer == 'e') //判断数据尾
{
re_finish = 1; //置接收完成标志
receive =0; //清接收标志
}
else if(receive){ //判断当前是否处于接收状态
cbuffer[cmd_numb++] = sbuffer; //当前字符送缓冲区
}
else //无效命令则返回
return;
}
else{
TI=0; //为单个字符发送完中断
if(!number) //字符串发送完
{ REN = 1; //允许接收
}
else{ //字符串未发送完
SBUF = cbuffer[i++]; //发送下一字符
number--; //发送字符数减一
}
}
}
/*****************************延时函数**************************/
void delay(unsigned int loop)
{ unsigned int i ; //loop 为执行空指令的次数,改变它可一改变延时时长
for(i=0;i<loop;i++);//循环执行空指令loop次,达到延时目的
}
// **************************允许写入****************************
void Ewen(void) {
unsigned char temp,InData;
LCK = 0;
P0 = 0xf6;
LCK = 1;//CS=0;
SK=0;
LCK = 0;
P0 = 0x40;
LCK = 1;//CS=1;
InData=0x98; // 10011XXXX
for(temp=9;temp!=0;temp--) { // 9
DI=InData&0x80;
SK=1; SK=0;//产生时钟
InData<<=1;
}
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
}
//****************************** 禁止写入************************
void Ewds(void) {
unsigned char temp,InData;
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
SK=0;
LCK = 0;
P0 = 0x40;
LCK = 1;//CS=0;
InData=0x80; // 10000XXXX
for(temp=9;temp!=0;temp--) { // 9
DI=InData&0x80;
SK=1; SK=0;
InData<<=1;
}
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
}
//**************************读address中的一字节****************************
unsigned int Read(unsigned char address) {
unsigned char temp;
unsigned int result;
Ewen();
SK=0; DI=1; // 110 A5-A0
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
LCK = 0;
P0 = 0x40;
LCK = 1;//CS=1;
SK=1; SK=0; // 1
address=address&0x3f|0x80;
for(temp=8;temp!=0;temp--) { // 8
DI=address&0x80;
SK=1; SK=0;
address<<=1;
}
DO=1;
for(temp=16;temp!=0;temp--) { // 16
SK=1;
result=(result<<1)|DO;
SK=0;
}
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
Ewds();
return(result);
}
//***************************往address中写一字节InData************************
void Write(unsigned char address,unsigned int InData) {
unsigned char temp;
Ewen();
SK=0; DI=1; // 101 A5-A0
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
LCK = 0;
P0 = 0x40;
LCK = 1;//CS=0;
SK=1; SK=0; // 1
address=address&0x3f|0x40;
for(temp=8;temp!=0;temp--) { // 8
DI=address&0x80;
SK=1; SK=0;
address<<=1;
}
for(temp=16;temp!=0;temp--) { // 16
DI=InData&0x8000;
SK=1; SK=0;
InData<<=1;
}
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
DO=1;
LCK = 0;
P0 = 0x40;
LCK = 1;//CS=0;
SK=1;
while(DO==0) { // busy test
SK=0; SK=1;
}
SK=0;
LCK = 0;
P0 = 0x00;
LCK = 1;//CS=0;
Ewds();
}
//*************************读address开始的一个字节,分高字节和地字节*******************
unsigned char ReadChar(unsigned char address) {
unsigned char temp=address>>1;
if(address&0x01) return((unsigned char)(Read(temp)>>8));
else return((unsigned char)(Read(temp)));
}
//**************************写address开始的一个字节,分高字节和地字节*****************
void WriteChar(unsigned char address,unsigned char InData) {
unsigned char temp=address>>1;
if(address&0x01) Write(temp,(unsigned int)(Read(temp)&0x00ff|(InData<<8)));
else Write(temp,(unsigned int)(Read(temp)&0xff00|InData));
}
//********************************读一个字符串**********************************
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) {
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);
}
/**********************************结束***********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -