⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 93c46.c

📁 8051 SPI_93c46 c语言程序
💻 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 + -