专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

ATmega16利用TWI模块读写24C02程序

作者:萧文   来源:本站原创   点击数:  更新时间:2014年04月01日   【字体:

/********************************************************
工程名称:AT_Mega16_master
创建日期:2007.10.21
程序编写:朱海峰
联系方式:543376422(QQ)       13405100406(手机)
AT24C02存储一个字节,并读回校验,正确蜂鸣器响一声,不正确响两声
AT24C02地址:0XA0
 EEPROM地址:0X01
TWI工作方式:查询方式
********************************************************/
#include <iom16v.h>
#include <macros.h>
#define uint unsigned int
#define uchar unsigned char
#define SLA_W               0xa0  //从机地址,主机写操作
#define SLA_R               0xa1  //从机地址,主机读操作
#define EE_address   0x01  //EEPROM地址     
#define Write_data   0x04  //写入的数据  
#define Baud_set   100   //TWI波特率设置
#define P_value    0x03  //预分频值
#define beep_on()   DDRD |= (1<<2);PORTD |= (1<<2);
#define beep_off()   DDRD |= (1<<2);PORTD &= ~(1<<2);
//TWI读写操作公共步骤
#define ST_FAIL    0 //出错状态
#define ST_START   1 //START状态检查
#define ST_SLAW    2 //SLAW状态检查
#define ST_WADDR   3 //ADDR状态检查
//TWI读操作步骤
#define ST_RESTART   4 //RESTART状态检查
#define ST_SLAR    5 //SLAR状态检查
#define ST_RDATA   6 //读取数据状态检查,循环n字节
//TWI写操作步骤
#define ST_WDATA   7 //写数据状态检查,循环n字节

#define FAIL_MAX   20 //重试次数最大值
/**********************I2C状态定义*************************/
/************************主机发送状态码********************/
#define TW_START    0x08 //START已发送
#define TW_REP_START   0x10 //重复START已发送
#define TW_MT_SLA_ACK   0x18 //SLA+W 已发送收到ACK
#define TW_MT_SLA_NACK   0x20 //SLA+W 已发送接收到NOT ACK
#define TW_MT_DATA_ACK   0x28 //数据已发送接收到ACK
#define TW_MT_DATA_NACK   0x30 //数据已发送接收到NOT ACK
#define TW_MT_ARB_LOST   0x38 //SLA+W 或数据的仲裁失败
/*************************主机接收状态码*****************/
//#define TW_START    0x08 //START已发送
//#define TW_REP_START   0x10 //重复START已发送
#define TW_MR_ARB_LOST   0x38 //SLA+R 或NOT ACK 的仲裁失败
#define TW_MR_SLA_ACK   0x40 //SLA+R 已发送接收到ACK
#define TW_MR_SLA_NACK   0x48 //SLA+R 已发送接收到NOT ACK
#define TW_MR_DATA_ACK   0x50 //接收到数据ACK 已返回
#define TW_MR_DATA_NACK   0x58 //接收到数据NOT ACK已返回
/************************从机接收状态码******************
#define TW_SR_SLA_ACK   0x60 //自己的SLA+W 已经被接收ACK已返回
#define TW_SR_ARB_LOST_SLA_ACK 0x68 //SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收ACK 已返回
#define TW_SR_GCALL_ACK   0x70 //接收到广播地址ACK 已返回
#define TW_SR_ARB_LOST_GCALL_ACK 0x78 //SLA+R/W 作为主机的仲裁失败;接收到广播地址ACK已返回
#define TW_SR_DATA_ACK   0x80 //以前以自己的SLA+W被寻址;数据已经被接收ACK已返回
#define TW_SR_DATA_NACK   0x88 //以前以自己的SLA+W被寻址;数据已经被接收NOT ACK已返回
#define TW_SR_GCALL_DATA_ACK 0x90 //以前以广播方式被寻址;数据已经被接收ACK已返回
#define TW_SR_GCALL_DATA_NACK 0x98 //以前以广播方式被寻址;数据已经被接收NOT ACK已返回
#define TW_SR_STOP    0xA0 //在以从机工作时接收到STOP或重复START
/*************************从发送状态码*******************
#define TW_ST_SLA_ACK   0xA8 //自己的SLA+R 已经被接收ACK 已返回
#define TW_ST_ARB_LOST_SLA_ACK 0xB0 //SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收ACK 已返回
#define TW_ST_DATA_ACK   0xB8 //TWDR 里数据已经发送接收到ACK
#define TW_ST_DATA_NACK   0xC0 //TWDR 里数据已经发送接收到NOT ACK
#define TW_ST_LAST_DATA   0xC8 //TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK
/****************************其它状态码*****************
#define TW_NO_INFO    0xF8 //没有相关的状态信息;TWINT = “0”
#define TW_BUS_ERROR   0x00 //由于非法的START 或STOP 引起的总线错误
 
/******************************************************/
void Chip_init(void);
void TWI_init(void);
void Delay_ms(uint ms);
/*****************************************************/
void main (void)
{
  uchar temp;
  CLI();
  Chip_init();
  TWI_init();
  Delay_ms(10);
  while(1)
  {
  beep_on();
  Delay_ms(1000);
  beep_off();
  Delay_ms(1000);
/************将0x04写入AT24C02内部的以0X01为地址的存储区****************/
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
  while (!(TWCR & (1<<TWINT)));  //0x08
  TWDR = SLA_W;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x18
  TWDR = EE_address;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x28
  TWDR = Write_data;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x28
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  Delay_ms(50);
/*********从AT24C02内部的以0X01为地址的存储区读出刚刚写入的数据*************/
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
  while (!(TWCR & (1<<TWINT)));  //0x08
  TWDR = SLA_W;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x18
  TWDR = EE_address;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT))); //0x28
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
  while (!(TWCR & (1<<TWINT)));  //0x10
  TWDR = SLA_R;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x40
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));  //0x58
  temp = TWDR;
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  if (temp == Write_data)
  {
      beep_on();
      Delay_ms(1000);
      beep_off();
      Delay_ms(1000);
  }
  else
  {
    beep_on();
   Delay_ms(1000);
   beep_off();
   Delay_ms(1000);
   beep_on();
   Delay_ms(1000);
   beep_off();
   Delay_ms(1000);
  }
  for(;;)
  NOP();
  }
}
/*****************************************************
函数名:Chip_init
作  用:芯片的初始化
*****************************************************/
void Chip_init()
{
  DDRD = 0X04;   //00001000---PD2:蜂鸣器   
 PORTD = 0X00;   //
}/****************************************************
函数名:TWI_init
作  用:TWI接口的初始化
*****************************************************/
void TWI_init(void)
{
     TWAR = 0x00;         //主机模式,该地址无效
     TWCR = 0x00;         //关闭TWI模块
  TWBR = Baud_set;        //100
  TWSR = P_value;         //64分频
}
/****************************************************/
void Delay_ms(uint ms)
{
  uint i,j;
 for(;ms>0;ms--)
  for(i = 0;i<100;i++)
  ;
}
/*****************************

关闭窗口

相关文章