📄 i2c24lc单字写.c
字号:
//。。。。。。。。。。。。。。。。。。。
//切记,当连续页写入时,中间要加入查询是否数据已写入标志;
//本程序在写完后;已加入//查询上次数据是否已写完;
//。。。。。。。。。。。。。。。。。。。
//本程序用于测试24LC的MSP430的程序,
//可用于24LC系列地址为8位或者为16位的,只需更改,
//(#define ic24_adr 1 //0代表8位地址,1代表16位地址,)
//本程序可用于对数组的读写,或者用于对单个变量的读写.
//对数组的读写时,取数组名既可,同时更改写字节数,
// IIC(write_table,Quantity,incept_add,(AT24_ADD|write));
// ( #define Quantity 4 //读写字节数量)
//对变量的读写时,取变量地址既可;同时更改写字节数,
// IIC(&write_table,Quantity,incept_add,(AT24_ADD|write));
//本程序算法部分可以用在其它部分,
//2007年6月7日调试已通过;
#define uchar unsigned char
#define uint unsigned int
#include "ic24LC.h"
//#define XF_MCU 1 //定义用哪一种单片机,1时,用于PIC; 0时,用于MSP430;
#if XF_MCU==0
//文件名:DS1302.c
#include<msp430x14x.h>
#else
#include<pic.h>
uchar pa_out;
uchar pb_out;
uchar pc_out;
uchar pd_out;
uchar pe_out;
#endif
//写入AT24C02数据表
unsigned char write_table[8]={1,2,3,4,5,6,7,8};
//unsigned char write_table=25; //写入单字节时
//读出AT24C02数据缓冲区
unsigned char read_Buff[8]={0};
//unsigned char read_Buff; //读入单字节时
unsigned char read_Buff1[8]={9,8,7,6,5,4,3,2};
//unsigned char read_Buff; //读入单字节时
unsigned char iic_check; //检查标志,可选的.
//小延时********************************
nop_()
{
uchar hang=1;
while(hang--);
}
SomeNOP()
{uchar hang=2;
while(hang--);
}
//**************************************
//起始信号
void I2CStart(void)
{
NOT_INT; //关总中断;
SCLOUT; //SCL口设为输出-------后加
SDAOUT; //SDA口设为输出
SDA1;
//SCLOUT; //SCL口设为输出
SCL1;
SomeNOP(); SomeNOP(); //INI
SDA0;
SomeNOP(); SomeNOP(); //START
SCL0;
}
//**************************************
//结束信号
void I2CStop(void)
{
SCL0;
SDA0;
SomeNOP(); //INI
SCL1;
SomeNOP();
SDA1; //STOP
OPE_INT; //EA=1;
}
//**************************************
//等待从器件接收方的应答
unsigned char WaitAck(void)
{
unsigned char errtime=255; //因故障接收方无ACK,超时值为255。
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SDAIN; //SDA口设为输入
while(SDA_STATE) //SDA出现为0时,则为有应答
{ errtime--;
if (!errtime) //errtime是否为0
{I2CStop();
return NO;} //返回为0(失败)
}
SDAOUT; //SDA口设为输出
SCL0;
return OK; //返回为1(成功)
}
//**************************************
//主器件为接收方,从器件为发送方时,单片机发出应答信号
//MCU Send to IC
void SendAck(void)
{
SDA0;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//**************************************
//主器件为接收方,从器件为发送方时,非应答信号
void SendNotAck(void)
{
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//**************************************
//发送字节
void I2CSendByte(unsigned char ch)
{
unsigned char i=8;
while (i--)
{
SCL0; //SCL=0;
nop_();
if(ch&0x80)
SDA1; //使SDA为1位
else
SDA0; //使SDA为0位
//---------------
ch<<=1;
SomeNOP();
SCL1;
SomeNOP();
}
SCL0;
}
//**************************************
//接收字节
unsigned char I2CReceiveByte(void)
{
unsigned char i=8; //接收8位
unsigned char ddata,timp;
ddata=0;
SDA1;
SDAIN; //SDA口设为输入
while (i--)
{
ddata<<=1; //将ddata位向高位移,于让位0
SCL0;
SomeNOP();
SCL1;
SomeNOP();
timp = SDA_STATE; //读入SDA,后加
timp>>=SDA_MOV_BIT; //将timp的SDA位数据移到位0
ddata|=timp; //将timp的SDA位数据移到ddata位0
}
SCL0; //SCL=0;
SDAOUT; //(附加)SDA口设回为输出
return ddata;
}
//正常操作时返回位值为0,有故障时返回位值为1.
//unsigned char *DataBuff数据缓冲区指针,char ByteQuantity字节数量,
//unsigned int Address IC片内地址,
//unsigned char ControlByte芯片控制字节-IC地址/读写位,
unsigned char IIC(unsigned char *DataBuff,char ByteQuantity,unsigned int Address,
unsigned char ControlByte)
{
unsigned char errorflag=error; //错误标志位,1为错误,0为正确
unsigned char i,q; //i为允许本次操作的最大次数
unsigned char p;
i=1;
SCLOUT; //时钟口长设为输出
while(i--)
for(p=0;p<ByteQuantity;p++)
{ i=1;
q=1;
while(i--)
{
I2CStart();
I2CSendByte(ControlByte&0xfe); //指定芯片,此次必定为写
if(!WaitAck()) //涵数返回一个1为成功
continue;//结束写操作,并i-1后,再来一次
if(ic24_adr==0) //0代表8位地址,1代表16位地址,
{I2CSendByte((unsigned char)Address); //发送片内地址
if(!WaitAck()) //数返回一个1为成功
continue;//结束写操作,并i-1后,再来一次
}
else
{I2CSendByte(*((char *)&Address+1)); //发送片内高8位地址
if(!WaitAck()) //数返回一个1为成功
continue; //结束写操作,并i-1后,再来一次
I2CSendByte(*((char *)&Address+0)); //发送片内低8位地址
if(!WaitAck()) //数返回一个1为成功
continue; //结束写操作,并i-1后,再来一次
}
Address++; //IC片内地址,
//------------------------------已经选定好IC
if(!(ControlByte&0x01)) //本次操作是读还是写
{ //写操作
errorflag=right; //清错误标志位为0
while(q--) //操作j个数字节
{
I2CSendByte(*DataBuff++);//发送
if(WaitAck()) //涵数返回一个1为成功,涵数返回一个0为失败
continue; //成功,下一个数据循环(跳while)
errorflag=error; //不应答,失败了. errorflag=1
break; //退出写操作
}
if(errorflag==error) //经过写完后,如果最后errorflag标志为1,则表示有错误
continue; //结束写操作,并i-1后,再来一次
break; //写操作完成
}
else //则为读操作
{ I2CStart(); //开始
I2CSendByte(ControlByte);
if(!WaitAck()) //涵数返回一个1为成功
{continue;} //结束此操作,并i-1后,再来一次
while(q--) //读入ByteQuantity个数字节
{*DataBuff++=I2CReceiveByte(); //连续读入ByteQuantity个数据
SendAck();} //主机向从机发出应答,表示主机已接收
*DataBuff=I2CReceiveByte(); //读入最后个数据
SendNotAck(); //最后发出不应答信号(位),表示主机不再读了.
errorflag=right; //向错误标志位写0(right),表示读数据正确.
break;} //读操作完成*/
}
I2CStop(); //停止,结束IIC总线
if(!(ControlByte&0x01)) //当本次操作为写时,查询数据是否已写完;
I2C_QUERY(); //查询本次数据是否已写完;
return(errorflag); //返回操作成败标志
}
}
//***********************************************************************
//******************************************************
//******************************************************
//软延时
void delay(unsigned int n)
{unsigned int k;
for(k=0;k<n;k++);
}
//******************************************************
//检验两组数据是否正确,如在检验数据中有一组不正确,则退出.
//*Data_REF参考值数组,*Data_CHK被检验数组,n检验数量
//并返回一个成败标志.
unsigned char data_check(unsigned char *Data_REF, unsigned char *Data_CHK,
unsigned char n)
{unsigned char chk ;
while(n)
{
if(Data_REF[n-1]==Data_CHK[n-1]) //进行校对
{ chk = right; //正确
n--; //下一位
}
else
{ chk = error; //校对有错
continue; //马上退出
}
}
return chk ; //返回校对成败标志.
}
void I2C_QUERY(void) //查询本次数据是否已写完;
{
while(1)
{
I2CStart();
I2CSendByte((AT24_ADD|write)&0xfe); //指定芯片,此次必定为写
if(WaitAck()) //涵数返回一个1为成功
{break; //结束写操作,
I2CStop();} //停止,结束IIC总线
}
}
void I2C_CLR(void) //清24LC子程序;
{
uint a,b;
for(a=0;a<400;a++)
{
b=a*8;
iic_check=IIC(read_Buff,Quantity,b,(AT24_ADD|write));
// I2C_QUERY(); //查询本次数据是否已写完;
}
}
void I2C_WR(void) //页连续写子程序
{
uint a,b;
//for(a=0;a<400;a++)
for(a=0;a<406;a++)
{
//b=((a-168)*8+160);
b=a*8;
iic_check=IIC(write_table,Quantity,b,(AT24_ADD|write));
//I2C_QUERY(); //查询本次数据是否已写完;
}
}
//******************************************************
void main(void)
{
#if XF_MCU==0
WDTCTL=WDTPW+WDTHOLD; //停止WDT
#endif
I2C_CLR(); //清24LC子程序;
I2C_WR(); //页连续写子程序
while(1)
{
//写入数据所在的数组或者地址?
//向AT24C02芯片写入字节数
//向AT24C02芯片写入片内地址
//芯片控制字节-IC地址/读写位
iic_check=IIC(write_table,Quantity,incept_add,(AT24_ADD|write));
//iic_check=IIC(&write_table,Quantity,incept_add,(AT24_ADD|write)); //写入单字节时
delay(500); //写入后,做一个适当的延时
//读入数据所在的数组或者地址
//向AT24C02芯片读入字节数
//向AT24C02芯片读入片内地址
//芯片控制字节-IC地址/读写位
iic_check=IIC(read_Buff,Quantity,incept_add,(AT24_ADD|read));
//iic_check=IIC(&read_Buff,Quantity,incept_add,(AT24_ADD|read)); //读入单字节时
//判别校验是否成功
if(!(data_check(write_table,read_Buff,Quantity)))
;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -