ATMEGA16读写iic(TWI)(24c02) C语言程序
24C02读写C程序

//选择性读操作,从 address 地址中读出 1 个字节 uchar Read24c02(uchar address) {
uchar ch; //伪写操作 Start(); Write8Bit(WriteDeviceAddress); //发送从器件地址,且方式为写。 while(TestAck()); Write8Bit(address); while(TestAck());
}
//从 24c02 中读出 8 个 bit uchar Read8Bit() {
unsigned char temp,rbyte=0; for(temp=8;temp!=0;temp--) {
SCL=1; rbyte=rbyte<<1; rbyte=rbyte|((unsigned char)(SDA)); SCL=0; } return(rbyte); }
#define WriteDeviceAddress 0xa0 #define ReadDeviceAddress 0xa1 sbit SCL=P2^7; sbit SDA=P2^6;
//定义器件在 IIC 总线中的地址,且方式为写 //定义器件在 IIC 总线中的地址,且方式为读
sbit P10=P1Stop();
//主机产
生停止信号 return(ch);
}
//本课试验写入一个字节到 24c02 并读出来
void main(void) // 主程序 {
uchar c1,c2; c1=Read24c02(0x02);
//从 24c02 中读出 1 个字节
Write24c02(0x88,0x03); c2=Read24c02(0x03); P3=c2;
24C02读写C程序
51单片机IIC总线操作及24c02指定地址的读写

51单片机IIC总线操作及24c02指定地址的读写51单片机IIC总线操作及24c02指定地址的读写(单片机用STC89C58RD+)//24c02数据读写操作。
程序实现每一秒钟往24c02的指定地址内写入数据(既每一秒钟保存一次当前值)。
//共计时100秒,计时同步显示到数码管上,同时由8个led灯指示十位数的编码值。
//两个按键:单片机上电后按key6按键读取上次关机时存储到24c02内的数据,接着此数据继续计时显示。
//按key5按键计时停止。
#include#include#define uchar unsigned char#define sda P20 //24c02数据接到P2.0口#define scl P21 //24c02时钟接到P2.1口//sbit sda=P2^0;//sbit scl=P2^1;sbit key6=P3^7;sbit key5=P3^6;uchar cont=0;uchar write=0; //标志位uchar code table[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0};void delay(){_nop_();_nop_();_nop_();}void delay1(uchar x){uchar a,b;for(a=x;a>0;a--)for(b=100;b>0;b--);}/***以下为24c02的IIC总线操作及读写数据的通用程序,IIC总线部分的程序可以用在其他IIC器件中参考郭天祥新概念51c语言***/void start() //开始{sda=1;delay();scl=1;delay();sda=0;delay();}void stop() //停止{sda=0;delay();scl=1;delay();sda=1;delay();}void respons() //应答{uchar i;delay();while((sda==1)&&(i<250))i++; scl=0;delay();}void init(){sda=1;delay();scl=1;delay();}void write_byte(uchar date) {uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;scl=0;delay();sda=CY;delay();scl=1;delay();// scl=0;// delay();}scl=0;sda=1;delay();}uchar read_byte(){uchar i,k;scl=0;delay();sda=1;delay();for(i=0;i<8;i++){scl=1;delay();k=(k<<1)|sda;scl=0;delay();}return k;}void write_add(uchar address,uchar date) //24c02任一地址写入数据{start();write_byte(0xa0);respons();write_byte(address);respons();write_byte(date);respons();}uchar read_add(uchar address) //24c02任一地址读取数据{uchar date;start();write_byte(0xa0);respons();write_byte(address);respons();start();write_byte(0xa1);respons();date=read_byte();stop();return date;}/***以上为24c02的IIC总线操作及读写数据的通用程序,IIC总线部分的程序可以用在其他IIC器件中参考郭天祥新概念51c语言***/void display(uchar shi,uchar ge) //显示子程序,P0口为数码管段{P0=table[shi];P27=0;delay1(5);P27=1;P0=table[ge];P26=0;delay1(5);P1=table[shi]; //led指示灯按十位数变化相应亮灭}void main(){uchar keyscan;init();cont=read_add(36);if(cont==100)cont=0;TMOD=0X01; //ding shi qi gong zuo zai fang shi 1.EA=1;ET0=1;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TR0=1; //启动定时器0P3=P3|0xfc; //11111100 置位按键位,p3口除p3.0和p3.1外接有6个按键keyscan=P3;switch(keyscan|0x03){case 0x7f: //如果key6被按下{while(key5!=0){display(cont/10,cont%10); //分解为十位数和个位数if(write==1){write=0;write_add(36,cont); //每1s写入数据cont到36地址处(地址0~255可任选)}}break;}case 0xbf: //如果key5被按下{while(key6!=0){TR0=0; //停止定时器read_add(36); //读取36号地址处数据静态显示display(cont/10,cont%10);}break;}}}void timer0() interrupt 1{uchar temp;TH0=(65536-50000)/256; //50ms中断初值,晶振12MHzTL0=(65536-50000)%256;temp++;if(temp==20) //temp每中断20次为1s(50ms*20=1000ms=1s) {temp=0;cont++; //每1s时间到cont加一write=1; //到1s时标志位置一,开始往24c02里写入数据if(cont==100)cont=0; //100s时间到从00重新开始计时} }。
外部存储器24c02的读写操作..

