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

24c32 CVAVR程序

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
#include     // 使用CVAVR的标准 Input/Output 函数
#include     // 使用CVAVR的延时函数

#define EEPROM_BUS_ADDRESS 0xa0      // 24C32地址

#define SCL      DDRC.0          // 24C32时钟线,PD0
#define SDA      DDRC.1          // 24C32数据线,PD1
#define SCL_Input    PINC.0          // 时钟输入
#define SDA_Input    PINC.1          // 数据输入
#define SCL_Output   PORTC.0         // 时钟输出
#define SDA_Output   PORTC.1         // 数据输出

#define SCL_Hight    SCL = 0         // 时钟线输出1,PD0输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
#define SCL_Low      SCL = 1         // 时钟线输出0,PD0输出方式。
#define SDA_Hight    SDA = 0         // 数据线输出1,PD1输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
#define SDA_Low      SDA = 1         // 数据线输出0,PD1输出方式。
#define I2C_Delay    delay_us(10)    // 延时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向24C32内部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个字节。 连续读

#define hc164_data PORTD.0  // 164数据线
#define hc164_clk  PORTD.1  // 164时钟线
void hc164_send_byte (unsigned char byte);  // 数码管显示   
unsigned char str[8]={1,3,5,7,2,4,6,8};     // 向24c32写入的8字节数组
unsigned char ledxs[8]={0,0,0,0,0,0,0,0};   // 数码管显示缓冲区
flash 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_ms(200);
   I2C_init ();  //  I2C初始化  
   DDRD = 0xff;
   for(i=0;i<8;i++)   //显示全0
   {
      hc164_send_byte (tab[ledxs[i]]);
      delay_us(2);
   }
   delay_ms(2000);
   I2C_pageWR (0x01ff,str,8);     // 24c32 01ffH地址开始写入8字节数据
   delay_ms(10);
   I2C_nbyteRD (0x01ff,ledxs,8);  // 读取24c32 01ffH地址开始的8字节数据
   for(i=0;i<8;i++)   // 显示读取信息
   {
      hc164_send_byte (tab[ledxs[i]]);
      delay_us(2);
   }
   while(1);
}

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

//-------------------------------------------------------------------
//CPU产生I2C起始信号,SCL高电平期间,SDA由1到0
//-------------------------------------------------------------------
void I2C_start (void)
{
  SDA_Hight;    // SDA=1;SDA输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
  I2C_Delay;     
  SCL_Hight;    // SCL=1;SCL输入方式,内部上拉电阻无效,引脚为高组态,由于外部上拉电阻,引脚呈现高电平。
  I2C_Delay;   
  SDA_Low;      // SDA=0;SDA输出方式,输出0 。       
  I2C_Delay;
  SCL_Low;      // SCL=0;SDA输出方式,输出0 。
  I2C_Delay; 
}
//----------------------------------------------------------------------
//CPU产生I2C结束信号,SCL高电平期间,SDA由0到1
//--------------------------------------------------------------------
void I2C_stop (void)
{
  SDA_Low;     //  SDA=0
  I2C_Delay;  
  SCL_Hight;   //  SCL=1
  I2C_Delay;
  SDA_Hight;   //  SDA=1
  I2C_Delay;  
  SCL_Low;     //  SCL=0
}

//--------------------------------------------------------------------------------------------------------------------------------------------
//CPU接收数据后,产生应答信号。I2C总线中,接收方产生应答或非应答信号,24c32自动产生,cpu需要调用程序
//--------------------------------------------------------------------------------------------------------------------------------------------
void I2C_CPU_ACK (void)
{
  SDA_Low;     //  SDA=0
  I2C_Delay;  
  SCL_Hight;   //  SCL=1
  I2C_Delay;
  SCL_Low;     //  SCL=0
  I2C_Delay;  
  SDA_Hight;   //  SDA=1
  I2C_Delay;       
}
//-------------------------------------------
//CPU接收数据后,产生非应答信号 
//------------------------------------------
void I2C_CPU_NACK (void)
{
  SDA_Hight;   //  SDA=1
  I2C_Delay;       
  SCL_Hight;   //  SCL=1
  I2C_Delay;
  SCL_Low;     //  SCL=0
  I2C_Delay;  
}
//----------------------------------------------------------------------------------------------------
//CPU向24C32发送一个字节(写数据或地址),并检查24C32发回的确认信号,

//返回标志位flag,0应答,1非应答。
//----------------------------------------------------------------------------------------------------
unsigned char I2C_Sendbyte (unsigned char data0)
{
  unsigned char j;
  unsigned char flag;
  for(j=0;j<8;j++)    //发送一个字节 (1次发送1位)
  {
    SCL_Low;     //  SCL=0
    I2C_Delay;  
    if(data0&0x80)   //取data0最高位
    {
       SDA_Hight;   //  SDA=1
       I2C_Delay;
    }       
    else
    {
       SDA_Low;     //  SDA=0
       I2C_Delay; 
    } 
    SCL_Hight;   //  SCL=1
    I2C_Delay;
    data0=data0<<1;  //data0左移1位
  }
//以下为检查24C32应答信号
  SCL_Low;     //  SCL=0
  I2C_Delay;  
  SDA_Hight;  //数据线拉高,准备读应答信号,同时数据线置输入状态
  I2C_Delay;
  SCL_Hight;   //  SCL=1
  I2C_Delay;
  if(SDA_Input)   //读应答信号   
    flag=1;
  else 
    flag=0;
  SCL_Low;     //  SCL=0
  I2C_Delay;  
  return flag;  //24C64正确接收,返回0(ACK);不正确接收,返回1(NOACK)。
}
//----------------------------------------------------------------------
//CPU接收24C64发送来的一个字节
//----------------------------------------------------------------------
unsigned char I2C_Receivebyte (void)
{
  unsigned i,data0;
  SCL_Low;     //  SCL=0
  I2C_Delay;  
  SDA_Hight;  //数据线拉高,准备接收数据位,同时数据线置输入状态
  I2C_Delay;
  for(i=0;i<8;i++)   //1次接收1位
  {
    data0=data0<<1;
    SCL_Hight;   //  SCL=1
    I2C_Delay;
    if(SDA_Input) data0=data0+1;  //接收数据存在最低位
    I2C_Delay;
    SCL_Low;     //  SCL=0
    I2C_Delay;
  }
  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_ms(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_ms(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 hc164_send_byte (unsigned char byte)
{
  unsigned char i;
   for(i=0;i<8;i++)
   {
      hc164_data = byte & ( 1 << i );       
      hc164_clk = 1;       
      hc164_clk = 0;   
   }  
}


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

发表评论:                              


验证码:点击我更换图片

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