搜索
bottom↓
回复: 8

MEGA16 用模拟IIC 读写AT24C02 有详细资料 ICCAVR

[复制链接]

出0入0汤圆

发表于 2008-3-26 14:14:22 | 显示全部楼层 |阅读模式
一个中午努力,终于把模拟方式的IIC弄出来了。

用的是ICCAVR。

总用这里的资源也要贡献一点嘛
程序文件:
点击此处下载ourdev_239140.rar(文件大小:19K)

IIC的原理图在下面,这个是我自设计的学习板的关于IIC的部分,可以模拟IO,也可以硬件IIC。
1

下图的13和14连上,15和16连上
2

下面的图是为了判断IIC读写是否一致做的显示,一个LED接在PD7上
1
2


为了占点贴长,哈哈,把程序也贴出来
/****************************这个是主程序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);

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2008-3-26 14:19:30 | 显示全部楼层

出0入0汤圆

发表于 2008-3-26 15:05:51 | 显示全部楼层
不明白。。。。

为什么还要模拟

出0入0汤圆

 楼主| 发表于 2008-3-26 15:53:42 | 显示全部楼层
呵呵,练练手,刚刚又把模拟方式的3310液晶搞出来了

出0入0汤圆

发表于 2008-9-9 23:00:20 | 显示全部楼层
想问下,你这个模拟的方式的I2C ,通讯稳定吗? 虽然看明白了,但是每个时钟脉冲的长短会一样的吗?

出0入0汤圆

发表于 2009-4-15 17:23:03 | 显示全部楼层
shrlyq 胖胖心碎了
能否提供一个I2C驱动24C02进行读写的程序供参考参考

出0入0汤圆

发表于 2009-4-16 07:57:57 | 显示全部楼层
还有昨天晚上试验了楼主的程序   只能读出255

错误呀

出0入0汤圆

发表于 2014-2-7 23:02:36 | 显示全部楼层
是的,经过测试,每次读出的数字都是255

出0入8汤圆

发表于 2014-8-1 12:12:28 | 显示全部楼层
能做出来就不错了,用硬件还不如模拟的好~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-4 02:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表