/*------51单片机-----------------------名称:外部存储器24c02..芯片:STC89C51..邮箱:MG_TCCX@QQ:2424488418编写:C.ROOKIE日期:2012.9.13 (21:31)内容:定义一个数组,把数组的数据写入24c02存储,然后清楚数组,把24c02的数据读取到数组里,然后显示在数码管上..--------------------------------------*/#include<reg52.h>#include<intrins.h> //这个文件里有空操作指令..#define _Nop() _nop_() //定义空操作指令..unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~Funsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码sbit SCL=P2^0; //模拟IIC总线时钟控制位。
sbit SDA=P2^1; //模拟IIC总线数据传送位。
sbit LATCH1=P2^2; //数码管段选。
sbit LATCH2=P2^3; //数码管位选。
bit ack; //模拟应答标志位。
//声明延时程序。
void DelayUs(unsigned char);void DelayMs(unsigned char);//定义延时程序。
void DelayUs(unsigned char t){while(--t){}}void DelayMs(unsigned char t){while(--t){DelayUs(245);DelayUs(245);}}//启动IIC总线..void Start_IIC(){SDA=1; //SCL=1的情况下,SDA从高电平到低电平就能启动IIC总线.. _Nop();SCL=1; //起始条件建立的时间大概4.7us .._Nop();_Nop();_Nop();_Nop();_Nop();SDA=0; //已经启动IIC总线.._Nop(); //起始条件锁定时间大概4.7us .._Nop();_Nop();_Nop();_Nop();SCL=0; //钳住IIC总线。
24c02读写程序大全

24c02读写程序大全2C总线的应用(24C02子程序)// 对24C02的读、写// extern void DelayMs(unsigned int);// extern void Read24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);// extern void Write24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);/***************************************************************************/#define WriteDeviceAddress 0xa0#define ReadDviceAddress 0xa1#include <reg52.h>#include <stdio.h>#include <absacc.h>/***************************************************************************/sbit SCL=P2^7;sbit SDA=P2^6;bit DOG;/***************************************************************************/void DelayMs(unsigned int number) {unsigned char temp;for(;number!=0;number--,DOG=!DOG) {for(temp=112;temp!=0;temp--) {}}}/***************************************************************************/void Start() {SDA=1;SCL=1;SDA=0;SCL=0;}/***************************************************************************/void Stop() {SCL=0;SDA=0;SDA=1;}/***************************************************************************/void Ack() {SDA=0;SCL=1;SCL=0;SDA=1;}/***************************************************************************/void NoAck() {SDA=1;SCL=1;SCL=0;}/***************************************************************************/bit TestAck() {bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/***************************************************************************/void Write8Bit(unsigned char input) {unsigned char temp;for(temp=8;temp!=0;temp--) {SDA=(bit)(input&0x80);SCL=1;SCL=0;input=input<<1;}}/***************************************************************************/void Write24c02(unsigned char *Wdata,unsigned char RomAddress,unsign ed char number) {Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();for(;number!=0;number--) {Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/***************************************************************************/ unsigned char Read8Bit() {unsigned char temp,rbyte=0;for(temp=8;temp!=0;temp--) {SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA));SCL=0;}return(rbyte);}/***************************************************************************/void Read24c02(unsigned char *RamAddress,unsigned char RomAddress, unsigned char bytes) {//unsigned char temp,rbyte;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDviceAddress);TestAck();while(bytes!=1) {*RamAddress=Read8Bit();RamAddress++;bytes--;}*RamAddress=Read8Bit();NoAck();Stop();}[单片机应用]24c02的读写程序电子工匠发表于2007-1-4 22:33:07;---------------从24C02整组读数据RD_INI: LCALL DELAYRD_AREA: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITE ;24C02信息的读入LCALL DELAYLCALL ACKLCALL DELAYJC RD_AREAMOV R2, #8CLR P1.7 ;起始地址为00 ADDR_0: LCALL DELAYLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, ADDR_0LCALL ACKLCALL DELAYJC RD_AREALCALL DELAYLCALL STARTMOV R0, #SAVE0MOV R3, #8 ;6个字节LCALL DELAYLCALL READLCALL DELAYLCALL ACKJC RD_AREARD_R_0: LCALL DELAYLCALL DELAYLCALL RD_INFOLCALL DELAYINC R0DJNZ R3, RD_R_1lcall ack_2lcall delayLCALL STOPRETrd_r_1: lcall ack_1sjmp rd_r_0;---------------向24C02整组写数据WR_INI: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITELCALL DELAYLCALL ACKLCALL DELAYJC WR_INICLR P1.7MOV R2, #8WR_W_0: LCALL DELAY ;写地址SETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_W_0LCALL DELAYLCALL ACKLCALL DELAYJC WR_INIMOV R0, #SAVE0MOV R3, #8 ;6个字节WR_W_1: LCALL WR_INFOLCALL DELAYLCALL ACKLCALL DELAYJC WR_INIINC R0DJNZ R3, WR_W_1LCALL DELAYLCALL STOPRET;---------------24C02启动START: SETB P1.7SETB P1.6LCALL DELAYCLR P1.7LCALL DELAYCLR P1.6RET;---------------24C02读命令字;片选为"00";---------------------------- READ: MOV A, #10100001B MOV R2, #8RD1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, RD1RET;---------------24C02写命令字;片选为"00";---------------------------- WRITE: MOV A, #10100000B MOV R2, #8WR1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6CLR P1.7LCALL DELAYDJNZ R2, WR1RET;---------------24C02结束命令字STOP: CLR P1.7LCALL DELAYSETB P1.6LCALL DELAYSETB P1.7LCALL DELAYCLR P1.6RET;---------------24C02的应答信息ACK: SETB P1.7SETB P1.6LCALL DELAYmov a, p1MOV C, a.7LCALL DELAYCLR P1.6RETack_1: CLR P1.7 ;应答SETB P1.6lcall delayCLR P1.6lcall delaySETB P1.7lcall delayRETack_2: SETB P1.7 ;非应答SETB P1.6lcall delayCLR P1.6CLR P1.7lcall delayRET;---------------24C02的读;R0:数据的存储地址;-------------------------------- RD_INFO: SETB P1.7LCALL DELAYMOV R2, #8MOV R7, #0MOV A, #0RD_I_0: SETB P1.6LCALL DELAYMOV A, P1MOV C, A.7LCALL DELAYCLR P1.6MOV A, R7RLC AMOV R7, ALCALL DELAYDJNZ R2, RD_I_0MOV @R0, ARET;---------------24C02的写;R0:数据的写数据地址;-----------------------------------WR_INFO: MOV A, @R0MOV R2, #8WR_O_0: RLC AMOV P1.7, CLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_O_0RET24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。
I2C24LC02C读写例程(PIC单片机)

I2C24LC02C读写例程(PIC单片机)I2C 24LC02 C读写例程(PIC单片机)[单片机]发布时间:2008-04-22 10:11:001 I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
2 I2C总线工作原理I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。
如果SCL处于高电平时,SDA 上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。
通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。
同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。
每次数据传输都是以一个起始位开始,而以停止位结束。
传输的字节数没有限制。
最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。
数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。
这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。
从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。
AVR单片机IIC读写范例IIC.C 或者IIC.H

资料简介:本程序简单的示范了如何使用ATMEGA16的TWI 读写AT24C02 IIC EEPROM TWI协议(即IIC协议,请认真参考IIC协议的内容,否则根本就不能掌握)一主多从的应用,M16作主机(M16做从机和多主多从的应用不多,请自行参考相关文档)中断模式(因为AVR的速度很高,而IIC的速度相对较低,采用查询模式会长时间独占CPU,令CPU的利用率明显下降。
特别是IIC速度受环境影响只能低速通讯时,对系统的实时性产生严重的影响。
查询模式可以参考其它文档和软件模拟IIC的文档)AT24C02/04/08的操作特点出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器*/#include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <avr/delay.h>//时钟定为外部晶振7.3728MHz,F_CPU=7372800#include <compat/twi.h>//定义了各种模式下的状态码列表(TWSR已屏蔽预分频位),本文后面附上中文描述//管脚定义#define pinSCL0//PC0 SCL#define pinSDA1//PC1 SDA//为保险起见,最好在SCL/SDA接上1~10K的外部上拉电阻到VCC。
#define fSCL100000//TWI时钟为100KHz//预分频系数=1(TWPS=0)#if F_CPU < fSCL*36#define TWBR_SET 10;//TWBR必须大于等于10#else#define TWBR_SET(F_CPU/fSCL-16)/2;//计算TWBR值#endif#define TW_ACT(1<<TWINT)|(1<<TWEN)|(1<<TWIE)//TWCR只能IN/OUT,直接赋值比逻辑运算(|= &=)更节省空间#define SLA_24CXX0xA0//24Cxx系列的厂商器件地址(高四位)#define ADDR_24C020x00// AT24C02的地址线A2/1/0全部接地,SLAW=0xA0+0x00<<1+0x00,SLAR=0xA0+0x00<<1+0x01 //TWI_操作状态#define TW_BUSY0#define TW_OK 1#define TW_FAIL 2//TWI_读写命令状态#define OP_BUSY0#define OP_RUN 1//TWI读写操作公共步骤#define ST_FAIL0//出错状态#define ST_START1//START状态检查#define ST_SLAW2//SLAW状态检查#define ST_WADDR3//ADDR状态检查//TWI读操作步骤#define ST_RESTART4//RESTART状态检查#define ST_SLAR5//SLAR状态检查#define ST_RDATA6//读取数据状态检查,循环n字节//TWI写操作步骤#define ST_WDATA7//写数据状态检查,循环n字节#define FAIL_MAX20//重试次数最大值//定义全局变量unsigned char ORGDATA[8]={0xAA,0xA5,0x55,0x5A,0x01,0x02,0x03,0x04};//原始数据unsigned char CMPDATA[8];//比较数据unsigned char BUFFER[256];//缓冲区,可以装载整个AC24C02的数据struct str_TWI//TWI数据结构{volatile unsigned char STATUS;//TWI_操作状态unsigned char SLA;//从设备的器件地址unsigned int ADDR;//从设备的数据地址unsigned char*pBUF;//数据缓冲区指针unsigned int DATALEN;//数据长度unsigned char STATE;//TWI读写操作步骤unsigned char FAILCNT;//失败重试次数};struct str_TWI strTWI;//TWI的数据结构变量//仿真时在watch窗口,监控这些全局变量。
24c02参考实例程序

