shrlyq 发表于 2008-3-26 14:14:22

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);

guofang 发表于 2008-3-26 14:19:30

hhrfjz 发表于 2008-3-26 15:05:51

不明白。。。。

为什么还要模拟

shrlyq 发表于 2008-3-26 15:53:42

呵呵,练练手,刚刚又把模拟方式的3310液晶搞出来了

reynold520 发表于 2008-9-9 23:00:20

想问下,你这个模拟的方式的I2C ,通讯稳定吗? 虽然看明白了,但是每个时钟脉冲的长短会一样的吗?

ww7805 发表于 2009-4-15 17:23:03

shrlyq 胖胖心碎了
能否提供一个I2C驱动24C02进行读写的程序供参考参考

ww7805 发表于 2009-4-16 07:57:57

还有昨天晚上试验了楼主的程序   只能读出255

错误呀

iar520 发表于 2014-2-7 23:02:36

是的,经过测试,每次读出的数字都是255

蓝蓝的恋 发表于 2014-8-1 12:12:28

能做出来就不错了,用硬件还不如模拟的好~
页: [1]
查看完整版本: MEGA16 用模拟IIC 读写AT24C02 有详细资料 ICCAVR