📄 24cxx12864.c
字号:
/****************************************************************************************
AT24CXX的mega8控制程序
程序功能:该程序是用AVR来控制对AT24C256
读写信号等的操作.
硬件连接:
显示部分用12864液晶来显示从24c256中读取的图片
作者:张国旗
2009年1月3号
****************************************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define START 0X08 //START信号已发出
#define RESTART 0X10 //REPFEATED START信号已发出
#define MT_SLA_ACK 0X18 //SLA+W已发出并收到ACK
#define MT_DATA_ACK 0X28 //DATA已发出并收到ACK
#define MT_RSLA_ACK 0X40 //SLA+R已发出并收到ACK
#define MT_RDATA_ACK 0X50 //DATA已收到ACK已发出
#define MT_RDATA_NACK 0X58 //DATA已收到NACK已发出
//==============各种时序操作信号函数================
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //产生START信号
#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //产生STOP信号
#define Wait() while(!(TWCR&(1<<TWINT))) //等待当前操作完成
#define TestACK() (TWSR&0xF8) //取出状态码
#define SetACK() (TWCR|=(1<<TWEA)) //产生ACK
#define Twi_NoAcK() {TWCR=BIT(TWINT)|BIT(TWEN);} //非应答信号
#define Writebyte(twi_d) {TWDR=(twi_d);TWCR=(1<<TWINT)|(1<<TWEN);}//发送一个字节(twi_d为写入的数据)
//========在此设定芯片地址=============
#define W_ADD_COM 0xa0 //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa1 //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
//=======在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
#define e2prom 256 // <---在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
#if e2prom==1
#define PAGE_SIZE 8
#define SIZE 0x007f
#elif e2prom==2
#define PAGE_SIZE 8
#define SIZE 0x00ff
#elif e2prom==4
#define PAGE_SIZE 16
#define SIZE 0x01ff
#elif e2prom==8
#define PAGE_SIZE 16
#define SIZE 0x03ff
#elif e2prom==16
#define PAGE_SIZE 16
#define SIZE 0x07ff
#elif e2prom==32
#define PAGE_SIZE 32
#define SIZE 0x0fff
#elif e2prom==64
#define PAGE_SIZE 32
#define SIZE 0x1fff
#elif e2prom==128
#define PAGE_SIZE 64
#define SIZE 0x3fff
#elif e2prom==256
#define PAGE_SIZE 64
#define SIZE 0x7fff
#elif e2prom==512
#define PAGE_SIZE 128
#define SIZE 0xffff
#endif//========读取一个字节============
uchar Readbyte(void)
{
TWCR=BIT(TWINT)|BIT(TWEA)|BIT(TWEN);
while(!(TWCR&(1<<TWINT)));
return(TWDR);
}
//==========TWI初始化==========
void twi_init()
{
TWBR=0X20; //设置波特率
TWSR=0; //设置波特率预分频
TWCR=0X44; //初始化TWI控制寄存器
}
//=========写一个字节数据=============
uchar twi_writeBtye(uint dataddr,uchar rdata)//存储地址,数据
{
Start(); //启动IIC
Wait(); //等待操作完成
if(TestACK()!=START){return 0;}
Writebyte(W_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_SLA_ACK){return 0;}
Writebyte(((dataddr&0xff00)>>8)); //写数据存储地址高八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Writebyte(dataddr); //写数据存储地址低八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Writebyte(rdata); //写一字节数据
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Stop(); //停止
delay(10);
return 1;
}
//=========写N个字节数据=============
uchar twi_writeNBtye(uint dataddr,uchar rdata[],uint n)//存储地址,数据,数据个数
{
uchar i,j;
for(i=0;i<(n/PAGE_SIZE+1);i++) //page_spase
{
Start(); //启动IIC
Wait(); //等待操作完成
if(TestACK()!=START){return 0;}
Writebyte(W_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_SLA_ACK){return 0;}
#if e2prom>=32
Writebyte(((dataddr&0xff00)>>8));//写数据存储地址高八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
#endif
Writebyte(dataddr); //写数据存储地址低八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
if((n-PAGE_SIZE*i)>PAGE_SIZE)
{
for(j=0;j<PAGE_SIZE;j++)
{
Writebyte(rdata[(i*PAGE_SIZE)+j]);//写一字节数据
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
}
}
else
{
for(j=0;j<(n%PAGE_SIZE);j++)
{
Writebyte(rdata[(i*PAGE_SIZE)+j]);//写一字节数据
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
}
}
dataddr=dataddr+PAGE_SIZE;
Stop(); //停止
delay(10);
}
return 1;
}
//==========读一个字节数据=============
uchar twi_readBtye(uint dataddr) //存储地址
{
uint temp;
Start();
Wait(); //等待操作完成
if(TestACK()!=START){return 0;}
Writebyte(W_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_SLA_ACK){return 0;}
#if e2prom>=32
Writebyte(((dataddr&0xff00)>>8)); //写数据存储地址高八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
#endif
Writebyte(dataddr); //写数据存储地址低八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Start(); //重新启动IIC总线
Wait(); //等待应答信号
if(TestACK()!=RESTART){return 0;}
Writebyte(R_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_RSLA_ACK){return 0;}//
temp=Readbyte(); //读去一字节数据
Twi_NoAcK(); //发送非应答信号
Wait(); //等待操作完成
if(TestACK()!=MT_RDATA_NACK){return 0;}
Stop(); //停止
delay(10);
return temp;
return 1;
}
//==========读N个字节数据=============
uchar twi_readNBtye(uint dataddr,uchar rdata[],uint n)//存储地址
{
uint temp,i;
Start();
Wait(); //等待操作完成
if(TestACK()!=START){return 0;}
Writebyte(W_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_SLA_ACK){return 0;}
#if e2prom>=32
Writebyte(((dataddr&0xff00)>>8)); //写数据存储地址高八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
#endif
Writebyte(dataddr); //写数据存储地址低八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Start(); //重新启动IIC总线
Wait(); //等待操作完成
if(TestACK()!=RESTART){return 0;}
Writebyte(R_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_RSLA_ACK){return 0;}
for(i=0;i<n;i++)
{
rdata[i]=Readbyte(); //读去一字节数据
}
Twi_NoAcK(); //发送非应答信号
Wait(); //等待操作完成
if(TestACK()!=MT_RDATA_NACK){return 0;}
Stop(); //停止
delay(10);
return 1;
}
//========写入一屏24c256中的图片128*64=======
// 此函数是为了提高单片机的工作效率
// 专门写的读24c256中图片数据
// 并在12864液晶上显示的函数
//===========================================
uchar Put24c256BMP(uint dataddr)
{
unsigned char x,y,i,j,k,tempp;
x=0x80;
Start();
Wait(); //等待操作完成
if(TestACK()!=START){return 0;}
Writebyte(W_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_SLA_ACK){return 0;}
#if e2prom>=32
Writebyte(((dataddr&0xff00)>>8)); //写数据存储地址高八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
#endif
Writebyte(dataddr); //写数据存储地址低八位
Wait(); //等待操作完成
if(TestACK()!=MT_DATA_ACK){return 0;}
Start(); //重新启动IIC总线
Wait(); //等待操作完成
if(TestACK()!=RESTART){return 0;}
Writebyte(R_ADD_COM); //写器件地址
Wait(); //等待操作完成
if(TestACK()!=MT_RSLA_ACK){return 0;}
WriteCommand(0x34); //开图显
for(k=0;k<2;k++)
{
y=0x80;
for(j=0;j<32;j++)
{
WriteCommand(y); //写入列地址
WriteCommand(x); //写入行地址
for(i=0;i<16;i++)
{
WriteData(Readbyte());
}
y++;
}
x=0x88;
}
Twi_NoAcK(); //发送非应答信号
Wait(); //等待操作完成
if(TestACK()!=MT_RDATA_NACK){return 0;}
Stop(); //停止
WriteCommand(0x36); //开图显
}
//=========================================
// 主函数
// 任务:读取24c256中的图片数据
// 并在12864上循环显示
//=========================================
/*void main()
{
uchar i,data=0;
LcmInit(); //液晶初始化
Delay(10);
PORTB=0xff; //背光口开
LCD_ON; //开液晶背光显示
twi_init(); //TWI初始化
while(1)
{
for(i=0;i<7;i++)
{
Put24c256BMP(i*1024);
delay(1000);
}
}
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -