📄 at24c02.c
字号:
//参考程序A:AT24C02.C SMBUS 24C02 读/写 2005.12.25
//程序功能:在AT24C02的地址00---3FH中依次存入连续的数据10H--4FH
//再依次从地址00---3FH中读出数据并通过SAA1064驱动四位数码管显示出来.
//第一,二位数码管显示地址,第三,四位数码管显示存入该地址内的数据.
//显示格式:
//存储器的地址 存储器单元的内容
//00H---3FH 40H---4FH
#include <c8051f020.h> // SFR declarations
#include <intrins.h>
#include "regg.h" // SFR declarations
#include "main.h"
#define WRITE 0x00 // SMBUS寻址字节的写标志位
#define READ 0x01 // SMBUS寻址字节的读标志位
//Device addresses
#define CHIP_A 0xA0 //AT24C02器件自身的寻址字节
#define CHIP_B 0x70 //AT24C02器件自身的寻址字节
#define SMB_BUS_ERROR 0x0 //总线错误
//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 PIN_LCMCS P32
#define PIN_LCMRD P33
#define PIN_LCMWR P34
#define PIN_LCMDATA P35
#define LCM_READ_ID 0x06//00000110b //A5A4A3A2A1A0D0D1D2D3 D 从RAM 中读出数据
#define LCM_WRITE_ID 0x05//00000101b //A5A4A3A2A1A0D0D1D2D3 D 将数据写入RAM
#define READ_MODIFY_WRITE_ID 0x05//00000101b //A5A4A3A2A1A0D0D1D2D3 D 对RAM 进行读写
#define SYS_DIS_ID 0x00//00000100b //0000-0000-X C 关闭系统振荡器和LCD 偏置发生器Yes
#define SYS_EN_ID 0x02//00000100b //0000-0001-X C 打开系统振荡器
#define LCD_OFF_ID 0x04//00000100b //0000-0010-X C 关闭LCD 偏置发生器Yes
#define LCD_ON_ID 0x06//00000100b //0000-0011-X C 打开LCD 偏置发生器
#define TIMER_DIS_ID 0x08//00000100b //0000-0100-X C 禁止时基输出
#define WDT_DIS_ID 0x0a//00000100b //0000-0101-X C 禁止WDT 溢出标志输出
#define TIMER_EN_ID 0x0c//00000100b //0000-0110-X C 使能时基输出
#define WDT_EN_ID 0x0e//00000100b //0000-0111-X C 使能WDT 溢出标志输出
#define TONE_OFF_ID 0x10//00000100b //0000-1000-X C 关闭音频输出Yes
#define TONE_ON_ID 0x12//00000100b //0000-1001-X C 打开音频输出
#define CLR_TIMER_ID 0x18//00000100b //0000-11XX-X C 清零时基发生器内容
#define CLR_WDT_ID 0x1c//00000100b //0000-111X-X C 清零WDT
#define BIAS_1_2_ID 0xa0//00000100b //0010-abX0-X C 0x52
#define BIAS_1_3_ID 0x41//00000100b //0010-abX1-X C
#define BIAS 0x52
#define SYSEN 0x02
#define LCDON 0x06
#define LCDOFF 0x04
typedef struct
{
unsigned char LCM_ID; // command-id //
unsigned char LCM_ADDR; // 数据地址 //
unsigned char ucLen; // 通讯总字节数 //
unsigned char LCM_DATA[37]; // 显示的数据 //
}tLCM_DISP;
xdata tLCM_DISP LCM_DISP;
typedef union
{
struct
{
unsigned char data_h:4,data_l:4;
}DISP;
unsigned char vimdata[1];
}tLCM_DISP_DATA;
xdata tLCM_DISP_DATA LCM_DATA;
uchar bdata LCMdata;
sbit LCM_DATA_SIGN=LCMdata^0;
unsigned char xdata lcmtest[10];
unsigned char xdata DATA0[6]={0x17,0x3f,0x06,0x5b,0x4f};
unsigned char xdata DATA2[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char xdata SLAW,DATA1[64]; // 保存从地址+ WRITE 位
unsigned char SLAR,SLADDR; // 保存从地址+ WRITE 位
unsigned char WORD,WORDADR; // 保存被收/发的数据字节
unsigned char xdata sendnumber; // 保存被收/发的数据字节的数目
//unsigned char xdata WORDADR; //保存被传送的数据在24C02中的首地址.
unsigned char xdata SENDMODE; //SENDMODE作读/写控制字
unsigned char xdata i,j,k,sla,n,m,p;
unsigned char xdata Key_Stuck_Time_Counter;
unsigned char xdata flash_time_counter;
unsigned char xdata VFD_Refresh_Time_Counter,Key_Time_Counter;
bit SM_BUSY; //忙碌标志位
void sleep_ms( unsigned int count); //延时
void SYSCLK_Init (void); //系统时钟初始化
void DISPLAY(void); //通过SAA1064驱动四位数码管显示
void SMBUS_ISR (void); //中断服务程序
unsigned char SLA_READ(char chip,char wordadr,char number);
void SLA_SEND(char chip,char wordadr, char word,char number);
void sleep_ms(unsigned int count);
uchar LCM_READ(uchar addr_lcm);
void LCM_READ_ALL(uchar cnt);
void LCM_WRITE(uchar wdata,uchar lcmaddr);
void LCM_WRITE_ALL(uint *data_addr,uint *lcm_addr,uchar datalen);
void LCM_READ_MODIFY_WRITE(void);
void LCM_READ_MODIFY_WRITE_ALL(void);
void LCM_COMMAND_MODE(void);
void SendBit_1626(uchar Wdata,uchar cnt);
void SendDataBit_1626(uchar Wdata,uchar cnt); //data 的低cnt 位写入HT1621,低位在前
void SendCmd(uchar command);
void Write_1626(uchar addr,uchar Wdata);
void WriteAll_1626(uchar addr,uchar *p,uchar cnt);
void delay(void);
void timer0_Interrupt(void);
void timer1_Interrupt(void);
void HW_Intialize(void);
uchar test_cnt;
uchar xdata a[170],b[170];
void MAIN (void)
{
unsigned char unI; // 测试用的工作变量
WDTCN = 0xde; // 关闭看们狗
WDTCN = 0xad;
HW_Intialize();
//写64个连续的数据到AT24C02中去并依次存放.
//64个连续的数据的存放地址:00H--3fH.第一个数为10H,最后一个数为4FH.
i=0x10;
sla=CHIP_A;
test_cnt=0;
for(unI=0;unI<170;unI++)
{
a[unI]=0xff;
b[unI]=0x00;
}
while(1)
{
DISPLAY ();
for (j=0;j<0x40;j++) //向24C02的000地址依次写入64个数据,
{
delay();
}
if(test_cnt>170)
{
test_cnt=0;
WriteAll_1626(0,&b[0],170);
}
}
}
void DISPLAY (void)
{
SendCmd(BIAS_1_2_ID); //设置偏压和占空比
SendCmd(SYS_EN_ID); //打开系统振荡器
SendCmd(LCD_ON_ID); //打开LCD 偏压发生器
WriteAll_1626(0,&a[0],test_cnt++); //0:(起始地址)高8 位有效,a:(写入数据的起始地址)8 位
}
void SYSCLK_Init (void)
{
int i; // i 用于延时计数
OSCXCN = 0x67; // 先选择外捕振荡器,频率位11.0592MHZ
for (i=0; i < 256; i++) ; // 再延时(>1ms),
while (!(OSCXCN & 0x80)) ; // 等待外部晶振稳定
OSCICN = 0x88; // 选择外部晶振,允许时钟丢失检测
}
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
SLADDR = (chip| WRITE); // COMMAND = 7 个地址位 + 一位WRITE.
WORD = word; // WORD中存放要送到24C02中去的数据(8位)
WORDADR = wordadr; // OP_CODE 中存放被传送数据送入24C02的首地址.
STO = 0;
STA = 1; // 启动数据传输
while(SM_BUSY); // 等待传输完成
}
unsigned char SLA_READ(char chip, char wordadr,char number)
{
sendnumber=number;
SENDMODE=0;
while(SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // 置SM_BUSY位(忙碌标志位)为1
SLADDR= (chip| READ); // COMMAND = 7 个地址位 + 一位READ
WORDADR = wordadr; // OP_CODE 中存放从24C02读出数据的的首地址.
STO = 0;
STA = 1; // 启动传输
while(SM_BUSY); // 等待传输完成
return WORD; //返回读出来的数据(一个字节)
}
/*延时子程序*/
void sleep_ms(unsigned int count)
{
unsigned int ii,jj;
for(ii=0;ii<count;ii++)
{
for(jj=0;jj<250;jj++)
_nop_();
_nop_();
_nop_();
_nop_();
}
}
//PIN_LCMRD P33
//PIN_LCMWR P34
//PIN_LCMDATA P35
uchar LCM_READ(uchar addr_lcm)
{
unsigned char unI;
unsigned char data_lcm;
PIN_LCMCS=0;
PIN_LCMRD=1;
data_lcm=LCM_READ_ID;//LCM_DISP.LCM_ID;
for(unI=0;unI<3;unI++)//write id
{
PIN_LCMWR=0;
if(data_lcm&0x01)
PIN_LCMDATA=1;
else
PIN_LCMDATA=1;
data_lcm=data_lcm>>1;
PIN_LCMWR=1;
}
data_lcm=addr_lcm;//LCM_DISP.LCM_ADDR;
for(unI=0;unI<8;unI++)//write addr
{
PIN_LCMWR=0;
if(data_lcm&0x01)
PIN_LCMDATA=1;
else
PIN_LCMDATA=1;
data_lcm=data_lcm>>1;
PIN_LCMWR=1;
}
PIN_LCMCS=0;
PIN_LCMWR=1;
data_lcm=0;
for(unI=0;unI<4;unI++)//READ DATA
{
PIN_LCMRD=0;
data_lcm=LCMdata<<1;
LCMdata=data_lcm;
LCM_DATA_SIGN=PIN_LCMDATA;
PIN_LCMRD=1;
}
return LCMdata;
}
void LCM_READ_ALL(uchar cnt)
{
uchar unI,unJ;
uchar data_lcm;
PIN_LCMCS=0;
PIN_LCMRD=1;
data_lcm=LCM_DISP.LCM_ID;
for(unI=0;unI<3;unI++)//write id
{
PIN_LCMWR=0;
if(data_lcm&0x01)
PIN_LCMDATA=1;
else
PIN_LCMDATA=1;
data_lcm=data_lcm>>1;
PIN_LCMWR=1;
}
data_lcm=LCM_DISP.LCM_ADDR;
for(unI=0;unI<8;unI++)//write addr
{
PIN_LCMWR=0;
if(data_lcm&0x01)
PIN_LCMDATA=1;
else
PIN_LCMDATA=1;
data_lcm=data_lcm>>1;
PIN_LCMWR=1;
}
PIN_LCMCS=0;
PIN_LCMWR=1;
for(unJ=0;unJ<cnt;unJ++)
{
data_lcm=0;
for(unI=0;unI<4;unI++)//READ DATA
{
PIN_LCMRD=0;
data_lcm=LCMdata<<1;
LCMdata=data_lcm;
LCM_DATA_SIGN=PIN_LCMDATA;
PIN_LCMRD=1;
}
lcmtest[unJ]=LCMdata;
}
}
void LCM_WRITE(uchar wdata,uchar lcmaddr)
{
uchar unI,unJ;
uchar data_lcm;
PIN_LCMCS=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -