⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 工厂环境污染控制数据采集器
💻 C
字号:

/*
岁月催人老,2007-09-10

读写AT24C16的函数,用模拟方式读写任意地址的任意个数据(小于256)
输出以下两个函数,分别用于读写;
addr为16位的地址;取值0--2047
*s为放置写入(或读出)数据的缓冲区指针
count为一次写入的数量,最大为255
返回值表明读写是否成功;1--成功;0 -- 出错;
没有检测是否地址溢出,所以请使用时注意;
unsigned char write(unsigned int addr,unsigned char *s,unsigned char count);
unsigned char read(unsigned int addr,unsigned char *s,unsigned char count);

需要引入两个函数,这两个函数可以自己定义,也可以使用系统的,如下
void delay_xms(unsigned int x); 延时x毫秒
void delay_xus(unsigned int x); 延时x微秒

使用系统自带
#define F_CPU  ??(你的晶振频率)
#include <util\delay.h>
#define delay_xms(a) _delay_ms(a)
#define delay_xus(a) _delay_us(a)

该程序针对ATMEGA64在AT24C16上应用;如果用其它的MCU,请更改端口设置

*/



#define PORT_EP PORTD
#define DDR_EP DDRD
#define PIN_EP PIND

#define SDA (1 << PD1)
#define SCL (1 << PD0)
#define PIN_SDA (PIN_EP & SDA)
#define I2CWAIT delay_xus(2)

#define SET_SDA PORTD |= SDA;I2CWAIT
#define CLR_SDA PORTD &= ~SDA;I2CWAIT
#define SET_SCL PORTD |= SCL;I2CWAIT
#define CLR_SCL PORTD &= ~SCL;I2CWAIT
#define SDA_IN  DDRD &= ~SDA;delay_xus(1)
#define SDA_OUT DDRD |= SDA;delay_xus(1)
#define IF_SDA_H  (PIND & SDA) == SDA
#define IF_SDA_L  (PIND & SDA) == 0

// 在SCL为高的时间,SDA从高到低的跳变表明开始,从低到高的跳变表明结束
// SDA 在处理数据时,SCL必须在低状态,否则就表明开始或结束;
// SCL从低到高的跳变时输出或读入数据;


void i2cstart(void)
{ 
	 SDA_OUT;
	 
     SET_SDA; 
	 delay_xus(10); 
     SET_SCL;  
     CLR_SDA; 
     CLR_SCL;
}

unsigned char i2cstop(void)
{
	 //SDA_OUT;
	 
     CLR_SDA;
     SET_SCL;
     SET_SDA;
	 
	 SDA_IN;

	 if (IF_SDA_L)
	 {
		SDA_OUT;
		return 0;
	 }
	 else
	 {
		SDA_OUT;
		return 1;
	 }
}

unsigned char i2csendbyte(unsigned char temp12)
{
    unsigned char i=8;
	unsigned char flag2data;
   
    CLR_SCL; 
	while (i--)
	{
        if (temp12&0x80)
		{
			SET_SDA;
		}
		else
		{
			CLR_SDA;
		}
		
        temp12<<=1; 
        SET_SCL;
        CLR_SCL;
    }
	
    SDA_IN;
	SET_SCL;
	
    if (IF_SDA_H)
	{
		flag2data = 1;
	}
	else
	{
		flag2data = 0;
		
		//disp_char(2,2,'5',0);
	}
	
    CLR_SCL;  
    SDA_OUT;
	return flag2data;
}

unsigned char i2creceivebyte(unsigned char ac)
{
     unsigned char i=8,temp12=0;
     
	 SDA_IN;
	 CLR_SCL;
     while (i--)
	 {
         SET_SCL;
         temp12 <<= 1;
         if (IF_SDA_H) temp12++; 
         CLR_SCL;
     }
	 
	 SDA_OUT;
	 if (ac)
	 {
		SET_SDA;
	 }
	 else
	 {
		CLR_SDA;
	 }
	
	 SET_SCL;
	 CLR_SCL;
	 
     return temp12;
}

unsigned char setaddr(unsigned char sla,unsigned char suba,unsigned char rw)
{
	sla &= 0x07;
	sla <<= 1;
	if (rw)
		sla |= 0xa1;
	else
		sla |= 0xa0;
	i2cstart();
	if (i2csendbyte(sla)) return 1;
	if (!rw) return i2csendbyte(suba);
	return 0;
}


unsigned char write(unsigned int addr,unsigned char *s,unsigned char count)
{
	unsigned char i;

	do
	{
		for (i=255;i>0;i--)
		{
			if (setaddr(addr >> 8,addr,0) == 0) break;
			i2cstop();
			if (i == 0) return 0;
		}
		i = ((unsigned char)addr) & 0x0f;
		if (count == 0) return i2cstop();
		do
		{
			if (i2csendbyte(*s))
		 	{
				i2cstop();
				return 0;
			}
			s++;
			addr++;
		} while((--count) && ((++i) < 0x10));
		i2cstop();
		delay_xms(20);
	} while(1);
}

unsigned char read(unsigned int addr,unsigned char *s,unsigned char count)
{
	unsigned char mack;
	
	if (count == 0) return 0;

	if (setaddr(addr >> 8,addr,0))
	{
		i2cstop();
		return 1;
	}

	do
	{
		if (setaddr(addr >> 8,addr,1))
		{
			i2cstop();
			return 1;
		}

		for (;;)
		{
			
			mack = ((--count) && ((++addr) & 0xff));
			*s = i2creceivebyte(!mack);
			s++;
			if (!mack) break;
		}
	}while(count);
	return i2cstop();
}


void init_eeprom(void)
{
	//unsigned char i;
	
	
	DDR_EP |= SDA | SCL;
	PORT_EP |= SDA | SCL;

	TWCR= 0X00; //disable twi
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -