STC15W读写AT24C02的C51程序,CH563读写AT24C02的程序,

/*****************************

STC15W读写AT24C02的C51程序

**************************/

#include <stc15w.h>
#include <intrins.h>

#define uint unsigned int

#define INT8 unsigned char  //通常是写成uchar,但这些写成INT8,是为是方便移植程序到32位的单片机CH563上时与原厂给的程序相对应

#define  WRITE24C02  0xA0  //注意:AT24C02的A0、A1、A2脚全接地

#define    READ24C02  0xA1

sbit SDA=P2^7;     //AT24C02串行数据 5脚  <-对于不同的系统板,需要在此处进行修改

sbit SCL=P2^6;    //AT24C02串行时钟 6脚

 

void delaymss(uint xms)  // 延时

{

 uint x, y;

 for(x = xms; x > 0; x--)

   for(y = 110; y > 0; y--);

}

void I2C_delay(void)//IIC通信延时用.注意这个延时非常重要,如果延时的时间不够,那么就不能正常通信

{

  _nop_();_nop_();_nop_();_nop_();

   _nop_();_nop_();_nop_();_nop_();

    _nop_();_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();_nop_();

}

void I2C_start(void)   //函数功能:iic开始

{

  SDA=1;

I2C_delay();

  SCL=1;

I2C_delay();

  SDA=0;

I2C_delay();

  SCL=0;

I2C_delay();

}

 

void I2C_stop(void)   // 函数功能:iic停止

{

  SDA=0;

I2C_delay();

  SCL=1;

I2C_delay();

  SDA=1;

I2C_delay();

  SCL=0;

I2C_delay();

}

 

void I2C_send_ack(bit k)

{

  SDA=k;

  I2C_delay();

  SCL=1;

  I2C_delay();

  SCL=0;

}

 

void I2C_write_byte(INT8 dat)

{

  INT8 i,i2;

   for (i=8;i>0;i--)

    {

    SCL=0;

I2C_delay();

i2=(dat&0x80)/0x80;

SDA=i2;//i2的值不是1就是0

    dat<<=1;

    I2C_delay();

    I2C_delay();

    SCL=1;

    I2C_delay();

    }

   SCL=0;  

}

 

INT8 I2C_read_byte(void)

{

  INT8 i,dat;

   for (i=0;i<8;i++)

    {

    SCL=0;

I2C_delay();

    SDA=1;

    I2C_delay();

    SCL=1;

    dat<<=1;

      I2C_delay();

    if(SDA)

       dat++;

    }

   SCL=0; 

     

   return (dat);

}

 

void I2C_write(INT8 address,INT8 dat)

{

 

 I2C_start();

 I2C_write_byte(WRITE24C02);    

 I2C_send_ack(0);

 I2C_write_byte(address);  

 I2C_send_ack(0);   

 I2C_write_byte(dat);    

 I2C_send_ack(1);

 I2C_stop();

}

 

INT8 I2C_read(INT8 address)

{

 INT8 dat;

 I2C_start();

 I2C_write_byte(WRITE24C02);

 I2C_send_ack(0);

 I2C_write_byte(address);

 I2C_send_ack(1);

 I2C_start();

 I2C_write_byte(READ24C02);

 I2C_send_ack(0);

 dat=I2C_read_byte();

 I2C_send_ack(1);

 I2C_stop();       

  return (dat);

}

 

 

void AT24C02_write(INT8 address,INT8 dat)//函数功能:向AT24C02的address中写入数据dat

I2C_delay();

 I2C_write(address,dat);

I2C_delay();

}

 

INT8 AT24C02_read(INT8 address)//函数功能:从AT24C02的address中读出数据dat

{

 INT8 temp;

I2C_delay();

 temp=I2C_read(address);

I2C_delay(); 

 return (temp);

}

 

void InitUART(void)//串口初始化

