搜索
bottom↓
回复: 0

请教MEGA 328 TWI问题

[复制链接]

出0入0汤圆

发表于 2014-11-15 19:32:13 | 显示全部楼层 |阅读模式
使用MEGA328的硬件TWI中断模式读取240C2(内部0x02 里面的数据应该是0xd0),发现TWI流程正确。(所有返回状态正确)但是最后读取TWDR的时候却一直是0,SDA SCL都有上拉电阻 ,在线等
/**************************************
**  函数名称:IIC_Init(void) **********
**  功能:总线初始化(主机模式)*******
**  输入值:无           **************
**  返回值:无          ***************
**************************************/
void IIC_Init(void)
{
  DDRC&=~((1<<PC4)&(1<<PC5));  
  PORTC|= (1<<PC4)|(1<<PC5);
  TWAR = 0x00;                          //设置为主机模式
  TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWIE); //主机模式,使能TWI 使能中断
  TWBR = 0x10;                          //设置分频因子初值64(f = 8M/(16+2*64))
  TWSR = 0x00;                          //不分频            
}
/****************************************************
**  函数名称:IIC_Write_Byte      *******************
**  功能:总线写函数              *******************
**  输入值:IIC_Addr、REG_Address、REG_data *********
**  返回值:无                    *******************
****************************************************/
void IIC_Write_Byte(unsigned char IIC_Addr,unsigned char REG_Address,unsigned char REG_data)
{
  SLA_RW_flg = 0 ;                       //写命令
  IIC_Device_Addr = IIC_Addr;            //写入操纵器件地址(写)
  RW_Addr = REG_Address;                 //写入操纵地址(写)              
  RW_Data = REG_data;                    //写入数据内容(写)
  IIC_START();                           //启动发送命令
}
/****************************************************
**  函数名称:IIC_Read_Byte       *******************
**  功能:总线读函数              *******************
**  输入值:IIC_Addr、REG_Address *******************
**  返回值:无                    *******************
****************************************************/
unsigned char IIC_Read_BYTE(unsigned char IIC_Addr,unsigned int REG_Address)
{
  Recive_Over_flg = 0 ;                  //请接受完成标志位,等待IIC读取完成
  RW_Data = 0 ;                          //清接受数据缓存器
  SLA_RW_flg = 1 ;                       //读命令
  IIC_Device_Addr = IIC_Addr;            //写入操纵器件地址(读)
  RW_Addr = REG_Address;                 //写入操纵地址(读)              
  IIC_START();                           //启动发送命令
  while(Recive_Over_flg);
  return RW_Data ;                       //返回读取数据
}
/****************************************************
**  函数名称:IIC_ISR             *******************
**  功能:IIC中断函数             *******************
**  输入值:无                    *******************
**  返回值:无                    *******************
****************************************************/
#pragma interrupt_handler IIC_ISR:25
void IIC_ISR(void)
{
  unsigned char IIC_State = 0;                   //定义IIC状态变量,用于读取状态寄存器与预定的状态比较
  IIC_State = (TWSR & 0xF8);                     //取出IIC状态变量
  //接收模式        
  if(SLA_RW_flg == 1)                    
   {
     switch(IIC_State)                           //判断IIC当前状态
           {
             case START_08:                      //start已经发送,接下来发送SLA+W
                  TWDR = IIC_Device_Addr ;       //导入将要操纵的IIC元器件的地址
                  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE); //发送IIC器件地址,置位中断标志位      
                  break;
             case RE_START_10:                   //重复START已发送
                  TWDR = IIC_Device_Addr+1 ;     //SLA+R
                  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);//发送 地址+读
                  break;               
             case MT_SLA_ACK_18:                 //SLA+W 已发送;接收到 ACK
                  TWDR = RW_Addr; //写入要读寄存器的高8位地址                     
                  TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE);//发送数据(数据内容是:读器件地址)                                      
                  break;
             case MT_SLA_NACK_20:                //SLA+W 已发送接收到   NACK
                  TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);//发送停止信号并使能中断
                  break;         
             case MT_DATA_ACK_28:                //数据(要读寄存器首地址)已经发送,接收到ACK
                  IIC_START();                   //再发送起始信号               
                  break;               
             case MR_SLA_ACK_40:                 //SLA+R 已发送接收到ACK
                                  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);                          
                  break;               
             case MR_SLA_NACK_48:              //SLA+R 已发送接收到NACK
                              Recive_Over_flg = 1 ;
                  IIC_STOP();
                  break;        
             case MR_DATA_ACK_50:               //数据已经收到,应答
                              Recive_Over_flg = 1 ;                                       
                  IIC_STOP();         
                  break;               
             case MR_DATA_NACK_58:
                                  RW_Data = TWDR;                //读出地址中的数据                          
                              Recive_Over_flg = 1 ;                  
                  IIC_STOP();
                  break;               
            }

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

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

本版积分规则

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

GMT+8, 2024-8-26 04:21

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

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