资讯详情

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

/******************************************************** 工程名称:AT_Mega16_master 创建日期:2007.10.21 程序编写:朱海峰 联系方式:543376422(QQ) 13405100406(手机) AT24C02存储一个字节,并读回校验,正确响一声,不正确响两声 AT24C02地址:0XA0 地址:0X01 TWI工作方式:查询方式 ********************************************************/ #include <iom16v.h> #include <macros.h> #define uint unsigned int #define uchar unsigned char #define A_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() D |= (1<<2);PORTD |= (1<<2); #define beep_off() DDRD |= (1<<2);PORTD &= ~(1<<2); //TWI读写操作公共步骤 #define _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_ALL_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 //没有相关的状态信息;TWI = “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++) ; } /*****************************

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台