打印

M0516的IIC通讯问题

[复制链接]
2049|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
uestc2007|  楼主 | 2013-3-27 18:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个程序哪里有问题呢???IIC一直写不进去,SDA线一直没有结果,SCL时钟端一直都有,总线没有没空闲,大家帮我看看编程什么问题???我没有分啊。。。。
#define RD_DEVICE_ADDR 0xa9   //前6位器件固定,后1位看连线,最后1位是读写指令位
#define WR_DEVICE_ADDR 0xa8

void WriteByte(uint8_t addr,uint8_t data)
{        uint32_t i;
    DrvI2C_Open(400000);                  //打开IIC1设备 并配置时钟总线400KHZ                                  
    DrvI2C_Ctrl(1,0,0,0);                         //启动Start        清SI标志位
        while(I2C->CON.SI==0);                                //查询中断标志位 SI        如果忙则一直等待
        DrvI2C_WriteData(WR_DEVICE_ADDR);                //写从设备地址 发写命令
        DrvI2C_Ctrl(0,0,1,0);                                        //清SI标志位          start                 - [in]                1:Enable / 0:Disable                                                                                 */
                                            //   stop                 - [in]                1:Enable / 0:Disable                                                           
                                            //       intFlag         - [in]                Wrtie '1' to clear this flag                                                   
                                            //       ack                 - [in]                1:Enable / 0:Disable             
        while(I2C->CON.SI==0);
    DrvI2C_WriteData(addr);                     //写器件相应寄存器地址
        DrvI2C_Ctrl(0,0,1,1);
        while(I2C->CON.SI==0);
        DrvI2C_WriteData(data);                                   //写入数据
        DrvI2C_Ctrl(0,0,1,1);
        while(I2C->CON.SI==0);                           //发STOP信号
        DrvI2C_Ctrl(0,1,1,0);
        for(i=0;i<60;i++);
        DrvI2C_Close();
        for(i=0;i<6000;i++);
        for(i=0;i<6000;i++);                                                  
}
uint8_t I2C_ReadByte (uint32_t address)
{
        uint8_t DATA;
        DrvI2C_Open(400000);                                         //打开I2C1功能,并配置 I2C总线时钟为100KHZ       
    DrvI2C_Ctrl(1, 0, 0, 0);                                 //设定I2C控制比位   START并清中断标志
        while (I2C->CON.SI == 0);                                                //查询中断标志位 SI        如果忙则一直等待
    DrvI2C_WriteData (WR_DEVICE_ADDR);                                //先把数据写进相应的寄存器,但不发送数据到总线
    DrvI2C_Ctrl(0, 0, 1, 0);                                  
    while(I2C->CON.SI == 0 );                                                  //查询中断标志位 SI         如果忙则一直等待
        DrvI2C_WriteData (address);                //发送需要读写的地址
        DrvI2C_Ctrl(0, 0, 1, 1);                            //清标志位 SI 并使能应答
        while(I2C->CON.SI == 0 );                                                   //查询中断标志位 SI        如果忙则一直等待
        DrvI2C_Ctrl(1, 0, 1, 0);                            //设定I2C控制比位   START并清中断标志
        while(I2C->CON.SI == 0 );                                                   //查询中断标志位 SI        如果忙则一直等待
        DrvI2C_WriteData(RD_DEVICE_ADDR);                     //发送写命令  即从器件地址的最低位 R/W 位设置为 1
        DrvI2C_Ctrl(0, 0, 1, 1);                            //清SI并要求应答,I2CON内容发生变化,启动发送到总线
    while( I2C->CON.SI == 0 );                                                   //查询中断标志位 SI         如果忙则一直等待;直到发送完成

    I2C->DATA = 0xFF;                                                        //通过操作数据寄存器配合控制位的设置启动一次新的I2C操作(此句加与不加未影响到结果)
        /*"Software should load the data byte (to be transmitted)into I2DAT before new I2CON setting is done." 手册中该句怎么解释?*/
        DrvI2C_Ctrl(0, 0, 1, 0);                            //清标志位 SI
        while(I2C->CON.SI == 0);                                                   //查询中断标志位 SI         如果忙则一直等待
        DATA= DrvI2C_ReadData( );                                //读数据       
        DrvI2C_Ctrl( 0, 1, 1, 0);                     //清标志位 SI 并STOP

        DrvI2C_Close( );                                    //关闭I2C1功能

        return DATA;
}


//整个I2C初始化函数

void DrvI2C_Init(void)

{
  DrvI2C_Open(400000);         //打开I2C硬件并配置时钟总线400KHZ;
  DrvI2C_SetClockFreq (400000);//给I2C配置时钟频率;
  DrvI2C_GetStatus ();        //获取I2C状态码;
  DrvI2C_Ctrl(0, 0, 0, 0);   //设定I2C控制位,包括控制寄存器中的STA, STO, AA, SI。
}
void main (void)
{
UNLOCKREG();
    SYSCLK->PWRCON.XTL12M_EN = 1;
        /*等待外部12M晶振稳定*/
    DrvSYS_Delay(5000);
DrvGPIO_InitFunction(E_FUNC_I2C);  //把I/O 定义成SDA, SLK   
DrvGPIO_SetBit(E_PORT3,E_PIN4);                        //在使用之前需将 I2C_SDA 置高                     
DrvGPIO_SetBit(E_PORT3,E_PIN5);                        //在使用之前需将 I2C_SCL 置高
                       
        LOCKREG();
        DrvI2C_Init();
        DrvI2C_EnableInt();
         WriteByte(0x00,0x32);          //先地址后数据 CLK=1M; SCL=400K        输出频率
           WriteByte(0x01,0x87);           //时钟加倍
          WriteByte(0x02,0xFF);
                            WriteByte(0x03,0x32);
                            WriteByte(0x04,0x87);           //时钟加倍
                             WriteByte(0x05,0xFF);
                            WriteByte(0x06,0x27);                //输出电压35V
                            WriteByte(0x07,0x35);           //占空比        40%
                            WriteByte(0x08,0x35);                                                                                                                         
  //        }
while(1)
{;}
               
}

相关帖子

沙发
uestc2007|  楼主 | 2013-3-27 18:08 | 只看该作者
自己顶一下

使用特权

评论回复
板凳
smilingangel| | 2013-3-28 09:55 | 只看该作者
这程序的我看着没啥问题的啦,楼主检查下你的硬件的是否出现虚焊的

使用特权

评论回复
地板
smilingangel| | 2013-3-28 09:56 | 只看该作者
若是虚焊的话,程序时不能运行下去的,会一直停在程序中的某个while 循环的

使用特权

评论回复
5
uestc2007|  楼主 | 2013-3-28 10:10 | 只看该作者
  while(I2C->CON.SI==0);
我单步执行的时候,程序就一直停在这里,不知道是什么问题,因为后端芯片是BGA封装的,没办法测试是不是虚焊,我现在就是不确定是硬件问题还是软件问题

使用特权

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

本版积分规则

2

主题

5

帖子

0

粉丝