打印
[技术问答]

m0516 I2C 程序的问题

[复制链接]
1131|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
benscottsih|  楼主 | 2018-6-20 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我网上了找了新唐M051 IIC使用程序,这个程序,修改了一下,做成I2C256的程序,读写很不稳定?不知道哪里有问题跪求高手帮忙啊?
#include "M051.h"
//#include "Register_Bit.h"
#include "I2C.h"
//#include "delay.h"
//#include "SysConfig.h"

#define CLOCK_SETUP             0
#define CLOCK_EN                0xF
#define PLL_Engine_Enable       0
#define PLL_SEL                 0x00080000
#define CLOCK_SEL               0x0
#define I2C_CLOCK               99 //40K:  16m/(4*(I2C_CLOCK+1))

#define EEPROM_SLA         0xa0
#define DS1307_SLA         0xd0
#define WRITE               0x00
#define I2CREAD             0x01
#define SAFETY_COUNTER_LIMIT 5000
#define PageSize 64
uint16_t CycleTimerOut = 0 ;
void Init_I2C(void)
{

        APBCLK |= I2C0_CLKEN;              //Enable I2C0 clock
    I2CLK = I2C_CLOCK;                 //Set I2C0 clock rate                                 
    I2CON |= ENSI;                     //Enable I2C
}
/*****************************************
*º¯ÊýÃû³Æ:Timed_Write_Cycle
*Êä    Èë:ÎÞ
*Êä    ³ö:ÎÞ
*¹¦    ÄÜ:ͬ²½µÄдÖÜÆÚ
******************************************/

