ch563读写AT24C02程序

谁有ch563读写AT24C02程序吗?用C51的程序来改,就是不成功

您好,AT24C02应该是一个IIC从机器件,CH563没有硬件的IIC,可以采用 GPIO模拟,可以用逻辑分析仪或者示波器抓取一下两根线上的信号波形,看一下是不是在时序有什么问题。


AT24C02非常适合存储一些经常修改的小数据,比ch563 自带的DataFlash更灵活。小数据用AT24Cxx,中量数据用DataFlash,大量数据用TF卡,这样ch563就非常好用了。

经过几天的努力,已经能让ch563正常读写AT24C02了,代码是从51单片机STC15W上移植过来的。ch563的代码还没整理好,先发一个STC15W上的代码,给大家参考一下,ch563的整理完了再发上来。



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

基于STC15W的51单片机对AT24C02进行数据读写

AT24C02_write是写入数据程序

AT24C02_read是读出数据程序


AT24C02是2K的容量,但我们一条数据是8位的,所以我们实际是能存储256条数据,对于一些需要不断更改的小数据,AT24C02是非常合适的。

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


#include  //这个地方可能不能正常显示,是stc15w的头文件

#include       //这个地方可能不能正常显示,是intrins文件 

#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单片机的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读出的数据

}

}

}



只有登录才能回复,可以选择微信账号登录