{

 

     AUXR &= ~0x01;      //串口1使用定时器T1

     AUXR &= ~(1<<6);   //定时器T1设置为1T的12分频模式

    TMOD=0x20;            //定时器T1使用工作方式2

    TH1=0xfd;               // 串口工作模式1下, 11.0592M晶振波特率计算: Baud=(2^SMOD / 32)*Fosc/(12*(256-X)), 其中Fosc=11059200

    TL1=0xfd;               //计算得到Baud=9600

    TR1=1;                   //开始计时   

    PCON=0x00;           //SMOD=0;

    SCON=0x50;           //串口工作模式1

    TI=1;                     //发送完成标志

    EA=1;                   //CPU开放中断

}

 

void SendOneByte(INT8 c) 

    while(!TI); 

    TI = 0; 

    SBUF = c; 

 

/***************************************************

函数功能:主函数

***************************************************/

main(void)

{

INT8 k1,r,r1;

P2M1=0X00;  //设置成准双向口  P27  P26

P2M0=0X00;             

InitUART(); //串口初始化

while(1)

{

for(r=0;r<=255;r++)

{

r1=r;

 

 AT24C02_write(r,r1); //向AT24C02的地址r处写入数据r1

 delaymss(2000);

k1=AT24C02_read(r);  //从AT24C02的地址r处读取数据,赋值给k1

 

SendOneByte(r1);  //用串口发送写入的数据

SendOneByte(k1);   //用串口发送读出的数据

delaymss(3000);

}

}

}

 

/******************************************************************

CH563读写AT24C02的程序.。从STC15W读写AT24C02的C51程序修改移植而来

********************************************************************/

#include "stdio.h"
#include "string.h"
#include "CH563SFR.H"
#include "SYSFREQ.H"

#define  WRITE24C02  0xA0    //AT24C02的A0、A1、A2管脚接地
#define    READ24C02  0xA1

#define SCL               (1<<9)    //SCL 为PB9脚
#define SDA               (1<<8)    //SDA  为PB8脚

/* 连接一个LED用于监控演示程序的进度,低电平LED亮 */
#define LED                     1<<19  //LED灯是PB19管脚

#define LED_OUT_INIT(  )     { R32_PB_OUT |= LED; R32_PB_DIR |= LED; }         /* LED 高电平为输出方向 */
#define LED_OUT_0(  )      { R32_PB_CLR |= LED; }                            /* LED 低电平驱动LED显示 */
#define LED_OUT_1(  )    { R32_PB_OUT |= LED; }                            /* LED 高电平关闭LED显示 */


#define SDA_OUT_INIT(  )     { R32_PB_OUT |= SDA; R32_PB_DIR |= SDA; }    /* SDA 高电平为输出方向 */     
#define SDA_OUT_0(  )      { R32_PB_CLR |= SDA; }           /* SDA 输出0 */               
#define SDA_OUT_1(  )    { R32_PB_OUT |= SDA; }            /* SDA 输出1 */                 

#define SCL_OUT_INIT(  )     { R32_PB_OUT |= SDA; R32_PB_DIR |= SCL; }  /* SCL 高电平为输出方向 */      
#define SCL_OUT_0(  )      { R32_PB_CLR |= SCL; }      /* SCL 输出0 */                       
#define SCL_OUT_1(  )    { R32_PB_OUT |= SCL; }         /* SCL 输出1 */                    


void SDA_c(void)         //SDA输入初始化
{
    R32_PB_PU |= (SDA);                                   /* 上拉 */
    R32_PB_DIR &= (~SDA);                               /* 输入 */
}

