当前位置:主页 > AVR单片机 > 24c32 ICC程序
201709/06

24c32 ICC程序

AVR单片机 Comments 围观:
/*****************************************************

File name           : 24c32.c
Chip type           : ATmega16
Program type        : Application
Clock frequency     : 4.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/
#include

//164数据线置1
#define hc164_data_SET     PORTD |= 0x01  
//164数据线清0 
#define hc164_data_CLR     PORTD &= ~0x01 
//164时钟线置1 
#define hc164_clk_SET      PORTD |= 0x02  
//164时钟线清0 
#define hc164_clk_CLR      PORTD &= ~0x02 

void delay_nms(unsigned int);   //延时 n ms  
void hc164_send_byte (unsigned char byte); //164发送数据子程序
void leddisplay(void);          // 数码管显示子程序   
#define EEPROM_BUS_ADDRESS 0xa0      // 24C32地址

#define SCL          0                  // 24C32时钟线,PD0
#define SDA          1                  // 24C32数据线,PD1
#define SCL_Input    PINC&(1< #define SDA_Input    PINC&(1< #define SCL_Output   PORTC &= ~(1< #define SDA_Output   PORTC &= ~(1<

#define SCL_Hight    DDRC &= ~(1< #define SCL_Low      DDRC |= 1< #define SDA_Hight    DDRC &= ~(1< #define SDA_Low      DDRC |= 1< //#define I2C_Delay    j=7;while(--j);    // 延时10us

void I2C_init (void);     // I2C初始化
void I2C_start (void);    // I2C起始
void I2C_stop (void);     // I2C结束
void I2C_CPU_ACK (void);  // CPU应答
void I2C_CPU_NACK (void); // CPU非应答
unsigned char I2C_Sendbyte (unsigned char data0); // CPU向24c32发送一个字节
unsigned char I2C_Receivebyte (void);             // CPU从24c32接收一个字节 
//void I2C_byteWR (unsigned int address,unsigned char data0); // CPU向24C64内部EEPROM写入一个字节  (写1个字节数据过程)
void I2C_pageWR (unsigned int address,unsigned char *p1,unsigned char count);  // CPU向24C32内部EEPROM写入一页字节,一次最多32个字节。
void I2C_nbyteRD (unsigned int address,unsigned char *p2,unsigned char count); // CPU从24C32内部EEPROM读取n个字节。 连续读

 
unsigned char str[8]={2,0,0,8,1,0,1,8};     // 向24c64写入的8字节数组
unsigned char ledxs[8]={0,0,0,0,0,0,0,0};   // 数码管显示缓冲区
const unsigned char tab[] = {0xb7,0x12,0x67,0x76,0xd2,0xf4,0xf5,0x16,0xf7,0xf6,0xd7,0xf1,0xa5,0x73,0xe5,0xc5,0,0xff};
                          //共阴极代码 0-F,  全灭,全亮

void main(void)
{
   unsigned char i; 
   delay_nms(200);
   I2C_init ();      //  I2C初始化  
   DDRD = 0xff;
   leddisplay();     //显示全0
   delay_nms(2000);
   I2C_pageWR (0x1000,str,8);        // 24c32 1000H地址开始写入8字节数据
   delay_nms(10);
   I2C_nbyteRD (0x1000,ledxs,8);     // 读取24c32 1000H地址开始的8字节数据
   leddisplay();     // 显示读取信息
   while(1);
}

void I2C_init (void) // I2C初始化
{  
    SCL_Output;  // SCL的PORT状态锁定为0。输出方式,输出0;输入方式,内部上拉电阻无效。
    SDA_Output;  // SDA的PORT状态锁定为0。输出方式,输出0;输入方式,内部上拉电阻无效。
    SCL_Hight;   // SCL输入方式,输出1 
    SDA_Hight;   // SDA输入方式,输出1 
}

//---------------------------------------------
//CPU产生I2C起始信号,SCL高电平期间,SDA由1到0
//---------------------------------------------
void I2C_start (void)
{
  unsigned char j;
  SDA_Hight;    // SDA=1;SDA输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
  j=7;while(--j);  // 延时10us ( 一个循环6个周期,4M晶振,延时1.5us ) 
  SCL_Hight;    // SCL=1;SCL输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
  j=7;while(--j);  
  SDA_Low;      // SDA=0;SDA输出方式,输出0 。       
  j=7;while(--j);
  SCL_Low;      // SCL=0;SDA输出方式,输出0 。
  j=7;while(--j); 
}
//---------------------------------------------
//CPU产生I2C结束信号,SCL高电平期间,SDA由0到1
//---------------------------------------------
void I2C_stop (void)
{
  unsigned char j;
  SDA_Low;     //  SDA=0
  j=7;while(--j);  
  SCL_Hight;   //  SCL=1
  j=7;while(--j);
  SDA_Hight;   //  SDA=1
  j=7;while(--j);  
  SCL_Low;     //  SCL=0
  j=7;while(--j);
}

//---------------------------------------------------------------------------------------------------
//CPU接收数据后,产生应答信号。I2C总线中,接收方产生应答或非应答信号,24c64自动产生,cpu需要调用程序
//---------------------------------------------------------------------------------------------------
void I2C_CPU_ACK (void)
{
  unsigned char j;
  SDA_Low;     //  SDA=0
  j=7;while(--j);  
  SCL_Hight;   //  SCL=1
  j=7;while(--j);
  SCL_Low;     //  SCL=0
  j=7;while(--j);  
  SDA_Hight;   //  SDA=1
  j=7;while(--j);      
}
//-----------------------------
//CPU接收数据后,产生非应答信号 
//-----------------------------
void I2C_CPU_NACK (void)
{
  unsigned char j;
  SDA_Hight;   //  SDA=1
  j=7;while(--j);      
  SCL_Hight;   //  SCL=1
  j=7;while(--j);
  SCL_Low;     //  SCL=0
  j=7;while(--j); 
}
//---------------------------------------------------------------------------------------------------
//CPU向24C32发送一个字节(写数据或地址),并检查24C32发回的确认信号,返回标志位flag,0应答,1非应答。
//---------------------------------------------------------------------------------------------------
unsigned char I2C_Sendbyte (unsigned char data0)
{
  unsigned char i,j;
  unsigned char flag;
  for(i=0;i<8;i++)    //发送一个字节 (1次发送1位)
  {
    SCL_Low;     //  SCL=0
    j=7;while(--j);  
    if(data0&0x80)   //取data0最高位
    {
       SDA_Hight;   //  SDA=1
       j=7;while(--j);
    }       
    else
    {
       SDA_Low;     //  SDA=0
       j=7;while(--j); 
    } 
    SCL_Hight;   //  SCL=1
    j=7;while(--j);
    data0=data0<<1;  //data0左移1位
  }
//以下为检查24C32应答信号
  SCL_Low;     //  SCL=0
  j=7;while(--j);  
  SDA_Hight;  //数据线拉高,准备读应答信号,同时数据线置输入状态
  j=7;while(--j);
  SCL_Hight;   //  SCL=1
  j=7;while(--j);
  if(SDA_Input)   //读应答信号   
    flag=1;
  else 
    flag=0;
  SCL_Low;     //  SCL=0
  j=7;while(--j);  
  return flag;  //24C64正确接收,返回0(ACK);不正确接收,返回1(NOACK)。
}
//----------------------------------------------------------------------
//CPU接收24C64发送来的一个字节
//----------------------------------------------------------------------
unsigned char I2C_Receivebyte (void)
{
  unsigned i,j,data0;
  SCL_Low;     //  SCL=0
  j=7;while(--j);  
  SDA_Hight;  //数据线拉高,准备接收数据位,同时数据线置输入状态
  j=7;while(--j);
  for(i=0;i<8;i++)   //1次接收1位
  {
    data0=data0<<1;
    SCL_Hight;   //  SCL=1
    j=7;while(--j);
    if(SDA_Input) data0=data0+1;  //接收数据存在最低位
    j=7;while(--j);
    SCL_Low;     //  SCL=0
    j=7;while(--j);
  }
  return data0;      //返回接收的数据
}
//-------------------------------------------------------
//CPU向24C32内部EEPROM写入一个字节  (写1个字节数据过程)
//-------------------------------------------------------
/*void I2C_byteWR (unsigned int address,unsigned char data0)
{               //  24c64内部单元地址,             数据
  unsigned char flag;
  I2C_start();    //CPU发起始信号
  flag=I2C_Sendbyte(EEPROM_BUS_ADDRESS);    //CPU发器件地址
    while(flag) {I2C_Sendbyte(0xa0);}   //检查确认信号,不正确则重发
  flag=I2C_Sendbyte(address/256);     //CPU发ROM高八位地址
    while(flag) {I2C_Sendbyte(address/256);}
  flag=I2C_Sendbyte(address%256);     //CPU发ROM低八位地址
    while(flag) {I2C_Sendbyte(address%256);}
  flag=I2C_Sendbyte(data0);        //CPU发送数据
    while(flag) {I2C_Sendbyte(data0);}
  I2C_stop();     //CPU发结束信号
  delay_nms(10);
}  */
//-----------------------------------------------------------------------
//CPU向24C32内部EEPROM写入一页字节,一次最多32个字节。  (写1页数据过程)
//-----------------------------------------------------------------------
void I2C_pageWR (unsigned int address,unsigned char *p1,unsigned char count)
{           //  24c64内部起始单元地址,  数据缓冲区地址        写入字节个数
  unsigned char flag;
  I2C_start();     //CPU发起始信号
  flag=I2C_Sendbyte(EEPROM_BUS_ADDRESS);    //CPU发器件地址
    while(flag) {I2C_Sendbyte(0xa0);} //检查确认信号,不正确则重发
  flag=I2C_Sendbyte(address/256);   //CPU发ROM起始单元高八位地址
    while(flag) {I2C_Sendbyte(address/256);}
  flag=I2C_Sendbyte(address%256);   //CPU发ROM起始单元低八位地址
    while(flag) {I2C_Sendbyte(address%256);}
  while(count--)
  {
    flag=I2C_Sendbyte(*p1); // 发送1个数据
    while(flag) {I2C_Sendbyte(*p1);}  //检查确认信号,不正确则重发
    p1++;   //修改指针
  }
  I2C_stop();  //CPU发结束信号
  delay_nms(10);
}
//------------------------------------------------------------------------
//CPU从24C32内部EEPROM读取n个字节。 连续读
//------------------------------------------------------------------------
void I2C_nbyteRD (unsigned int address,unsigned char *p2,unsigned char count)
{            //  24c64内部起始单元地址,  数据缓冲区地址       读取字节个数
  unsigned char flag;
  //以下是伪写
  I2C_start();   //CPU发起始信号
  flag=I2C_Sendbyte(EEPROM_BUS_ADDRESS);  //CPU发器件地址
    while(flag) {I2C_Sendbyte(0xa0);}
  flag=I2C_Sendbyte(address/256);  //CPU发ROM起始单元高八位地址
    while(flag) {I2C_Sendbyte(address/256);}
  flag=I2C_Sendbyte(address%256);  //CPU发ROM起始单元低八位地址
    while(flag) {I2C_Sendbyte(address%256);}
  //以下是读n个字节
  I2C_start();   //CPU发起始信号
  flag=I2C_Sendbyte(0xa1);   //CPU发器件地址
    while(flag) {I2C_Sendbyte(EEPROM_BUS_ADDRESS | 0x01);}
  while(--count)   //读取 count-1 个数据
  {
    *p2=I2C_Receivebyte();  // 读取1个数据
    I2C_CPU_ACK();   //cpu发应答信号
    p2++;    //修改指针
  }
  *p2=I2C_Receivebyte();  // 读取第 count 个数据
  I2C_CPU_NACK();   // cpu发送非应答信号
  I2C_stop();   //CPU发结束信号
}
void leddisplay()     // 数码管显示子程序
{
  unsigned char i,j;
  for(i=0;i<8;i++)
  {
     hc164_send_byte (tab[ledxs[i]]);
     j=2;while(--j);
  }

void hc164_send_byte (unsigned char byte)  //164发送数据子程序
{
  unsigned char i;
   for(i=0;i<8;i++)
   {
      if( byte & ( 1 << i )) 
     hc164_data_SET;
   else 
     hc164_data_CLR;
      hc164_clk_SET;
      hc164_clk_CLR;   
   }  

void delay_nms(unsigned int k)  //延时 n ms
{
  while(k)   //4M晶振,一个循环1ms
  {
  int i;
  i=700;
  while(i--);
  k=k-1;
  }
}


文章作者:
本文地址:
版权所有 © 未注明“转载”的博文一律为原创,转载时必须以链接形式注明作者和原始出处!
如果你觉得文章不错,您可以推荐给你的朋友哦!

◇◇上一篇:atmega16片上AD ICC程序 下一篇:AVR熔丝位设置大全 ◇◇

发表评论:                              


验证码:点击我更换图片

来看看其他人说了些什么?-----------------------------------------------------------------> 进入详细评论页