MEGA16 用模拟IIC 读写AT24C02 有详细资料 ICCAVR
一个中午努力,终于把模拟方式的IIC弄出来了。用的是ICCAVR。
总用这里的资源也要贡献一点嘛
程序文件:
点击此处下载ourdev_239140.rar(文件大小:19K)
IIC的原理图在下面,这个是我自设计的学习板的关于IIC的部分,可以模拟IO,也可以硬件IIC。
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_239137.jpg
下图的13和14连上,15和16连上
2http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_239138.jpg
下面的图是为了判断IIC读写是否一致做的显示,一个LED接在PD7上
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_239141.jpg
2http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_239142.jpg
为了占点贴长,哈哈,把程序也贴出来
/****************************这个是主程序iic.c,包含的在下面***************************/
#include <iom16v.h>
#include <MACROS.h>
#include "dc_defines.h"
#include "I2C.h"
#define OP_READ 0xa1 //器件地址以及读取操作
#define OP_WRITE 0xa0 //器件地址以及写入操作
#define MAX_ADDR 0xff //AT24C02最大地址
unsigned char dis_code[] = {0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};//写入的数据串
void main(void)
{
unsigned char i,j;
unsigned char data_read;
DDRD= 0xff;
PORTD = 0xff;
fill_byte(0xff);
while(1)
{
for(i = 0 ; i < 255; i++)
{
write_byte(i,i);
PORTD = 0xff;
delayms(50);
if(i = read_random(i))
{
PORTD = 0x00;
delayms(50);
}
}
}
}
/******************************************************************************/
void start(void)
{
SETBIT(I2C_DIR,SDA);// Set SDA to output
SETBIT(I2C_DIR,SCL);// Set SCL to output
SETBIT(I2C_PORT,SDA);// Set SDA High
SETBIT(I2C_PORT,SCL);// Set SCL High
NOP();
NOP();
CLEARBIT(I2C_PORT,SDA);// Clear SDA
NOP();
NOP();
NOP();
NOP();
CLEARBIT(I2C_PORT,SCL);// Clear SCL
}
/******************************************************************************/
void stop(void)
{
SETBIT(I2C_DIR,SDA);// Set SDA to output
SETBIT(I2C_DIR,SCL);// Set SCL to output
CLEARBIT(I2C_PORT,SDA);// Clear SDA
NOP();
NOP();
SETBIT(I2C_PORT,SCL);// Set SCL High
NOP();
NOP();
NOP();
NOP();
SETBIT(I2C_PORT,SDA);// Set SDA High
}
/******************************************************************************/
void shout(unsigned char byte)
{
unsigned char i;
SETBIT(I2C_DIR,SDA);// Set SDA to output
SETBIT(I2C_DIR,SCL);// Set SCL to output
for (i = 0; i < 8; i++)
{
if((byte & 0x80) == 0x80)
{
SETBIT(I2C_PORT, SDA);
}
else
{
CLEARBIT(I2C_PORT,SDA);
}
NOP();
SETBIT(I2C_PORT,SCL);// Set SCL high
NOP();
NOP();
CLEARBIT(I2C_PORT,SCL);// Set SCL low
byte = byte << 1;
}
SETBIT(I2C_PORT,SDA);// Set SDA High
NOP();
NOP();
SETBIT(I2C_PORT,SCL);// Set SCL high
NOP();
NOP();
NOP();
NOP();
CLEARBIT(I2C_PORT,SCL);// Set SCL low
}
/******************************************************************************/
unsigned char shin(void)
{
unsigned char i,read_data;
SETBIT(I2C_DIR,SCL);// Set SCL to output
CLEARBIT(I2C_DIR,SDA);// Set SDA to input
for (i = 0; i < 8; i++)
{
SETBIT(I2C_PORT,SCL);// Set SCL high
read_data <<= 1;
if(CHECKBIT(I2C_IN,SDA))
{
read_data = read_data | 0x01;
}
CLEARBIT(I2C_PORT,SCL);// Set SCL low
}
return read_data;
}
//*****************************************************************************/
void write_byte(unsigned char addr, unsigned char write_data)//在指定地址addr处写入write_data
{
start();
shout(OP_WRITE);
shout(addr);
shout(write_data);
stop();
delayms(10);
}
/******************************************************************************/
void fill_byte(unsigned char fill_data)//填充数据fill_data到EEPROM内
{
unsigned char i;
for(i = 0; i < MAX_ADDR; i++)
{
write_byte(i, fill_data);
}
}
/******************************************************************************/
unsigned char read_current()//在当前地址处读取
{
unsigned char read_data;
start();
shout(OP_READ);
read_data = shin();
stop();
return read_data;
}
/******************************************************************************/
unsigned char read_random(unsigned char random_addr)//从指定地址random_addr处读取
{
start();
shout(OP_WRITE);
shout(random_addr);
return(read_current());
}
/******************************************************************************/
void delayms(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
/*******************************这个是dc_defines.h**********************************************************/
/* enable global interrupts */
#define GIE (SREG |= BIT(7))
/* disable global interrupts */
#define GID (SREG &= ~BIT(7))
#define SLEEP() asm("sleep")
/* enables an unsigned char to be used as a series of booleans */
#define BIT(x) (1 << (x))
#define SETBIT(x, y) (x |= y)
#define CLEARBIT(x, y) (x &= ~y)
#define CHECKBIT(x, y) (x & y)
// ***** Define I/O pins *****
#define BIT7 0x80
#define BIT6 0x40
#define BIT5 0x20
#define BIT4 0x10
#define BIT3 0x08
#define BIT2 0x04
#define BIT1 0x02
#define BIT0 0x01
#define true 1
#define True 1
#define false 0
#define False 0
/*****************************************************这个是iic.h********************************************/
#define SDA BIT1
#define SCL BIT0
#define I2C_PORT PORTC
#define I2C_DIR DDRC
#define I2C_IN PINC
void start(void);
void stop(void);
unsigned char shin(void);
void shout(unsigned char write_data);
unsigned char read_random(unsigned char random_addr);
void write_byte( unsigned char addr, unsigned char write_data);
void fill_byte(unsigned char fill_data);
void delayms(unsigned char ms); 顶 不明白。。。。
为什么还要模拟 呵呵,练练手,刚刚又把模拟方式的3310液晶搞出来了 想问下,你这个模拟的方式的I2C ,通讯稳定吗? 虽然看明白了,但是每个时钟脉冲的长短会一样的吗? shrlyq 胖胖心碎了
能否提供一个I2C驱动24C02进行读写的程序供参考参考 还有昨天晚上试验了楼主的程序 只能读出255
错误呀 是的,经过测试,每次读出的数字都是255 能做出来就不错了,用硬件还不如模拟的好~
页:
[1]