/*******************************************************************************
* Function Name  : IRQ_Handler
* Description    : IRQ中断函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void Delay_a()    //延时函数
{
INT32 i3;
for(i3=0;i3<1000000;i3++);
}


__irq void IRQ_Handler( void )   
{
    while(1);

__irq void FIQ_Handler( void )
{
    while(1);
}


//AT24C02存储程序开始
void I2C_delay() // IIC延时用,如果延时时间不够,IIC可能不能正常工作
{
INT8 i4,i5;
for(i4=0;i4<120;i4++)
{
i5=i5+1;
}
}

void I2C_start(void)  //AT24C02开始
{
SDA_OUT_INIT(  );
SCL_OUT_INIT(  );
SDA_OUT_1(  );
 // SDA=1;
I2C_delay();
SCL_OUT_1(  );
//  SCL=1;
I2C_delay();
SDA_OUT_0(  );
//  SDA=0;
I2C_delay();
SCL_OUT_0(  );
 // SCL=0;
I2C_delay();
}

void I2C_stop(void)      //AT24C02停止
{
SDA_OUT_INIT(  );
SDA_OUT_0(  );
//  SDA=0;
I2C_delay();
SCL_OUT_1(  );
//  SCL=1;
I2C_delay();
SDA_OUT_1(  );
//  SDA=1;
I2C_delay();
SCL_OUT_0(  );
//  SCL=0;
I2C_delay();
}

void I2C_send_ack(INT8 k)
{
    if(k==1)
    {
 SDA_OUT_1(  );
    }
    else
    {
 SDA_OUT_0(  );
    }
 // SDA=k;
  I2C_delay();
SCL_OUT_1(  );
//  SCL=1;
  I2C_delay();
SCL_OUT_0(  );
//  SCL=0;
}

void I2C_write_byte(INT8 dat)
{
  INT8 i,i2;
   for (i=8;i>0;i--)
    {
    SCL_OUT_0(  );
 //   SCL=0;
I2C_delay();
  //  SDA=(bit)(dat&0x80);
    i2=(dat&0x80)/0x80;
    if(i2==1)
    {
 SDA_OUT_1(  );
    }
    else
    {
 SDA_OUT_0(  );
    }
//    SDA=i2;
    dat<<=1;
    I2C_delay();
    I2C_delay();
    SCL_OUT_1(  );
//    SCL=1;
    I2C_delay();
    }
    SCL_OUT_0(  );
//   SCL=0;  
}
INT8 I2C_read_byte(void)
{
  INT8 i,dat8;
   for (i=0;i<8;i++)
    {
    SCL_OUT_0(  );
 //   SCL=0;
 SDA_OUT_INIT(  );
I2C_delay();     
    SDA_OUT_1(  );
//    SDA=1;
    I2C_delay();
      SCL_OUT_1(  );
 //   SCL=1;
    dat8<<=1;
    SDA_c(); //SDA输入
      I2C_delay();
 if(R32_PB_PIN&SDA)
 {
 dat8++;
 }
  //  if(SDA)
  //     dat++;
    }
      SCL_OUT_0(  );
 //  SCL=0;   
   return (dat8);
}
void I2C_write(INT8 address,INT8 dat)
{
 //INT8 temp;
 I2C_start();
 I2C_write_byte(WRITE24C02);    
 I2C_send_ack(0);
 I2C_write_byte(address);  
 I2C_send_ack(0);   
 I2C_write_byte(dat);    
 I2C_send_ack(1);
 I2C_stop();
}

INT8 I2C_read(INT8 address)
{
 INT8 dat;
 I2C_start();
 I2C_write_byte(WRITE24C02);
 I2C_send_ack(0);
 I2C_write_byte(address);
 I2C_send_ack(1);
// I2C_stop();
 I2C_start();
 I2C_write_byte(READ24C02);
 I2C_send_ack(0);
 dat=I2C_read_byte();
  SDA_OUT_INIT(  );
 I2C_send_ack(1);
 I2C_stop();       
// temp=dat/16;
// dat=dat%16;
// dat=dat+temp*10;
  return (dat);
}


void AT24C02_write(INT8 address,INT8 dat)  //写数据函数

I2C_delay();
 I2C_write(address,dat);
I2C_delay();
}
INT8 AT24C02_read(INT8 address)     //读数据函数
{
 INT8 temp;
I2C_delay();
 temp=I2C_read(address);
I2C_delay();
 return (temp);
}

//AT24C02存储程序结束

void Uart1_Init( UINT32 baud )     //串口初始化。这段函数是直接从原厂实例照抄来的。
{
    UINT32 x;

    x = 10 * FREQ_SYS/ 8 / baud;                                                /* 115200bps */
    x += 5;                                                                     /* 四舍五入 */
    x /= 10;
    R8_UART1_LCR = RB_LCR_DLAB;                                                 /* DLAB位置1 */
    R8_UART1_DIV = 1;                                                           /* 预分频 */
    R8_UART1_DLM = x>>8;
    R8_UART1_DLL = x&0xff;

    R8_UART1_LCR = RB_LCR_WORD_SZ ;                                             /* 设置字节长度为8    */
  
    R8_UART1_FCR = RB_FCR_FIFO_TRIG|RB_FCR_TX_FIFO_CLR|RB_FCR_RX_FIFO_CLR |    
                   RB_FCR_FIFO_EN ;                                             /* 设置FIFO触发点为28,清发送和接收FIFO,FIFO使能 */
   
    R8_UART1_IER = RB_IER_TXD_EN | RB_IER_LINE_STAT |RB_IER_THR_EMPTY | 
                   RB_IER_RECV_RDY  ;                                           /* TXD enable   !!TXD使能*/
    R8_UART1_MCR = RB_MCR_OUT2;                                                
    R8_INT_EN_IRQ_0 |= RB_IE_IRQ_UART1;                                         /* 串口中断输出使能 */
    R32_PB_SMT |= RXD1|TXD1;                                                    /* RXD1 schmitt input, TXD1 slow rate  !!RXD1施密特输入,TXD1低速率 */
    R32_PB_PD  &= ~ RXD1;                                                       /* disable pulldown for RXD1, keep pullup  !!禁用RXD1的下拉,保持向上下拉*/
    R32_PB_DIR |= TXD1;                                                         /* TXD1 output enable !!TXD1输出使能*/
}

