ch563讀寫AT24C02程序

誰有ch563讀寫AT24C02程序嗎?用C51的程序來改,就是不成功

您好,AT24C02應(yīng)該是一個IIC從機(jī)器件,CH563沒有硬件的IIC,可以采用 GPIO模擬,可以用邏輯分析儀或者示波器抓取一下兩根線上的信號波形,看一下是不是在時序有什么問題。


AT24C02非常適合存儲一些經(jīng)常修改的小數(shù)據(jù),比ch563 自帶的DataFlash更靈活。小數(shù)據(jù)用AT24Cxx,中量數(shù)據(jù)用DataFlash,大量數(shù)據(jù)用TF卡,這樣ch563就非常好用了。

經(jīng)過幾天的努力,已經(jīng)能讓ch563正常讀寫AT24C02了,代碼是從51單片機(jī)STC15W上移植過來的。ch563的代碼還沒整理好,先發(fā)一個STC15W上的代碼,給大家參考一下,ch563的整理完了再發(fā)上來。



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

基于STC15W的51單片機(jī)對AT24C02進(jìn)行數(shù)據(jù)讀寫

AT24C02_write是寫入數(shù)據(jù)程序

AT24C02_read是讀出數(shù)據(jù)程序


AT24C02是2K的容量,但我們一條數(shù)據(jù)是8位的,所以我們實際是能存儲256條數(shù)據(jù),對于一些需要不斷更改的小數(shù)據(jù),AT24C02是非常合適的。

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


#include  //這個地方可能不能正常顯示,是stc15w的頭文件

#include? ? ? ?//這個地方可能不能正常顯示,是intrins文件 

#define uint unsigned int

#define INT8 unsigned char? //通常是寫成uchar,但這些寫成INT8,是為是方便移植程序到32位的單片機(jī)CH563上時與原廠給的程序相對應(yīng)

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

#define? ? READ24C02? 0xA1

sbit SDA=P2^7;? ? ?//AT24C02串行數(shù)據(jù) 5腳? <-對于不同的系統(tǒng)板,需要在此處進(jìn)行修改

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)? ?//函數(shù)功能:iic開始

{

? SDA=1;

I2C_delay();

? SCL=1;

I2C_delay();

? SDA=0;

I2C_delay();

? SCL=0;

I2C_delay();

}


void I2C_stop(void)? ?// 函數(shù)功能: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)//函數(shù)功能:向AT24C02的address中寫入數(shù)據(jù)dat

{?

I2C_delay();

?I2C_write(address,dat);

I2C_delay();

}


INT8 AT24C02_read(INT8 address)//函數(shù)功能:從AT24C02的address中讀出數(shù)據(jù)dat

{

?INT8 temp;

I2C_delay();

?temp=I2C_read(address);

I2C_delay();?

?return (temp);

}


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

{


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

? ? ?AUXR &= ~(1<<6);? ?//定時器T1設(shè)置為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;? ? ? ? ? ? ? ? ? ? ?//發(fā)送完成標(biāo)志

? ? EA=1;? ? ? ? ? ? ? ? ? ?//CPU開放中斷

}


void SendOneByte(INT8 c)?

{?

? ? while(!TI);?

? ? TI = 0;?

? ? SBUF = c;?

}?


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

函數(shù)功能:主函數(shù)

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

main(void)

{

INT8 k1,r,r1;

P2M1=0X00;? //設(shè)置成準(zhǔn)雙向口? P27? P26

P2M0=0X00;? ? ? ? ? ? ?

InitUART(); //串口初始化

while(1)

{

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

{

r1=r;


?AT24C02_write(r,r1); //向AT24C02的地址r處寫入數(shù)據(jù)r1

?delaymss(2000);

k1=AT24C02_read(r);? //從AT24C02的地址r處讀取數(shù)據(jù),賦值給k1


SendOneByte(r1);? //用串口發(fā)送寫入的數(shù)據(jù)

SendOneByte(k1);? ?//用串口發(fā)送讀出的數(shù)據(jù)

delaymss(3000);

}

}

}



CH563讀寫AT24C02程序,經(jīng)一天一夜的跑程序驗證,沒有問題,未發(fā)現(xiàn)任何一個讀寫數(shù)據(jù)錯誤。

從STC15W單片機(jī)的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用于監(jiān)控演示程序的進(jìn)度,低電平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 低電平驅(qū)動LED顯示 */

#define LED_OUT_1(? )? ? { R32_PB_OUT |= LED; }? ? ? ? ? ? ? ? ? ? ? ? ? ? /* LED 高電平關(guān)閉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中斷函數(shù)

* Input? ? ? ? ? : None

* Output? ? ? ? ?: None

* Return? ? ? ? ?: None

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


void Delay_a()//延時函數(shù)

{

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)? //寫數(shù)據(jù)函數(shù)

{?

I2C_delay();

?I2C_write(address,dat);

I2C_delay();

}

INT8 AT24C02_read(INT8 address) //讀數(shù)據(jù)函數(shù)

{

?INT8 temp;

I2C_delay();

?temp=I2C_read(address);

I2C_delay();

?return (temp);

}


//AT24C02存儲程序結(jié)束


void Uart1_Init( UINT32 baud ) //串口初始化。這段函數(shù)是直接從原廠實例照抄來的。

{

? ? 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;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 預(yù)分頻 */

? ? R8_UART1_DLM = x>>8;

? ? R8_UART1_DLL = x&0xff;


? ? R8_UART1_LCR = RB_LCR_WORD_SZ ;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 設(shè)置字節(jié)長度為8? ? */

??

? ? R8_UART1_FCR = RB_FCR_FIFO_TRIG|RB_FCR_TX_FIFO_CLR|RB_FCR_RX_FIFO_CLR |? ??

? ? ? ? ? ? ? ? ? ?RB_FCR_FIFO_EN ;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 設(shè)置FIFO觸發(fā)點為28,清發(fā)送和接收FIFO,F(xiàn)IFO使能 */

? ?

? ? 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發(fā)送一字節(jié)子程序

* Input? ? ? ? ? : dat -要發(fā)送的數(shù)據(jù)

* Output? ? ? ? ?: None

* Return? ? ? ? ?: None

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


void UART1_SendByte( UINT8 dat )? ?//串口發(fā)送

{? ? ? ??

? ? R8_UART1_THR? = dat;

? ? while( ( R8_UART1_LSR & RB_LSR_TX_ALL_EMP ) == 0 );? ? ? ? ? ? ? ? ? ? ? ? ?/* 等待數(shù)據(jù)發(fā)送 */? ? ? ?

}

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

? 主函數(shù)

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

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寫入數(shù)據(jù)

Delay_a();? //延時函數(shù)。

Delay_a();? //讀出函數(shù)不能直接放在寫入函數(shù)后面,中間要有足夠的延時,否則可能讀不出正確的數(shù)據(jù)

Delay_a();

Delay_a();

Delay_a();

Delay_a();

b8=AT24C02_read(a1);? //從AT24C02讀出數(shù)據(jù) 。注意:讀出函數(shù)不能直接放在寫入函數(shù)后面,中間要有足夠的延時,否則可能讀不出正確的數(shù)據(jù)

UART1_SendByte(a1); //串口輸出往AT24C02寫入的數(shù)據(jù)

UART1_SendByte(b8); //串口輸出從AT24C02讀出的數(shù)據(jù)

}

}

}



只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频