历时两天,总算把AT24C02调试成功了
相关主要代码如下
//AT24Cxx.H"文件
#ifndef WW_IIC
#define WW_IIC
#include <intrins.h>
#include "STC12C5A60AD.H"
// AT24C02端口
sbit AT24C02_SDA = P1^2;
sbit AT24C02_SCL = P1^1;
sbit AT24C02_WP = P1^0; //写保护输入端,用于硬件数据保护。当其为低电平时,可以正常读写;为高电平时,写保护,读操作不受影响。
#define A2A1A0 0x0E
#define AT24Cxx_READ (0xA1 | A2A1A0) // 器件地址以及读取操作
#define AT24Cxx_WRITE (0xA0 | A2A1A0) // 器件地址以及写入操作
// 函数功能:使能写保护
void AT24C02EnableProtect();
// 函数功能:禁止写保护
void AT24C02DisableProtect();
// 函数功能:初始化AT24Cxx
void AT24CxxInit();
// 函数功能:开始数据传送
void AT24CxxStart();
// 函数功能:结束数据传送
void AT24CxxStop();
//发送应答信号
void AT24CxxAck(void);
//发送非应答信号
void AT24CxxNAck(void);
//应答位检查子程序
bit AT24CxxCheckAck(void);
// 函数功能:从AT24Cxx读取数据
unsigned char AT24CxxReadData();
// 函数功能:向AT24Cxx的当前地址写入数据
//在调用此数据写入函数前需首先调用开始函数24CxxStart(),所以SCL=0
void AT24CxxWriteCurrent(unsigned char y);
// 函数功能:向AT24Cxx中的指定地址写入数据
void AT24CxxWriteSet(unsigned char add, unsigned char dat);
// 函数功能:向AT24Cxx中的指定地址连续写入n个字节数据
void AT24CxxWriteMulByte(unsigned char add, unsigned char *y, unsigned num);
// 函数功能:从AT24Cxx中的当前地址读取数据
unsigned char AT24CxxReadCurrent();
// 函数功能:从AT24Cxx中的指定地址读取数据
unsigned char AT24CxxReadSet(unsigned char set_addr);
// 函数功能:从AT24Cxx中的指定地址读取n个数
void AT24CxxRendNByte(unsigned char set_addr, unsigned char *y, unsigned num);
#endif
//AT24Cxx.C"文件
#include "AT24Cxx.H"
#include "BASIC_VAL_FUN.H"
// 函数功能:使能写保护
void AT24C02EnableProtect()
{
AT24C02_WP = 1;
delayms(1);
}
// 函数功能:禁止写保护
void AT24C02DisableProtect()
{
AT24C02_WP = 0;
delayms(1);
}
// 函数功能:初始化AT24Cxx
void AT24CxxInit()
{
AT24C02_SDA = 1;
delayms(1);
AT24C02_SCL = 1;
delayms(1);
}
// 函数功能:开始数据传送
void AT24CxxStart()
// 开始位
{
AT24C02_SDA = 1; //AT24C02_SDA初始化为高电平“1”
AT24C02_SCL = 1; //开始数据传送时,要求AT24C02_SCL为高电平“1”
delayus(3);
AT24C02_SDA = 0; //AT24C02_SDA的下降沿被认为是开始信号
delayus(3);
AT24C02_SCL = 0; //AT24C02_SCL为低电平时,AT24C02_SDA上数据才允许变化(即允许以后的数据传递)
}
// 函数功能:结束数据传送
void AT24CxxStop()
// 停止位
{
AT24C02_SDA = 0; //AT24C02_SDA初始化为低电平“0” _n
AT24C02_SCL = 1; //结束数据传送时,要求AT24C02_SCL为高电平“1”
delayus(3);
AT24C02_SDA = 1; //AT24C02_SDA的上升沿被认为是结束信号
delayus(3);
}
//发送应答信号
void AT24CxxAck(void)
{
AT24C02_SDA = 0;
AT24C02_SCL = 1;
delayus(3);
AT24C02_SCL = 0;
AT24C02_SDA = 1;
}
//发送非应答信号
void AT24CxxNAck(void)
{
AT24C02_SDA = 1;
AT24C02_SCL = 1;
delayus(3);
AT24C02_SCL = 0;
AT24C02_SDA = 1;
}
//应答位检查子程序
bit AT24CxxCheckAck(void)
{
bit ack_bit; //储存应答位
AT24C02_SDA = 1;
delayus(2);
AT24C02_SCL = 1;
delayus(3);
ack_bit = AT24C02_SDA; //接受设备(AT24Cxx)向AT24C02_SDA送低电平,表示已经接收到一个字节
//若送高电平,表示没有接收到,传送异常
AT24C02_SCL = 0; //AT24C02_SCL为低电平时,AT24C02_SDA上数据才允许变化(即允许以后的数据传递)
delayus(2);
return ack_bit; // 返回AT24Cxx应答位
}
/***************************************************
函数功能:从AT24Cxx读取数据
出口参数:x
***************************************************/
unsigned char AT24CxxReadData()
// 从AT24Cxx移入数据到MCU
{
uchar i;
uchar x; //储存从AT24Cxx中读出的数据
x = 0;
for(i = 0; i < 8; i++)
{
AT24C02_SDA = 1;
AT24C02_SCL = 1; //AT24C02_SCL置为高电平
x<<=1; //将x中的各二进位向左移一位
AT24C02_SDA = 1; // ww自行添加 变高之后增加两个空操作延时
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
x|=(uchar)AT24C02_SDA; //将AT24C02_SDA上的数据通过按位“或“运算存入x中
AT24C02_SCL = 0; //在AT24C02_SCL的下降沿读出数据
}
return(x); //将读取的数据返回
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数24CxxStart(),所以AT24C02_SCL=0
void AT24CxxWriteCurrent(unsigned char y)
{
uchar i; //储存应答位
for(i = 0; i < 8; i++) // 循环移入8个位
{
AT24C02_SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S
//因为传送时高位在前,低位在后
delayus(1);
AT24C02_SCL = 1; //在AT24C02_SCL的上升沿将数据写入AT24Cxx
delayus(3);
AT24C02_SCL = 0; //将AT24C02_SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1; //将y中的各二进位向左移一位
}
}
// 函数功能:向AT24Cxx中的指定地址写入数据
void AT24CxxWriteSet(unsigned char add, unsigned char dat)
{
bit ack;
AT24CxxStart(); //开始数据传递
AT24CxxWriteCurrent(AT24Cxx_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
ack = AT24CxxCheckAck();
AT24CxxWriteCurrent(add); //写入指定地址
ack = AT24CxxCheckAck();
AT24CxxWriteCurrent(dat); //向当前地址(上面指定的地址)写入数据
ack = AT24CxxCheckAck();
AT24CxxStop(); //停止数据传递
delayms(4); //1个字节的写入周期为1ms, 最好延时1ms以上
}
// 函数功能:向AT24Cxx中的指定地址连续写入n个字节数据
void AT24CxxWriteMulByte(unsigned char add, unsigned char *y, unsigned num)
{
bit ack;
uchar i;
AT24CxxStart(); //开始数据传递
AT24CxxWriteCurrent(AT24Cxx_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
ack = AT24CxxCheckAck();
AT24CxxWriteCurrent(add); //写入指定地址
ack = AT24CxxCheckAck();
for(i = 0; i<num; i++)
{
AT24CxxWriteCurrent(*y);
ack = AT24CxxCheckAck();
y++;
}
AT24CxxStop(); //停止数据传递
delayms(4);
}
// 函数功能:从AT24Cxx中的当前地址读取数据
unsigned char AT24CxxReadCurrent()
{
bit ack;
uchar x;
AT24CxxStart(); //开始数据传递
AT24CxxWriteCurrent(AT24Cxx_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据
ack = AT24CxxCheckAck();
x=AT24CxxReadData(); //将读取的数据存入x
AT24CxxNAck();
AT24CxxStop(); //停止数据传递
return x; //返回读取的数据
}
// 函数功能:从AT24Cxx中的指定地址读取数据
unsigned char AT24CxxReadSet(unsigned char set_addr)
// 在指定地址读取
{
bit ack;
AT24CxxStart(); //开始数据传递
AT24CxxWriteCurrent(AT24Cxx_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
ack = AT24CxxCheckAck();
AT24CxxWriteCurrent(set_addr); //写入指定地址
ack = AT24CxxCheckAck();
return(AT24CxxReadCurrent()); //从指定地址读出数据并返回
}
// 函数功能:从AT24Cxx中的指定地址读取n个数
void AT24CxxRendNByte(unsigned char set_addr, unsigned char *y, unsigned num)
{
bit ack;
uchar i;
AT24CxxStart(); //开始数据传递
AT24CxxWriteCurrent(AT24Cxx_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
ack = AT24CxxCheckAck();
AT24CxxWriteCurrent(set_addr); //写入指定地址
ack = AT24CxxCheckAck();
AT24CxxStart();
AT24CxxWriteCurrent(AT24Cxx_READ); //写入指定地址
ack = AT24CxxCheckAck();
for(i=0; i<num-1; i++)
{
*y = AT24CxxReadData(); //将读取的数据存入x
AT24CxxAck();
y++;
}
*y = AT24CxxReadData(); //将读取的数据存入x
AT24CxxNAck();
AT24CxxStop(); //停止数据传递
}
// mcu_diy.c 文件
// main函数部分
#include "STC12C5A60AD.H"
#include "MY_IO_DEFINE.H"
#include "BASIC_VAL_FUN.H"
#include "COM_PC.H"
#include "AT24Cxx.H"
#include "DS1302.H"
#include "LCD1602.H"
#include <intrins.h>
void main()
{
uchar LED;
uchar i, j, k;
uchar uLedDelayCount;
uchar uLedWei; // 8端数码管的位选信号
uchar code disled[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uchar code array[8] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
uchar revArray[8];
// 实现串口通信
Initial_Com_PC(Baud_Rate_9600);
//实现24C02
P1 = 0xFF;
AT24C02DisableProtect();
AT24CxxInit();
AT24CxxWriteSet(0x33, 0x12);
k = AT24CxxReadSet(0x33); //从指定地址0x33中读取数据并送P1口显 0xBF SendOneByte(k);
AT24CxxWriteMulByte(0x30, array, 8);
AT24CxxWriteMulByte(0x40, array, 8);
AT24CxxWriteSet(0x03, 0x11);
k = AT24CxxReadSet(0x03); //从指定地址0x03中读取数据
SendOneByte(k);
k = AT24CxxReadSet(0x34); //从指定地址0x34中读取数据
SendOneByte(k);
AT24CxxRendNByte(0x40, revArray, 8);
SendMulBuff(revArray,8);
while(1)
{
}
}