×
单片机 > 单片机程序设计 > 详情

AT24CXX的mega8控制程序

发布时间:2020-08-21 发布时间:
|
/****************************************************************************************

                         AT24CXX的mega8控制程序   
                                                  
             程序功能:该程序是用AVR来控制对AT24C256
              读写信号等的操作.
             硬件连接:
    显示部分用12864液晶来显示从24c256中读取的图片
   
****************************************************************************************/
#include
#include
#include "st7920iccavrmega8.c"
#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< #define Stop()     (TWCR=(1< #define Wait()     while(!(TWCR&(1< #define TestACK()    (TWSR&0xF8)        //取出状态码
#define SetACK()    (TWCR|=(1< #define Twi_NoAcK()   {TWCR=BIT(TWINT)|BIT(TWEN);}    //非应答信号
#define Writebyte(twi_d) {TWDR=(twi_d);TWCR=(1< //========在此设定芯片地址=============
#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 // #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<  return(TWDR);

//==========毫秒延时============
void delay(uint ms)
{
    uint i,j;
 for(i=0;i  {
     for(j=0;j<1141;j++);
    }
}
//==========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  {
       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   {
         Writebyte(rdata[(i*PAGE_SIZE)+j]);//写一字节数据
         Wait();        //等待操作完成
   if(TestACK()!=MT_DATA_ACK){return 0;}
  }
  }
  else
  {
  for(j=0;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  {
     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);
  }
  
 }
}




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