{
Scl=0; _nop_();_nop_();_nop_();_nop_();_nop_(); Scl=1; _nop_();_nop_();_nop_();_nop_();_nop_(); if(Sda)
temp=temp|0x01; else
temp=temp&0xfe;
if(BitCounter-1) { temp1=temp<<1; temp=temp1; } BitCounter--; }
Ack();
*(PData+i)=Read();//读数据
Scl=0;
NoAck();
Stop();
}
}
/*------------------------------------------------
主程序
------------------------------------------------*/
sbit Sda=P1^2; sbit Scl=P1^1; sbit WP=P1^0;
//定义总线连接端口 //写保护,这里不使用
/*-----------------------------------------------延时程序
------------------------------------------------*/ void mDelay(unsigned char j) { unsigned int i; for(;j>0;j--) { for(i=0;i<125;i++) {;} } }
void main()
{
unsigned char Number[4]={0x06,0x5b,0x4f,0x66};// 显示码值 1234
24c02读写实验c程序

Init();//初始化
DispBuf[2]=Hidden;
DispBuf[3]=Hidden;
for(;;)
{
Calc(RecBuf[1],RomDat[0]);//分别显示地址和数据
if(Rec)//接收到数据
{Rec=0;//清除标志
if(RecBuf[0]==0)//第一种功能,写入
TR1=1;
}
void Calc(uchar Dat1,uchar Dat2)//第一个参数放在第1、2位,第二个参数放入第5、6位
{DispBuf[0]=Dat1/16;
DispBuf[1]=Dat1%16;
DispBuf[4]=Dat2/16;
DispBuf[5]=Dat2%16;
}
void main()
/**************************************************
24C02.C
功能描述:
PC端发送3个数据n0,n1,n2.
n0=0,写,将n1写入n2地址中
n0=1,读,读出n1地址中的数据,n2不起作用,但必须有
收到一个字节后,将其地址值显示在数码管第1、2位上,数值显示在第5、6位上
sbit we=P2^7;
sbit du=P2^6;
uchar code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code disptab[]={0x3f,0x6,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
Rec=1;//置位标志
C语言程序写入按键次数到24c02,并读出来显示在4个LED上

Write8Bit(ch);
TestAck();
Stop();
DelayMs(10);
}
//从24c02中读出8个bit
uchar Read8Bit()
{
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--)
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h> //包括一个52标准内核的头文件
char code dx516[3] _at_ 0x003b;//这是为了仿真设置的
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Start();
Write8Bit(ReadDviceAddress);
TestAck();
ch=Read8Bit();
NoAck();
Stop();
{
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
}
//从24c02中读出1个字节
uchar Read24c02(uchar address)
{
uchar ch;
ATMEGA16读写iic(TWI)(24c02) C语言程序

ATMEGA16读写iic(24c02) C语言程序测试通过#include <iom16v.h>#include "I2C.h"#include "1602.h"#include "delay.h"/*通过AVR往I IC写数据,并通过串口把数据读出显示出来*///===============================================================void UART_init(void) //UART初始化{ DDRD = 0x02;PORTD = 0x00;UCSRA = 0x02; /*无倍速*/UCSRB = 0x18; /*允许接收和发送*/UC SRC = 0x06; /*8位数据,1位停止位,无校验*/UBRRH = 0x00;UBRRL = 12; /*9600*/}//===============================================================void USART_TXD(float data) //发送采用查询方式{while( !(UCSRA & BIT(UDRE)) );UDR=data;while( !(UCSRA & BIT(TXC )) );UCSRA|=BIT(TXC);}void main(void){unsigned char i;//LCD_init();uart_init();//TART初始化SEI(); //全局中断使能while(1){/*I2C_Write('n',0x00);I2C_Write('c',0x01);I2C_Write('e',0x02);I2C_Write('p',0x03);I2C_Write('u',0x04);*/i=I2C_Read(0x00);//LCD_write_char(0,0,i); USART_TXD(i);i=I2C_Read(0x01);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x02);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x03);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x04);//LCD_write_data(i);USART_TXD(i);}}/*上面上主函数部分*/#include <macros.h>#include "delay.h"//I2C 状态定义//MT 主方式传输 MR 主方式接受#define START 0x08#define RE_START 0x10#define MT_SLA_ACK 0x18#define MT_SLA_NOACK 0x20#define MT_DATA_ACK 0x28#define MT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40#define MR_SLA_NOACK 0x48#define MR_DATA_ACK 0x50#define MR_DATA_NOACK 0x58#define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位#define WD_DEVICE_ADDR 0xA0//常用TWI操作(主模式写和读)#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C#define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生#define TestAck() (TWSR&0xf8) //观察返回状态#define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答#define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDRunsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress); unsigned char I2C_Read(unsigned RegAddress);/*********************************************I2C总线写一个字节返回0:写成功返回1:写失败**********************************************/unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress){Start(); //I2C启动Wait();if(TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if(TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKWrite8Bit(Wdata); //写数据到器件相应寄存器Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKStop(); //I2C停止delay_nms(10); //延时return 0;}/*********************************************I2C总线读一个字节返回0:读成功返回1:读失败**********************************************/ unsigned char I2C_Read(unsigned RegAddress){unsigned char temp;Start();//I2C启动Wait();if (TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if (TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if (TestAck()!=MT_DATA_ACK)return 1;Start(); //I2C重新启动Wait();if (TestAck()!=RE_START)return 1;Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式Wait();if(TestAck()!=MR_SLA_ACK)return 1; //ACKTwi(); //启动主I2C读方式Wait();if(TestAck()!=MR_DATA_NOACK)return 1; //ACKtemp=TWDR;//读取I2C接收数据Stop();//I2C停止return temp;}/*以上是IIC.h头文件部分,需要对照技术文档好好研究*/*----------------------------------------------------------------------- 延时函数编译器:I CC-AVR v6.31A 日期: 2005-11-24 20:29:57目标芯片 : M16时钟: 8.0000M Hz作者:archeng504-----------------------------------------------------------------------*/ #ifndef __delay_h#define __delay_hvoid delay_nus(unsigned int n);void delay_nms(unsigned int n);void delay_1us(void);void delay_1ms(void) ;void delay_1us(void) //1us延时函数{asm("nop");}void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1us();}void delay_1ms(void) //1ms延时函数{unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}#endif/*以上是delay.h部分,再加上IIC中自带的iom16v.h 和macros.h就可以编译通过*//*注意点:本程序在实验板ATMEGA16上测试通过,在示波器把SCL,SDA信号线有数据,移值到自己电路上可以放心使用,在ATMEGA32上一样使用,本人24C02的A2,A1,A0都是接地,若地址不一样,在程序相应位置改一下就可以,串口上调试单片机的基础,所以它一定要会用*//*本程序调试软件环境是ICC6.31*/。
五、ATmega16通过TWI(兼容I2C)操作24C02

12
#define I2C_SetAck (TWCR|=(1<<TWEA)) //做出 ACK 应答 #define I2C_SetNoAck (TWCR&=~(1<<TWEA)) //做出 Not Ack 应答 #define I2C_Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动 I2C #define I2C_Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到 TWDR #define RD_DEVICE_ADDR 0xA1 #define WD_DEVICE_ADDR 0xA0 //前 4 位器件固定,后三位看连线,最后 1 位是读写指令位
6
if(Flag[3]==1) Flag[3]=I2C_Write('D',0x80+0x03); if(Flag[3]==0) break; } while(1) { Flag[4]=I2C_Write('E',0x80+0x04); if(Flag[4]==1) Flag[4]=I2C_Write('E',0x80+0x04); if(Flag[4]==0) break; } DDRC&=~(1<<PC1); Delay_ms(1000);//写和读之间的延时 Flag[0]=0;Flag[1]=0;Flag[2]=0;Flag[3]=0;Flag[4]=0; while(1) { Flag[0]=I2C_Read(0x80+0x00); if(Flag[0]==0) Flag[0]=I2C_Read(0x80+0x00); else {k[0]=Flag[0];break;} }Delay_ms(20); while(1)
24C02(IIC)读写操作

1. AT24C02写操作首先我们来看一下写AT24C02。
一般步骤是:1) 发送起始信号2) 发送写器件地址3) 等待应答4) 发送要写入的24C02 的地址5) 等待应答6) 发送要写入的数据7) 等待应答8) 发送数据结束发送结束信号具体程序如下:/****************************************************************************** ** 函数名: AT24Cxx_WriteOneByte* 函数功能: 24c02写一个字节地址数据* 输入: addr dt* 输出: 无********************************************/void AT24Cxx_WriteOneByte(u16 addr,u8 dt){I2C_Start();if(EE_TYPE>AT24C16){I2C_Send_Byte(0xA0);I2C_Wait_Ack();I2C_Send_Byte(addr>>8); //发送数据地址高位}else{I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址}I2C_Wait_Ack();I2C_Send_Byte(addr%256);//双字节是数据地址低位//单字节是数据地址低位I2C_Wait_Ack();I2C_Send_Byte(dt);I2C_Wait_Ack();I2C_Stop();delay_ms(10);}2. AT24C02读操作那么读取AT24C02 的步骤是:1)发送起始信号2) 发送写器件地址3) 等待应答4) 发送要读取的AT24C02 的地址5) 等待应答6) 再发送其实信号7) 发送读器件地址8) 等待应答9) 接收数据10) 如果没有接收完数据,发送应答11) 接收数据12) 直到接收完数据,发送非应答13) 发送结束信号/****************************************************************************** ** 函数名: AT24Cxx_ReadOneByte* 函数功能: 24c02读一个字节地址数据* 输入: addr* 输出: 返回值temp*****************************************************************************/ u8 AT24Cxx_ReadOneByte(u16 addr){u8 temp=0;I2C_Start();if(EE_TYPE>AT24C16){I2C_Send_Byte(0xA0);I2C_Wait_Ack();I2C_Send_Byte(addr>>8); //发送数据地址高位}else{I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址}I2C_Wait_Ack();I2C_Send_Byte(addr%256);//双字节是数据地址低位//单字节是数据地址低位I2C_Wait_Ack();I2C_Start();I2C_Send_Byte(0xA1);I2C_Wait_Ack();temp=I2C_Read_Byte(0); // 0 代表NAC I2C_NAck();I2C_Stop();return temp;}。
ATmega16 _TWI主从机

* twi.c** Created: 2015/2/19 19:55:38* Author: Administrator*//************************************************************************/ /* 常用头文件及宏定义*/ /************************************************************************/#include <avr/io.h>#include <util/delay.h> //延时文件#include <avr/sleep.h> //睡眠文件#include <avr/interrupt.h> //中断文件#include <avr/eeprom.h> //eeprom#define BIT(x) 1<<x#define uchar unsigned char#define uint unsigned int/************************************************************************/ /* TWI程序*/ /************************************************************************//* 引脚说明*/ /* PC0 SCL PC1 SDA */#define START() TWCR|=BIT(TWSTA)|BIT(TWINT)//发送START#define DIZHI_CONGJI (1<<1) //从机地址//READ_WRITE=0写,=1读key=0发送中,=1空闲中uchar DIZHI_TWI=0,SHUJU_WRITE_TWI=0,SHUJU_READ_TWI=0,READ_WRITE=0,key=1; void chushihua_twi(){DDRC&=0xfc;PORTC|=BIT(0)|BIT(1);TWBR=20; //波特率cli();TWCR=BIT(TWEN)|BIT(TWIE)|BIT(TWEA);//中断sei();TWAR=BIT(TWGCE)|DIZHI_CONGJI; //从机地址:}ISR(TWI_vect)switch(TWSR&0xf8){/////////////////////// 主机发送/////////////////////////////////case 0x08: //START发送成功{if (READ_WRITE) //读写控制1读,0写{TWDR=(DIZHI_TWI<<1)+1; //发送SLA+RTWCR=(TWCR|BIT(TWINT))&~(BIT(TWSTA));//清标志}else{TWDR=DIZHI_TWI<<1; //发送SLA+WTWCR=(TWCR|BIT(TWINT))&~(BIT(TWSTA));//清标志}}break;case 0x10: //重复START发送成功{if (READ_WRITE) //读写控制1读,0写{TWDR=(DIZHI_TWI<<1)+1; //发送SLA+RTWCR=(TWCR|BIT(TWINT))&~(BIT(TWSTA));//清标志}else{TWDR=DIZHI_TWI<<1; //发送SLA+WTWCR=(TWCR|BIT(TWINT))&~(BIT(TWSTA));//清标志}}break;case 0x18: //SLA+W已发送,收到ACK{TWDR=SHUJU_WRITE_TWI; //发送数据TWCR|=BIT(TWINT); //清标志}break;case 0x20: //SLA+W已发送,收到NOT ACK {START(); //发送重复START}break;case 0x28: //数据已发送,收到ACKcase 0x30: //数据已发送,收到NOT ACK {key=1;TWCR=BIT(TWINT)|BIT(TWSTO)|BIT(TWEN)|BIT(TWIE);//发送STOP,清标志}break;case 0x38: //SLA+W 或数据的仲裁失败{START(); //总线空闲时发送START}break;/////////////////////// 主机接收//////////////////////case 0x40: //SLA+R 已发送接收到ACK{TWCR=(TWCR|BIT(TWINT))&~(BIT(TWEA));//接收数据,返回NOT ACK }break;case 0x48: //SLA+R 已发送接收到NOT ACK{START(); //将发送重复START}break;case 0x50: //接收到数据ACK 已返回{SHUJU_READ_TWI=TWDR;TWCR|=BIT(TWINT); //接收数据,返回NOT ACK}break;case 0x58: //接收到数据NOT ACK 已返回{SHUJU_READ_TWI=TWDR;TWCR|=BIT(TWINT)|BIT(TWSTO);//将发送STOP,TWSTO 将复位}break;/////////////////////// 从机接收//////////////////////case 0x60: //自己的SLA+W 已经被接收ACK 已返回case 0x68: //SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收ACK 已返回case 0x70: //接收到广播地址ACK 已返回case 0x78: //SLA+R/W 作为主机的仲裁失败;接收到广播地址ACK 已返回case 0x80: //以前以自己的SLA+W 被寻址;数据已经被接收ACK 已返回{TWCR=(TWCR|BIT(TWINT))&~(BIT(TWEA));//接收数据,返回NOT ACK }break;case 0x88: //以前以自己的SLA+W 被寻址;数据已经被接收NOT ACK 已返回{SHUJU_READ_TWI=TWDR; //读数据TWCR|=BIT(TWINT)|BIT(TWEA); //切换到未寻址从机模式;能够识别自己的SLA;若TWGCE = “1”,GCA 也可以识别}break;case 0x90: //以前以广播方式被寻址;数据已经被接收ACK 已返回{SHUJU_READ_TWI=TWDR; //读数据TWCR|=BIT(TWINT); //接收数据,返回NOT ACK}break;case 0x98: //以前以广播方式被寻址;数据已经被接收NOT ACK 已返回{SHUJU_READ_TWI=TWDR;TWCR|=BIT(TWINT)|BIT(TWEA); //切换到未寻址从机模式;能够识别自己的SLA;若TWGCE = “1”,GCA 也可以识别}break;case 0xa0: //在以从机工作时接收到STOP或重复START{TWCR|=BIT(TWINT)|BIT(TWEA); //切换到未寻址从机模式;能够识别自己的SLA;若TWGCE = “1”,GCA 也可以识别}break;/////////////////////// 从机发送//////////////////////case 0xa8: //自己的SLA+R 已经被接收ACK 已返回{TWDR=SHUJU_WRITE_TWI;TWCR=(TWCR|BIT(TWINT))&~(BIT(TWEA));//发送一字节的数据,接收NOT ACK }break;case 0xb0: //SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收ACK 已返回{TWDR=SHUJU_WRITE_TWI;TWCR=(TWCR|BIT(TWINT))&~(BIT(TWEA));//发送一字节的数据,接收NOT ACK }break;case 0xb8: //TWDR 里数据已经发送接收到ACK{TWDR=SHUJU_WRITE_TWI;TWCR=(TWCR|BIT(TWINT))&~(BIT(TWEA));//发送一字节的数据,接收NOT ACK }break;case 0xc0: //TWDR 里数据已经发送接收到NOT ACK{TWCR|=BIT(TWINT)|BIT(TWEA);//切换到未寻址从机模式;能够识别自己的SLA;若TWGCE = “1”,GCA 也可以识别}break;case 0xc8: //TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK{TWCR|=BIT(TWINT)|BIT(TWEA);//切换到未寻址从机模式;能够识别自己的SLA;若TWGCE = “1”,GCA 也可以识别}break;case 0xf8: //没有相关的状态信息;TWINT = “0”{//等待或进行当前传输}break;case 0x00: //由于非法的START 或STOP 引起的总线错误{TWCR|=BIT(TWINT)|BIT(TWSTO);//只影响内部硬件;不会发送STOP 到总线上。
最好的24C02储存开机次数实验 读写程序

24C02储存开机次数实验24C02是2K字节的串行EEPROM, 内部含有256个8位字节,该器件通过总线操作,并有专门的写保护功能。
串行EEPROM简称I2C总线式串行器件。
串行器件不仅占用很少的资源和I/O线,而且体积大大缩小,同时具有工作电源宽、抗干扰能力强、功耗低、数据不易丢失和支持在线编程等特点。
I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
我们通过一个实验来了解24C02的读写操作过程:该实验功能是单片机复位一次,自动从24C02中读取数据,然后加1,最终数码管中的数据就是开机的次数,具有一定的实用意义。
相关原理:程序运行的照片:接线方法:1、接8位数码管的数据线。
将数码管部份的数据口 JP5接到CPU部份的P0口JP51.2、接8位数码管的显示位线。
将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.3、用一根2PIN数据线一端插入CPU部份JP53(P3口)的P3.6,P3.7另外一端插入24C02部份的控制端JP38。
烧写后用手按复位键可以看到数码管每按一下加一。
程序流程图:汇编语言参考程序:SDA24 EQU P3.7 SCLK24 EQU P3.6 ORG 0000HAJMP MAINORG 0080HMAIN:CLR P3.7 ;打开写保护MOV DPTR,#TABMOV A,#00H ;读地址LCALL RD24CJNE A,#10,TTTT: JNC TT1AJMP TT2TT1: MOV A,#00TT2: MOV 30H,AMOVC A,@A+DPTRCLR P2.6 ;开数码管MOV P0,A ;送显示MOV A,30HINC AMOV B,AMOV A,#00HLCALL WT24AJMP $TAB: DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60HRD24: PUSH ACC ;读24C02子程序。
ATMEL24c02使用详解(汇编及C程序都有)

ATMEL 24c02使用详解(汇编及C程序都有)1000字ATMEL 24c02是一种串行EEPROM存储器,具有2KB的存储容量,可通过I2C总线进行读写操作。
使用ATMEL 24c02时,需先设置I2C总线的通信速率和设备地址。
然后,可以使用汇编语言或C语言编写程序进行读写数据操作。
汇编语言程序示例:1. 设置I2C总线通信速率及设备地址```LDAA #$0 ;设置I2C总线通信速率为100kHzSTAA SCLDIVLDAA #$A0 ;设置EEPROM的设备地址为0xA0STAA SLA```2. 写入数据到EEPROM```BYTE_WRITE PROCLDAA #$00 ;设置数据的存储地址为0x00STAA DADDRLDAA #$A5 ;设置需要写入的数据为0xA5STAA DATAJSR I2C_WRITE ;调用I2C总线写入函数RTSBYTE_WRITE ENDP```3. 从EEPROM读取数据```BYTE_READ PROCLDAA #$00 ;设置数据的读取地址为0x00STAA DADDRJSR I2C_START ;发送起始信号LDAA #$A1 ;设置EEPROM的设备地址为0xA1,读操作时需要在地址末位添加1JSR I2C_SEND ;发送EEPROM设备地址LDAA #$00 ;设置要读取的数据长度为1JSR I2C_READ ;调用I2C总线读取函数LDA DATA ;将读取到的数据保存到DATA寄存器中RTSBYTE_READ ENDP```C语言程序示例:1. 在main函数中,调用I2C_Init()函数,设置I2C总线速率和设备地址。
```void main(){I2C_Init(); //设置I2C总线速率和设备地址}```2. 写入数据到EEPROM```void Write_Byte(unsigned char addr, unsigned char dat) {I2C_Start(); //发送起始信号I2C_SendByte(0xa0); //写入EEPROM的设备地址I2C_SendByte(addr); //设置存储地址I2C_SendByte(dat); //写入数据I2C_Stop(); //发送停止信号}```3. 从EEPROM读取数据```unsigned char Read_Byte(unsigned char addr){unsigned char res;I2C_Start(); //发送起始信号I2C_SendByte(0xa0); //写入EEPROM的设备地址I2C_SendByte(addr); //设置读取地址I2C_Start(); //发送起始信号I2C_SendByte(0xa1); //设置EEPROM的设备地址为读取模式 res = I2C_ReadByte(); //读取数据I2C_Stop(); //发送停止信号return res; //返回读取的数据}```即可进行EEPROM的读写操作。
AVR ATmega16 EEPROM读写程序源码

void delay(uint ms) //延迟函数 { uint i,j; for (i=0;i<ms;i++) for (j=0;j<1141;j++); } /********************************************************** LCD1602相关定义 **********************************************************/ void wr_com(uchar com) //写命令函数 { CTRL_PORT &=~BIT(0); CTRL_PORT &=~BIT(1); DATA_PORT =com; CTRL_PORT &=~BIT(2); delay(1); CTRL_PORT |=BIT(2); delay(1); } void wr_data(uchar data) { //写数据函数 //RS置0 //RW置1 //E置0 //E置1,产生上升沿,开始写入
第7页 共 9页
AVR ATmega16 EEPROM 读写程序
CTRL_PORT |=BIT(0); CTRL_PORT &=~BIT(1); DATA_PORT = data; CTRL_PORT &=~BIT(2); delay(1); CTRL_PORT |=BIT(2); delay(1); }
(3) EEPROM 控制寄存器- EECR
Bit
读/写 初始值
7
-
6
-
5
-
4
-
3
EERIE
2
EEMWE
1
EEWE
0
AVR单片机教程19—第十九课 ATMEAG16L的内部EEPROM读写编程

——————————————————————————第十九课ATMEAG16L的内部EEPROM读写编程本教程节选自周兴华老师《手把手教你学AVR单片机C程序设计》教程,如需转载,请注明出处!读者可通过当当网、淘宝网等网站购买本教程,如需购买配书实验器材,可登陆周兴华单片机培训中心网购部自助购买!11.1 ATMEAG16L的内部EEPROMATmegal6L单片机片内有512个字节的EEPROM,它作为一个独立的数据空间存在。
ATmegal6L的EEPROM采用独立线性编址,其地址范围为0~511。
ATmegal6L通过对相关单片机培训寄存器的操作实现对EEPROM按字节进行读写。
ATmegal6L的EEPROM至少可以擦写100000次。
ATmegal6L的EEPROM的写入时间约花数毫秒,取决于VCC的电压。
电源电压越低,写周期越长。
11.2 与EEPROM相关的寄存器——————————————————————————l.EEPROM地址寄存器—EEARH、EEARLEEPROM地址寄存器EEARH、EEARL用于指定某个EEPROM单元的地址。
512个字节的EEPROM线性编址为0~511。
地址寄存器EEARH、EEARL可读可写,初始值没有定义,访问前必须赋予正确的地址。
2.EEPROM数据寄存器—EEDREEPROM数据寄存器EEDR用于存放即将写入EEPROM或者从EEPROM读出的某个单元的数据。
写入或者读出的地址由EEPROM的地址寄存器EEARH、EEARL给出。
EEPROM按字节进行读写。
EEPROM数据寄存器EEDR可读可写,初始值为0x00。
3.EEPROM控制寄存器—EECR——————————————————————————EEPROM控制寄存器EECR用于控制单片机对EEPROM的操作。
位7~4:保留位。
读这些位时总为0。
位3:EERIE位为EEPROM中断准备好使能位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ATMEGA16读写iic(24c02) C语言程序测试通过#include <iom16v.h>#include "I2C.h"#include "1602.h"#include "delay.h"/*通过AVR往I IC写数据,并通过串口把数据读出显示出来*///===============================================================void UART_init(void) //UART初始化{ DDRD = 0x02;PORTD = 0x00;UCSRA = 0x02; /*无倍速*/UCSRB = 0x18; /*允许接收和发送*/UC SRC = 0x06; /*8位数据,1位停止位,无校验*/UBRRH = 0x00;UBRRL = 12; /*9600*/}//===============================================================void USART_TXD(float data) //发送采用查询方式{while( !(UCSRA & BIT(UDRE)) );UDR=data;while( !(UCSRA & BIT(TXC )) );UCSRA|=BIT(TXC);}void main(void){unsigned char i;//LCD_init();uart_init();//TART初始化SEI(); //全局中断使能while(1){/*I2C_Write('n',0x00);I2C_Write('c',0x01);I2C_Write('e',0x02);I2C_Write('p',0x03);I2C_Write('u',0x04);*/i=I2C_Read(0x00);//LCD_write_char(0,0,i); USART_TXD(i);i=I2C_Read(0x01);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x02);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x03);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x04);//LCD_write_data(i);USART_TXD(i);}}/*上面上主函数部分*/#include <macros.h>#include "delay.h"//I2C 状态定义//MT 主方式传输 MR 主方式接受#define START 0x08#define RE_START 0x10#define MT_SLA_ACK 0x18#define MT_SLA_NOACK 0x20#define MT_DATA_ACK 0x28#define MT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40#define MR_SLA_NOACK 0x48#define MR_DATA_ACK 0x50#define MR_DATA_NOACK 0x58#define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位#define WD_DEVICE_ADDR 0xA0//常用TWI操作(主模式写和读)#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C#define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生#define TestAck() (TWSR&0xf8) //观察返回状态#define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答#define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDRunsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress); unsigned char I2C_Read(unsigned RegAddress);/*********************************************I2C总线写一个字节返回0:写成功返回1:写失败**********************************************/unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress){Start(); //I2C启动Wait();if(TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if(TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKWrite8Bit(Wdata); //写数据到器件相应寄存器Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKStop(); //I2C停止delay_nms(10); //延时return 0;}/*********************************************I2C总线读一个字节返回0:读成功返回1:读失败**********************************************/ unsigned char I2C_Read(unsigned RegAddress){unsigned char temp;Start();//I2C启动Wait();if (TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if (TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if (TestAck()!=MT_DATA_ACK)return 1;Start(); //I2C重新启动Wait();if (TestAck()!=RE_START)return 1;Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式Wait();if(TestAck()!=MR_SLA_ACK)return 1; //ACKTwi(); //启动主I2C读方式Wait();if(TestAck()!=MR_DATA_NOACK)return 1; //ACKtemp=TWDR;//读取I2C接收数据Stop();//I2C停止return temp;}/*以上是IIC.h头文件部分,需要对照技术文档好好研究*/*----------------------------------------------------------------------- 延时函数编译器:I CC-AVR v6.31A 日期: 2005-11-24 20:29:57目标芯片 : M16时钟: 8.0000M Hz作者:archeng504-----------------------------------------------------------------------*/ #ifndef __delay_h#define __delay_hvoid delay_nus(unsigned int n);void delay_nms(unsigned int n);void delay_1us(void);void delay_1ms(void) ;void delay_1us(void) //1us延时函数{asm("nop");}void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1us();}void delay_1ms(void) //1ms延时函数{unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}#endif/*以上是delay.h部分,再加上IIC中自带的iom16v.h 和macros.h就可以编译通过*//*注意点:本程序在实验板ATMEGA16上测试通过,在示波器把SCL,SDA信号线有数据,移值到自己电路上可以放心使用,在ATMEGA32上一样使用,本人24C02的A2,A1,A0都是接地,若地址不一样,在程序相应位置改一下就可以,串口上调试单片机的基础,所以它一定要会用*//*本程序调试软件环境是ICC6.31*/。