void Timed_Write_Cycle(uint8_t div,uint16_t addr)                  
{
   
         uint8_t ucDeviceAddr = 0;
        uint16_t loopSafetyCounter = 0;
        if(div == EEROM)
        {            
      ucDeviceAddr = EEPROM_SLA;
        }
        else  ucDeviceAddr = DS1307_SLA;
        CycleTimerOut = 0;
        while ((I2STATUS != 0x18)&&(CycleTimerOut<1000))
   {
       //Æô¶¯
                 CycleTimerOut++ ;
        I2CON |= STA;                        
        I2CON |= SI;
                 //I2c_Delay();
                loopSafetyCounter = 0;
        while ((I2CON & SI) != SI)
                {
                          loopSafetyCounter ++;
                        if (loopSafetyCounter > SAFETY_COUNTER_LIMIT )
                        {
                                break ;
                        }
                }
        I2CON &= ((~STA) & (~SI));   //SAFETY_COUNTER_LIMIT
  //É豸µØÖ·
        I2DAT = ucDeviceAddr | WRITE;
        I2CON |= SI;
                //I2c_Delay();
        loopSafetyCounter = 0;
        while ((I2CON & SI) != SI)
                {
                        loopSafetyCounter ++;
            if (loopSafetyCounter >SAFETY_COUNTER_LIMIT )
            {
                break ;
            }
                }
         
    if (I2STATUS != 0x18)                       //¼ì²éÓ¦´ð
    {
    // DEBUGMSG("Not ACK returned!");
     }      
    //Í£Ö¹
         }
    I2CON |= STO;
    I2CON |= SI;
//         I2c_Delay();
    loopSafetyCounter = 0;
    while (I2CON & STO)
                {
                                        loopSafetyCounter ++;
                                        if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                        {
                                                        break ;
                                        }
                        }
}
uint8_t I2C_Write_code(uint8_t div,uint16_t addr,uint8_t *data,uint16_t uclength)
{
    //TCSR0 &= ~CEN;,tmp = 0
    uint8_t ucDeviceAddr = 0,i=0;
    uint16_t loopSafetyCounter = 0;
          ucDeviceAddr = EEPROM_SLA;
         // I2CON &= (~SI);
    I2CON |= STA;
    I2CON |= SI; //¿ªÖжÏ
         
        loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
        {
                loopSafetyCounter ++;
                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                {
                                break ;
                }
        }
   // //I2CON &= (~STA);
        //tmp = I2STATUS ;
        if(I2STATUS != 0x08)
        {
                //return 0 ;
        }
        I2CON &= ((~STA)&(~SI));
    I2DAT = (ucDeviceAddr | WRITE);
        //I2CON |= AA; //Ó¦´ð
        I2CON |= SI;
    loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
        {
                        loopSafetyCounter ++;
                        if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                        {
                                        break ;
                        }
        }
        if(I2STATUS != 0x18)
        {
                //return 0 ;
        }
        if(div == EEROM)
        {
                I2DAT = (uint8_t)(addr>>8);        //gao di zhi
                //I2CON |= AA;
                I2CON |= SI;
                //I2c_Delay();
                loopSafetyCounter = 0;
                while ((I2CON & SI) != SI)
                {
                        loopSafetyCounter ++;
                        if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                        {
                                        break ;
                        }
                }
                if(I2STATUS != 0x28)
                {
                        //return 0 ;
                }
                I2DAT = (uint8_t)(addr);//(addr>>8);   //di di zhi
           // I2CON |= AA; //20170316
            I2CON |= SI;
               
            loopSafetyCounter = 0;
        while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
                if(I2STATUS != 0x28)
                {
                        //return 0 ;
                }
        }
       
        for(i=0 ;i<uclength ;i++)
        {
                I2CON |= AA;
                I2DAT = *(data+i);
                //I2CON &= (~AA);
                I2CON |= SI;
//                I2c_Delay();
                loopSafetyCounter = 0;
                while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
  }
        //I2CON &= (~AA); 2018 06 20
        I2CON |= STO;               
    I2CON |= SI;
//        I2c_Delay();
        loopSafetyCounter = 0;
    while (I2CON & STO)
        {
                loopSafetyCounter ++;
                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                {
                                break ;
                }
        }
    Timed_Write_Cycle(div,addr);
    return I2STATUS;
}
uint8_t I2C_Read(uint8_t div,uint16_t addr,uint8_t *pdata,uint8_t length)
{
    uint8_t temp,i;
        uint8_t ucDeviceAddr = 0;//,i = 0
    uint16_t loopSafetyCounter = 0;
        //if(div == EEROM)
        //ucDeviceAddr = EEPROM_SLA;
        if(div == EEROM)
        {            
        ucDeviceAddr = EEPROM_SLA;
        }
        else  ucDeviceAddr = DS1307_SLA;

    //TCSR0 &= ~CEN;
    // START
        //I2CON &= (~SI);  
    I2CON |= STA;
    I2CON |= SI;        
    loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
        {
                        loopSafetyCounter ++;
                        if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                        {
                                        break ;
                        }
        }         //Check SI set or not
     I2CON &= ((~STA)&(~SI));            //I2CON &= (~STA);  
//         temp = I2STATUS  ;                                    //STA needs to be cleared after START codition is generated
//        if (I2STATUS != 0x08)                        //Check status value after every step
//    {
//      return 0 ;
//    }
   
    //Control byte (SLA+W)
        //I2CON |=AA;  //Ó¦´ð
    I2DAT = (ucDeviceAddr | WRITE);
    I2CON |= SI;
    loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
        if(div == EEROM)
        {
                //I2CON |= AA;
                temp = (uint8_t)(addr>>8);
                I2DAT = temp ;        //gao di zhi
               
                //Short_Delay() ;       
                I2CON |= SI;
                loopSafetyCounter = 0;
                while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
               
                temp = (uint8_t)(addr);
                I2DAT =         temp;//(addr>>8);   //di di zhi                
                //Short_Delay() ;
                I2CON |= SI;
                loopSafetyCounter = 0;
        while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }

        }
        else
        {
            I2DAT = (uint8_t)(addr);//(addr>>8);
            I2CON |= SI;
            loopSafetyCounter = 0;
        while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
        }
    I2CON |= STA;         
    I2CON |= SI;                    
   loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }     //Check SI set or not
    I2CON &= ((~STA)&(~SI));         //I2CON &= (~STA);                 
    I2DAT = (ucDeviceAddr | I2CREAD);
    I2CON |= SI;
    loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
                //I2CON &= ((~STA)&(~SI));  
    I2CON |= AA;
