打印
[ZLG-MCU]

LM3S IIC作从机的问题

[复制链接]
3227|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mj2008|  楼主 | 2008-4-5 19:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
mj2008|  楼主 | 2008-4-7 14:17 | 只看该作者

顶一下

使用特权

评论回复
板凳
acteler| | 2008-4-8 21:42 | 只看该作者

我也帮着你顶一下,我也有同样的疑惑,也想使用从机

我也帮着你顶一下,我也有同样的疑惑,也想使用从机

使用特权

评论回复
地板
mj2008|  楼主 | 2008-4-8 21:47 | 只看该作者

wo

我今天调的差不多了能收发了,当要求从机不应答时我把从机功能关闭然后傻延时一小会儿,然后重新使能,只是不知道这个办法行不行,毕竟出现这种情况让我验证比较难

使用特权

评论回复
5
zlgmcu| | 2008-4-9 08:24 | 只看该作者

关于I2C做从机的问题,我们也正在研究

如果调试出了一个完善的例程,一定会及时与大家共享的。

(zlgmcu_wdx)

使用特权

评论回复
6
wahahaabc| | 2008-4-10 08:29 | 只看该作者

LM3S的I2C做从机的代码很简单

偶将一个LM3S8962的I2C配置为从机,将这个从机看成一个简单的I2C总线的EEPROM,就相24C02一样。主机调用写24C02的代码来写这个从机,写完以后又读出,判断读出的和写入的是否相同。这个代码已经在EASYARM8962开发板上调试通过。



// 包含头文件
#include "includes.h"
#include "LM3S_I2C.h"

// 定义I2C总线管脚名称
#define I2C_SCL     GPIO_PIN_2          /* SCL = PB2 */
#define I2C_SDA     GPIO_PIN_3          /* SDA = PB3 */

int I2CM_Init(unsigned int spd, unsigned char pri)
{
      spd = spd;


            // 使能所使用的外设
            SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

            GPIOPinTypeI2C(GPIO_PORTB_BASE, I2C_SCL|I2C_SDA);   // I2C管脚配置

            // 初始化I2C从机
            I2CSlaveInit( I2C_SLAVE_BASE, 0x7F&(0xA4>>1) );

            // 使能I2C从机
            I2CSlaveEnable( I2C_SLAVE_BASE );

            // 使能处理器中断
            //IntMasterEnable();

            // 使能I2C中断
            IntEnable(INT_I2C);

            // 使能I2C从机中断
            I2CSlaveIntEnable(I2C_SLAVE_BASE);

            // 设置I2C中断的优先级
            IntPrioritySet(INT_I2C, (pri << 5));

            return(TRUE);

}


INT8U eeprom[EEPROM_SIZE];
static unsigned int eeprom_addr=0;

// I2C中断服务函数
void I2C_ISR(void)
{      
      unsigned long state, rec_data;

      // 清除中断
      I2CSlaveIntClear(I2C_SLAVE_BASE);

      // 读取状态
      state = I2CSlaveStatus(I2C_SLAVE_BASE);
      
      //CommPrintf( UART0, "I2C ISR " );

      switch( state )
      {
            case I2C_SLAVE_ACT_RREQ_FBR:
                  eeprom_addr = I2CSlaveDataGet(I2C_SLAVE_BASE);
                  //CommPrintf( UART0, "first:0x%02X ", eeprom_addr );
            break;

            case I2C_SLAVE_ACT_RREQ:
                  rec_data = I2CSlaveDataGet(I2C_SLAVE_BASE);
                  
                  eeprom[eeprom_addr++] = rec_data;
                  
                  //CommPrintf( UART0, "0x%02X ", rec_data );
            break;

            case I2C_SLAVE_ACT_TREQ:
                  I2CSlaveDataPut(I2C_SLAVE_BASE, eeprom[eeprom_addr++]);
            break;

            case I2C_SLAVE_ACT_NONE:

            break;

            default:
            break;
      }
}
//

使用特权

评论回复
7
wahahaabc| | 2008-4-10 08:33 | 只看该作者

主机端的代码如下


static  void  TaskUART0 (void  *parg)
{
      INT8U err;
      INT8U write_data[EEPROM_SIZE], read_data[EEPROM_SIZE];
      INT32U i, ok_cnt=0;

      // I2C总线初始化
      I2C_Init();

      // UART0初始化
      CommInit();
      CommCfgPort( UART0, 115200, 8, COMM_PARITY_NONE, 1 );
      CommRxIntEn( UART0 );
      CommPrintf( UART0, "UART0 init complete " );

      OSTimeDly( OS_TICKS_PER_SEC*2 );


#define I2C_24CXX_SLAVE_ADDRESS     0xA0 // I2C总线测试,I2C总线上连接一个AT24C02芯片
#define I2C_MCU_SLAVE_ADDRESS       0xA4 // 用LM3S8962做的I2C从机,从逻辑上看就像一个I2C的EEPROM
#define I2C_GENERAL_CALL_ADDRESS    0x00
      while(1)
      {
            // 产生要写入的数据
            for( i=0; i<EEPROM_SIZE; i++ )
            {
                  write_data = rand()%EEPROM_SIZE;
                  read_data = 0;
            }

            // 写入
            I2C_WriteMultiBytes( I2C_MCU_SLAVE_ADDRESS, 0, &write_data[0], EEPROM_SIZE );
            
            //Delay(1000);

            // 读出
            I2C_ReadMultiBytes(  I2C_MCU_SLAVE_ADDRESS, 0, &read_data[0],  EEPROM_SIZE );
            

            // 比较
            for( i=0; i<EEPROM_SIZE; i++ )
            {
                  if( read_data!=write_data )
                  {
                        CommPrintf( UART0, "%d   ***ERROR*** ", ok_cnt );
                        while(1);
                  }
            }

            if( i>=EEPROM_SIZE )
            {
                  ok_cnt++;
                  CommPrintf( UART0, "%d---OK ", ok_cnt );
            }

            OSTimeDly( OS_TICKS_PER_SEC/20 );
      }
}

使用特权

评论回复
8
mj2008|  楼主 | 2008-4-10 12:53 | 只看该作者

楼上

楼上没有看明白我的帖子的意思。你的程序里头体现不出我说的问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

67

帖子

0

粉丝