搜索
bottom↓
回复: 16

谁能给一个ATmega16用TWI总线读写24C02的实例??

[复制链接]

出0入0汤圆

发表于 2009-9-17 03:38:39 | 显示全部楼层 |阅读模式
我用软件模拟IIC总线去读写24C02,就能很顺利的执行;但用ATmega16自带的TWI总线,却怎么弄也搞不出来,现在心都凉了,请问谁能给一个ATmega16用TWI总线读写24C02的实例??

出0入0汤圆

 楼主| 发表于 2009-9-17 04:47:07 | 显示全部楼层
最好是ICCACR编译的

出0入0汤圆

 楼主| 发表于 2009-9-17 15:21:28 | 显示全部楼层
请帮帮我,感谢

出0入0汤圆

发表于 2011-8-22 12:00:56 | 显示全部楼层
我在在回复【2楼】lssbw
-----------------------------------------------------------------------

我也在等待,有得话也发一份给我

出0入0汤圆

发表于 2011-11-25 22:14:15 | 显示全部楼层
我也在等待

出0入0汤圆

发表于 2011-11-25 23:02:59 | 显示全部楼层
/*function.h*/
#include <iom16v.h>
#include <macros.h>

/*---------------------------------------------------------------------------------
     延时程序计算方法
     计数个数j = 延时时间/6*晶振频率 - 1
---------------------------------------------------------------------------------*/
#define uchar unsigned char
#define uint unsigned int

//方式一:
void Delay()                        
    {
    uchar a, b, c;
    for (a = 1; a; a++)
        for (b = 1; b; b++)
            for (c = 0; c<10; c++)  //循环次数=255*255*10
                        ;
    }

//方式二:1ms延时,准确性较Delay();高
void DelayMs(uint i)               
   {
    while(i--)
    {                          
            uint j;               
        for(j=1;j<=613;j++)   
                           ;               
    }                       
   }
   
//端口初始化
void port_init()
{
DDRA =0X00;
PORTA=0XFF;
DDRB =0XFF;
PORTB=0XFF;
DDRC =0X00;
PORTC=0XFF;
DDRD =0X00;
PORTD=0XFF;
}

//LED初始化
void LED_init()
{
  PORTB=0X00;
  DelayMs(1000);
  PORTB=0XFF;
  DelayMs(1000);
}

出0入0汤圆

发表于 2011-11-25 23:04:31 | 显示全部楼层
/*iic.h*/
#ifndef I2C_H
#define I2C_H

//主机模式启动状态码
#define I2C_START                       0x08   //启动总线
#define I2C_RESTART                                      0x10   //重新启动总线

//主机发送模式状态码
#define I2C_MT_SLA_ACK                                   0x18   //SLA+W写地址已发送,收到应答位
#define I2C_MT_SLA_NACK                                  0x20   //SLA+W写地址已发送,收到非应答位
#define I2C_MT_DATA_ACK                                  0x28   //写入数据已发送,收到应答位
#define I2C_MT_DATA_NACK                                 0x30   //写入数据已发送,收到应答位
#define I2C_MT_ARB_LOST                                  0x38   //SLA+W或数据仲裁失败

//主机接收模式状态码
#define I2C_MR_ARB_LOST                                  0x38   //SLA+R或NOT ACK的仲裁失败
#define I2C_MR_SLA_ACK                                   0x40   //SLA+R已发送,收到应答位
#define I2C_MR_SLA_NACK                                  0x48   //SLA+R已发送,收到非应答位
#define I2C_MR_DATA_ACK                                  0x50   //接收到数据,应答位已返回
#define I2C_MR_DATA_NACK                                 0x58   //接收到数据,非应答位已返回

//从机接收模式状态码
#define I2C_SR_SLA_ACK                                    0x60   //自己的SLA+W已经被接收ACK已返回
#define I2C_SR_ARB_LOST_SLA_ACK                  0x68   //SLA+R/W作为主机的仲裁失败,自己的SLA+W已经被接收ACK已返回
#define I2C_SR_GCALL_ACK                                   0x70   //接收到广播地址ACK已返回
#define I2C_SR_ARB_LOST_GCALL_ACK                 0x78   //SLA+R/W作为主机的仲裁失败,接收到广播地址ACK已返回
#define I2C_SR_DATA_ACK                                    0x80   //以前以自己的SLA+W被寻址,数据已经被接收ACK已返回
#define I2C_SR_DATA_NACK                                   0x88   //以前以自己的SLA+W被寻址,数据已经被接收NOT ACK已返回
#define I2C_SR_GCALL_DATA_ACK                          0x90   //以前以广播方式被寻址,数据已经被接收ACK已返回
#define I2C_SR_GCALL_DATA_NACK                  0x98   //以前以广播方式被寻址,数据已经被接收NOT ACK已返回
#define I2C_SR_STOP                                     0xA0   //在以从机工作时接收到STOP或重复START

//从机发送模式状态码
#define I2C_ST_SLA_ACK                                   0xA8   //自己的SLA+R已经被接收ACK已返回
#define I2C_ST_ARB_LOST_SLA_ACK                 0xB0   //SLA+R/W作为主机的仲裁失败,自己的SLA+R已经被接收ACK已返回
#define I2C_ST_DATA_ACK                                   0xB8   //TWDR里数据已经被发送接收到ACK
#define I2C_ST_DATA_NACK                                 0xC0   //TWDR里数据已经被发送接收到NOT ACK
#define I2C_ST_LAST_DATA                                  0xC8   //TWDR的一字节数据已经发送(TWAE='0'),接收到ACK

//其他状态码
#define I2C_NO_INFO                                           0xF8   //没有相关的状态信息,TWINT='0'
#define I2C_BUS_ERROR                                          0x00   //由于非法的START或STOP引起的总线错误

//定义SLA中读写控制位极性
#define I2C_READ   1
#define I2C_WRITE  0

#define I2CStart()      (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define I2CStop()       (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define I2C_STATUS      (TWSR & 0xf8)
#define I2CSendAck()    (TWCR|=(1<<TWEA))
#define I2CSendNoAck()  (TWCR&=~(1<<TWEA))
#define I2CRcvNckByte() (TWCR=(1<<TWINT)|(1<<TWEN))
#define I2CRcvAckByte() (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA))

//定义运行状态返回值极性
#define I2C_ERR   0     //错误
#define I2C_CRR   1     //正确

//定义TWINT位置位查询等待时间
#define WAITCOUNT  50   //3.6864M时,此处必须大于60,验证得知小于60,程序均不能正常工作

/*--------------------------------------------------------------------
函数名称:I2C_Init
函数功能:TWI初始化
注意事项:(须根据具体情况设置)
提示说明:
输    入:
返    回:
--------------------------------------------------------------------*/
void I2C_Init(void)
{
TWBR=0x0f;    //波特率设置,必须大于 10
TWSR=0;       //状态寄存器初始化
//TWAR=       //从机地址和通用呼叫设置,多CPU时使用
}
/*--------------------------------------------------------------------
函数名称:I2C_WaitINT
函数功能:等待TWINT位置位
注意事项:需定义 WAITCOUNT
提示说明:
输    入:
返    回:运行状况  I2C_ERR :错误   I2C_CRR :正确
--------------------------------------------------------------------*/
unsigned char I2C_WaitINT(void)
{
unsigned int i=WAITCOUNT;
while(!(TWCR&(1<<TWINT)))      //等待TWINT置1
{if((--i)==0) return I2C_ERR;}
return I2C_CRR;
}
/*--------------------------------------------------------------------
函数名称:I2C_SendByte
函数功能:发送一字节数据
注意事项:
提示说明:
输    入:待发送数据
返    回:运行状况  I2C_ERR :错误   I2C_CRR :正确
--------------------------------------------------------------------*/
void I2C_SendByte(unsigned char x)
{
         TWDR=(x);
         TWCR=(1<<TWINT)|(1<<TWEN);
}
/*--------------------------------------------------------------------
函数名称:I2C Start
函数功能:发出起始信号
注意事项:
提示说明:
输    入:
返    回:运行状况  I2C_ERR :错误   I2C_CRR :正确
--------------------------------------------------------------------*/
unsigned char I2C_Start()     
{
I2CStart();                        //发出起始信号
if(!I2C_WaitINT()) return I2C_ERR; //等待启动完成
if( I2C_STATUS!=I2C_START )        //检查是否启动成功
return I2C_ERR;                    //启动失败,返回0
return I2C_CRR;                    //启动成功,返回1
}
/*--------------------------------------------------------------------
函数名称:I2C ReStart
函数功能:发出重复起始信号
注意事项:
提示说明:
输    入:
返    回:运行状况  I2C_ERR :错误   I2C_CRR :正确
--------------------------------------------------------------------*/
unsigned char I2C_Restart()     
{
I2CStart();      
if(!I2C_WaitINT()) return I2C_ERR;
if( I2C_STATUS!=I2C_RESTART )     //检查是否重复启动成功
return I2C_ERR;
return I2C_CRR;
}
/*--------------------------------------------------------------------
函数名称:I2C_SendWrDAdr
函数功能:发送 7位 器件写地址: XXXX XXX0
注意事项:
提示说明:
输    入:写地址
返    回:运行状况  I2C_ERR :错误   I2C_CRR :正确
--------------------------------------------------------------------*/
unsigned char I2C_SendWrDAdr(unsigned char wrDAdr)
{
I2C_SendByte(wrDAdr);   //设置器件写地址

出0入0汤圆

发表于 2011-11-25 23:06:03 | 显示全部楼层
/*先在24C02中写入8个数据,然后依次将其读出,用对应LED指示读出的数据是否正确。*/
/*main.c*/
#include <iom16v.h>
#include "iic.h"
#include "function.h"

void main()
{
  unsigned char temp1[8]={18,17,16,15,14,13,12,11};
  unsigned char temp2[8]={0};
  
  port_init();
  LED_init();
  I2C_Init();
  I2C_Write_(0xa0,0X00,temp1,8);//一次在[0X00-0X07]中写入8个字节
  DelayMs(5);
  I2C_Read_(0xa1,0X00,temp2,8); //一次在[0X00-0X07]中读取8个字节
  DelayMs(5);
  
  while(1)
  {
      if(temp2[0]==18)
     {
      PORTB=0XFE;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[1]==17)
     {
      PORTB=0XFD;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[2]==16)
     {
      PORTB=0XFB;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[3]==15)
     {
      PORTB=0XF7;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[4]==14)
     {
      PORTB=0XEF;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[5]==13)
     {
      PORTB=0XDF;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[6]==12)
     {
      PORTB=0XBF;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
     
      if(temp2[7]==11)
     {
      PORTB=0X7F;
      DelayMs(100);
      PORTB=0XFF;
          DelayMs(50);
     }
  }
}

出0入0汤圆

发表于 2011-12-13 14:29:38 | 显示全部楼层
学习

出0入0汤圆

发表于 2012-1-30 13:51:05 | 显示全部楼层

悲催的刚用自带的IIC成功读写,用模拟却怎么也没有响应

出0入0汤圆

发表于 2012-1-31 19:12:42 | 显示全部楼层
我自已写的汇编的有要的吗?不好意思贴上来

出0入0汤圆

发表于 2012-2-3 13:48:00 | 显示全部楼层
回复【楼主位】lssbw
-----------------------------------------------------------------------

//======================================
//TWI状态定义
//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

//常用TWI操作(主模式写和主模式读)
#define Start()              (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop()               (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait()                     {while(!(TWCR&(1<<TWINT)));}
#define TestAck()           (TWSR&0xf8)
#define SetAck()          (TWCR|=(1<<TWEA))
#define SetNoAck()    (TWCR&=~(1<<TWEA))
#define Twi()                    (TWCR=(1<<TWINT)|(1<<TWEN))
#define Write8Bit(x)  {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}

.......

/******************************************
               I2C总线读一个字节
                           如果读失败返回0
*******************************************/
unsigned char i2c_Read(unsigned char RomAddress)
      {
           unsigned char temp;
           Start();
           Wait();
           if (TestAck()!=START) return 0;          
           Write8Bit(wr_device_add);
           Wait();
           if (TestAck()!=MT_SLA_ACK) return 0;
           Write8Bit(RomAddress);
           Wait();
           if (TestAck()!=MT_DATA_ACK) return 0;
           Start();
           Wait();
           if (TestAck()!=RE_START)  return 0;
           Write8Bit(rd_device_add);
           Wait();
           if(TestAck()!=MR_SLA_ACK)  return 0;
           Twi();
           Wait();
           if(TestAck()!=MR_DATA_NOACK) return 0;       
           temp=TWDR;
       Stop();
           return temp;
      }
          
/******************************************
               I2C总线写一个字节
                            返回0:写成功
                                返回非0:写失败
*******************************************/
unsigned char i2c_Write(unsigned char RomAddress,unsigned char Wdata)
{
          Start();
          Wait();
          if(TestAck()!=START) return 1;
          Write8Bit(wr_device_add);
          Wait();
          if(TestAck()!=MT_SLA_ACK) return 1;
          Write8Bit(RomAddress);
          Wait();
          if(TestAck()!=MT_DATA_ACK) return 1;
          Write8Bit(Wdata);
          Wait();
          if(TestAck()!=MT_DATA_ACK) return 1;       
          Stop();
          delay_ms(10);
          return 0;
}

出0入0汤圆

发表于 2012-9-28 10:42:23 | 显示全部楼层
楼主能分享一下你模拟的I2C吗 我模拟遇到问题了 搞不出来 能借鉴下不

出0入4汤圆

发表于 2017-6-12 08:40:22 | 显示全部楼层
vjcmain 发表于 2011-11-25 23:06
/*先在24C02中写入8个数据,然后依次将其读出,用对应LED指示读出的数据是否正确。*/
/*main.c*/
#include  ...

研究一下这个程序。正想改进一下我的IIC程序。谢谢了!

出0入0汤圆

发表于 2017-6-12 08:51:19 | 显示全部楼层
BS_good200xy 发表于 2017-6-12 08:40
研究一下这个程序。正想改进一下我的IIC程序。谢谢了!

挖坟啊,,现在谁还用AVR啊~!

出0入4汤圆

发表于 2017-6-12 11:26:47 | 显示全部楼层
jackiezeng 发表于 2017-6-12 08:51
挖坟啊,,现在谁还用AVR啊~!

那说说,你们项目中一般用到什么类型的MCU呢?感觉小项目用AVR很方便的。

出0入0汤圆

发表于 2017-6-12 14:15:57 | 显示全部楼层
BS_good200xy 发表于 2017-6-12 11:26
那说说,你们项目中一般用到什么类型的MCU呢?感觉小项目用AVR很方便的。

STM8,从性价比来说比AVR好很多啊,,MEGA16记得当年10RMB以上的价格,这个价格买M0系列的单片机都够了,

另外如果还想更省成本可以选国产单片机,赛元的SC93F5003 , 8K FLASH , 512B RAM , ADC  , PWM , UART , SPI , LCD驱动,都有,价格才1.5以下,,,还是工业温度范围。

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

本版积分规则

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

GMT+8, 2024-4-19 20:11

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

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