//        I2CON |= SI;
//    loopSafetyCounter = 0;
//    while ((I2CON & SI) != SI)
//                {
//                                loopSafetyCounter ++;
//                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
//                                {
//                                                break ;
//                                }
//                }
        for(i=0;i<length;i++)
        {
                I2CON |= SI;
                loopSafetyCounter = 0;
                while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
                  *(pdata+i) = I2DAT;
   }
    I2CON &= (~AA);
    I2CON |= SI;
    loopSafetyCounter = 0;
    while ((I2CON & SI) != SI)
                {
                                loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }
    //STOP
    I2CON |= STO;               
    I2CON |= SI;
               
    loopSafetyCounter = 0;
    while (I2CON & STO)
                {
                    loopSafetyCounter ++;
                                if (loopSafetyCounter > SAFETY_COUNTER_LIMIT)
                                {
                                                break ;
                                }
                }     //To ensure STOP condition is generated, polling STO flag
    return 1;
}
void AT2ICcontinousWite(uint16_t addr,uint8_t *data,uint16_t uclength)
{
        uint32_t m,n ;
        //uint32_t unCurWirteCount = 0 ;
//        if(addr<64)
//        {
//                m=1 ;
//        }
//        else
//        {
            m=  (addr/PageSize)+1 ;
//        }
        if((addr+uclength)<(PageSize*m))
        {
                I2C_Write_code(EEROM,addr,data,uclength) ;
        }
        else
        {
                n=  ((addr+uclength)%PageSize) ;
                I2C_Write_code(EEROM,addr,data,uclength-n) ;
                Short_Delay() ;
                //Short_Delay() ;
                I2C_Write_code(EEROM,addr+uclength-n,data+uclength-n,n) ;
        }
//        if(uclength<=m)
//        {
//                I2C_Write_code(0,addr,data,uclength) ;
//        }
//        else
//        {
//                I2C_Write_code(0,addr,data,m) ;
//                uclength-=m ;
//                unCurWirteCount +=m ;
//                m = uclength/PageSize ;
//                n = uclength%PageSize ;
//                for(i=0 ;i<m ;i++)
//                {
//                        I2C_Write_code(0,addr+unCurWirteCount,data+unCurWirteCount,PageSize) ;
//                        unCurWirteCount += PageSize ;
//                }
//                I2C_Write_code(0,addr+unCurWirteCount,data+unCurWirteCount,n) ;
//        }
}
沙发
benscottsih|  楼主 | 2018-6-20 17:24 | 只看该作者
高手帮忙改一下,或者谁有M0516模拟I2C的程序啊?

使用特权

评论回复
板凳
幸福小强| | 2018-6-21 17:48 | 只看该作者
这个不是有硬件收发器吗,怎么还要模拟,模拟的话,你要懂I2C的时序图。

使用特权

评论回复
地板
yiyigirl2014| | 2018-6-21 20:20 | 只看该作者
很不稳定是个什么概念

使用特权

评论回复
5
小明的同学| | 2018-6-21 21:39 | 只看该作者
BSP里的例子有啥问题额??

使用特权

评论回复
6
benscottsih|  楼主 | 2018-6-22 13:29 | 只看该作者
yiyigirl2014 发表于 2018-6-21 20:20
很不稳定是个什么概念

就是有时候能读正确有时候读过来都是零

使用特权

评论回复
7
benscottsih|  楼主 | 2018-6-22 13:30 | 只看该作者
幸福小强 发表于 2018-6-21 17:48
这个不是有硬件收发器吗,怎么还要模拟,模拟的话,你要懂I2C的时序图。

这是的啊,就是不知道哪里错了,所以想换成IO模拟的

使用特权

评论回复
8
benscottsih|  楼主 | 2018-6-22 13:30 | 只看该作者
幸福小强 发表于 2018-6-21 17:48
这个不是有硬件收发器吗,怎么还要模拟,模拟的话,你要懂I2C的时序图。

这是的啊,就是不知道哪里错了,所以想换成IO模拟的

使用特权

评论回复
9
dongliushui| | 2018-6-23 23:37 | 只看该作者
那你模拟一下啊,看看你外设手册的时序图

使用特权

评论回复
10
zhdbao88| | 2018-6-25 15:21 | 只看该作者
是不是没有主机跟设备没有握手匹配成功,?
为什么不用StdDriver库函数的例程改写,用RegBased?
#define EEPROM_SLA         0xa0
#define DS1307_SLA         0xd0
总线上不是最多能挂128个设备? 这个不是左移1位+读写位,写到设备就是不是这个地址的吧

使用特权

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

本版积分规则

2

主题

10

帖子

0

粉丝