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

📄 24c02test.c

📁 基于C8051F005的24C02存储器的操作程序
💻 C
字号:
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f000.h>                 // SFR declarations
#include <stdio.h>
#include <intrins.h>

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);                  //系统时钟初始化
void SMBUS_ISR (void);                    //中断服务程序
char SLA_READ(char chip,char wordadr,char number);
void SLA_SEND(char chip,char wordadr, char word,char number);
void UART0_Init (void);
void SYSCLK_Init (void);
void PORT_Init (void);
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define  WRITE       0x00                 //  SMBUS寻址字节的写标志位
#define  READ        0x01                 //  SMBUS寻址字节的读标志位
// Device addresses
#define  CHIP_A        0xA0                //AT24C02器件自身的寻址字节
#define  CHIP_B        0x70                //AT24C02器件自身的寻址字节
#define  SMB_BUS_ERROR  0x00  //总线错误                                  
  //MT为主发送器,MR为主接收器
#define  SMB_START      0x08              // (MT & MR) 发送起始位
#define  SMB_RP_START   0x10              // (MT & MR) 重复起始位
#define  SMB_MTADDACK   0x18              // (MT) 发送从地址 + W 后收到ACK
#define  SMB_MTADDNACK  0x20              // (MT) 发送从地址 + W 后收到NACK
#define  SMB_MTDBACK    0x28              // (MT) 发送数据后收到ACK
#define  SMB_MTDBNACK   0x30              // (MT) 发送数据后收到NACK
#define  SMB_MTARBLOST  0x38              // (MT)竞争失败
#define  SMB_MRADDACK   0x40              // (MR) 发送从地址 + R 后收到 ACK
#define  SMB_MRADDNACK  0x48              // (MR) 发送从地址 + R 后收到 NACK
#define  SMB_MRDACK     0x50              // (MR) 收到数据字节 后已发送ACK                                    
#define  SMB_MRDBNACK   0x58              // (MR) 收到数据字节 后已发送NACK 
#define SYSCLK       11059200          // SYSCLK frequency in Hz
#define BAUDRATE     115200              // Baud rate of UART in bps
char DATA[6]={0x17,0x3f,0x06,0x5b,0x4f}; 
char SLAW,DATA1[6];                    // 保存从地址+ WRITE 位
char SLAR;                              // 保存从地址+ WRITE 位
char WORD;                      // 保存被收/发的数据字节
char xdata sendnumber;                  // 保存被收/发的数据字节的数目        
unsigned char xdata  WORDADR;         //保存被传送的数据在24C02中的首地址.
unsigned char xdata SENDMODE;           //SENDMODE作读/写控制字                       
unsigned char j,k,sla,n,p;
unsigned int i;
bit  SM_BUSY;                             //忙碌标志位                                       
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void  main (void)
{
   unsigned char check,Y,i=0;              // 测试用的工作变量
   WDTCN = 0xde;                          // 关闭看们狗
   WDTCN = 0xad;
   UART0_Init ();
   SYSCLK_Init ();
   PORT_Init ();
   SMB0CN = 0x44;                         // 允许SMBUS, 应答返回AA(低电平
   SMB0CR = 0xf8;                   // SMBus 速率= 100 kHz,系统时钟为11.0592MHZ
   EIE1 |= 2;                             // SMBus 中断使能
   EA = 1;                                // 开中断
   SM_BUSY = 0;                           //  SM_BUSY是忙碌标志位
   SI = 0;                                //SM_BUSY中断标志位
   sla=CHIP_A;
  for  (j=0;j<0x06;j++)            //向24C02的000地址依次写入64个数据,
   { 
   Y=DATA[i];                      //64个数据的数值从10H---4FH   
   SLA_SEND(sla, j,Y,0x01);       // 写入AT24C02
    i++;
    }
  for  (j=0;j<0x06;j++)          //从24C02的00地址依次连续读出64个数据,
  {                              //64个数据的数值应该是从10H---3FH(连续存放)
   check=SLA_READ(sla, j,0x01);     
     DATA1[j]=check;               //读出来的数据依次连续存入数组DATA[]中
  }

 
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// SLA_SEND
//-----------------------------------------------------------------------------
void SLA_SEND(char chip, char wordadr, char word,char number)
{
  SENDMODE=0x01;
   sendnumber=number+1;
   while(SM_BUSY);               // 若SMBUS忙碌就等待
   SM_BUSY = 1;                  // 置SM_BUSY位(忙碌标志位)为1                
   SLAW = (chip| WRITE);         // COMMAND = 7 个地址位 + 一位WRITE.
   WORD = word;                  // WORD中存放要送到24C02中去的数据(8位)
   WORDADR = wordadr;            // OP_CODE 中存放被传送数据送入24C02的首地址.
   STO = 0;
   STA = 1;                         // 启动数据传输
   while(SM_BUSY);                  // 等待传输完成
}
//-----------------------------------------------------------------------------
// SLA_READ
//-----------------------------------------------------------------------------
char SLA_READ(char chip, char wordadr,char number){
   sendnumber=number;
  SENDMODE=0;
   while(SM_BUSY);                  // 若SMBUS忙碌就等待
   SM_BUSY = 1;                     // 置SM_BUSY位(忙碌标志位)为1 
   SLAR = (chip| READ);             // COMMAND = 7 个地址位 + 一位READ
   WORDADR = wordadr;                // OP_CODE 中存放从24C02读出数据的的首地址.
   STO = 0;
   STA = 1;                          // 启动传输
   while(SM_BUSY);                   // 等待传输完成 
   return WORD;                      //返回读出来的数据(一个字节)
}
//-----------------------------------------------------------------------------
// SMBUS_ISR
//-----------------------------------------------------------------------------
void SMBUS_ISR (void) interrupt 7    //中断服务程序
{
   switch (SMB0STA){                 // 根据中断状态码跳转
                                     //(SMB0STA 是中断状态寄存器)
       case SMB_START:	             //0x08, (MT & MR) 发送起始位
         SMB0DAT = SLAW ;            // 装入被访问的从芯片的写地址
         STA = 0;                    // 人工清除 STA 位
         SI = 0;                     // 清除中断标志位
         break;
       case SMB_RP_START:	         //0x10,(MT & MR) 重复发送起始位
         SMB0DAT = SLAR;             // 装入被访问的从芯片的读地址
         STA = 0;                    // 人工清除 STA 位
         SI = 0;                     // 清除中断标志位
         break;
       case SMB_MTADDACK:            //0x18 ,(MT) 发送从地址 + W 后收到ACK
         SMB0DAT = WORDADR;
         SI = 0;                     // 清除中断标志位
         break;
       case SMB_MTADDNACK:     	    //0x20,(MT) 发送从地址 + W 后收到NACK
         STO = 1;
         STA = 1;
         SI = 0;                    // 清除中断标志位
         break;
      case SMB_MTDBACK:		        //0x28,(MT) 发送数据后收到ACK
         switch (SENDMODE){         // 检查低1位
       case 1:
			   sendnumber--;
			   if(sendnumber)
			   SMB0DAT = WORD;
			   else{
			   		STO=1;
				   	SM_BUSY=0;
				}
              break;             
       case 0:
			     STO = 0;
               STA = 1;
               break;            
       default:              
               STO = 1;
               SM_BUSY = 0;
               break;
         }
         SI = 0;
         break;
      case SMB_MTDBNACK:	//0x30
         STO = 1;
         STA = 1;
         SI = 0;                          // 清除中断标志
         break;
      case SMB_MRADDACK:	//0x40
         AA = 0;                        
         SI = 0;
         break;
   	  case SMB_MRADDNACK:	//0x48
         STO = 0;
         STA = 1;
         SI = 0;
         break;
     case SMB_MRDBNACK:	    //0x58
         WORD = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;
         AA = 1;                          
         SI = 0;
         break;
      default:
         STO = 1;
         SM_BUSY = 0;
         break;
      }
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
void PORT_Init (void)
{

    	XBR0 = 0x27;                    	// XBAR0: Initial Reset Value
    	XBR1 = 0x00;	                    // XBAR1: Initial Reset Value
    	XBR2 = 0x5c;                    	// XBAR2: Initial Reset Value
    	PRT0CF = 0x14;                      // Output configuration for P0 
      	PRT1CF = 0x10; // Output configuration for P3 
       	PRT3CF = 0x01; // Output configuration for P3 

}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
                                  // delaynms counter
      OSCXCN = 0x67;                      // start external oscillator with
      for (i=0; i < 256; i++) ;           // XTLVLD blanking interval (>1ms)
      while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle
      OSCICN = 0x88;                      // select external oscillator as SYSCLK                              
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
   SCON    = 0x50;                     // SCON: mode 1, 8-bit UART, enable RX
   TMOD    = 0x20;                     // TMOD: timer 1, mode 2, 8-bit reload
   TH1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate
   TR1    = 1;                         // start Timer1
   CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base
   PCON  |= 0x80;                      // SMOD = 1
   TI     = 1;                         // Indicate TX ready
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -