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读出的数据
}
}
}
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读出的数据
}
}
}
举报