/*******************************************************************************
* Function Name  : UART1_SendByte
* Description    : 串口1发送一字节子程序
* Input          : dat -要发送的数据
* Output         : None
* Return         : None
*******************************************************************************/

void UART1_SendByte( UINT8 dat )       //串口发送
{        
    R8_UART1_THR  = dat;
    while( ( R8_UART1_LSR & RB_LSR_TX_ALL_EMP ) == 0 );                         /* 等待数据发送 */       
}
/******************************
  主函数
*******************************/
void main()
{
INT8 a1,b1,b8;
LED_OUT_INIT( );  // 指示灯初始化, IO为输出
LED_OUT_0( );   //指示灯亮                                            
Delay_a();       //延时
LED_OUT_1( );     //指示灯灭
b1=1;
// AT24C02_write(a1,b1);    //保存b1值到a1地址,a1的地址可以是0-255
//b8=AT24C02_read(a1);    //读取存储在a1地址的值    

Uart1_Init( 115200 );  //串口初始化,波特率115200
while(1)
{
for(a1=0;a1<=255;a1++)
{
AT24C02_write(a1,a1);  //往AT24C02写入数据
Delay_a();      //延时函数。
Delay_a();      //读出函数不能直接放在写入函数后面,中间要有足够的延时,否则可能读不出正确的数据
Delay_a();
Delay_a();
Delay_a();
Delay_a();
b8=AT24C02_read(a1);  //从AT24C02读出数据 。注意:读出函数不能直接放在写入函数后面,中间要有足够的延时,否则可能读不出正确的数据
UART1_SendByte(a1);     //串口输出往AT24C02写入的数据
UART1_SendByte(b8);     //串口输出从AT24C02读出的数据
}
}
}

代码比较多,又没有硬件,建议你自己调试下。