历史上的今天
返回首页

历史上的今天

今天是:2024年11月25日(星期一)

正在发生

2019年11月25日 | STM8L15X 硬件I2C调试总结

2019-11-25 来源:eefocus

最近接到一个项目需要使用STM8L上硬件I2C与SN3731通信,用户方是个方案商,硬件设计人员也没留测试点,直接就把板子焊了拿来了。调试时除了swio口能用所有都不能用,硬件设计大概是为了显得自己焊接技术牛B吧,调试用的板子用0402的封装,IC除了找不到QFN的曲阿布都用的QFN,做项目时不能说,在这里我先问候一下他娘亲。,,,。


这块板子经过大量的补焊终于可以上电出时序了。


调试STM8的硬件I2C master 注意一下几点,可以少走弯路:


1、需要配置GPIO引脚为GPIO_Mode_Out_OD_HiZ_Slow或fast,如果要提高抗干扰能力,完全可以配置为推挽输出模式的,我使用的是GPIO_Mode_Out_PP_High_Slow,或Fast,否则手摸都可能死锁。


2、如果是开漏高阻的需要上拉电阻,这个电阻很重要,影响稳定性,手册上说4.7k是可以,建议小于这个值,否则手摸都可能卡死。这个还取决于slave端的电流拉动能力,其实就是ack时的上拉能力。


3、刚开始调试不建议用中断模式的


4、I2C的速度可调,数值我测试使用40k,实际测试基本准确,稳定了可根据slave情况提高速度


5、必须有slave端,否则你就在while中加超时以便可以跳出来,要不就会收不到slave的ack信号一直卡死在这里。也可以做解锁代码进去,我的如下(这个是为解决抗干扰后加的,实践证明很有效):


。。。

 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){if(++timeout>MaxTimeOut)goto stop;}


。。。


 stop:

    I2CClearStatus();

    I2C_GenerateSTOP(I2C1,ENABLE);  //停止信号  

    I2C_DeInit(I2C1);

    I2C_SoftwareResetCmd(I2C1,ENABLE);

    I2C_3731_Init(0);

 


硬件I2C并不像网上大部分人认为的这么多坑,对硬件熟悉的话不会走太多弯路,大部分卡死估计主要是地址不对,对于st的例程,如果地址是错的或者没接,或者没上电,或者没选通,或者关断使能了等等可能只要有一种情况发生,slave就根本不会响应ack,那么主机就一直在等待中,估计很多人是掉这个坑里了。


硬件I2C速度快(超过400khz没问题),省代码,如果软件的已经调通了还是推荐改成硬件的。


void I2C_3731_Init(unsigned char Addr)

{

 GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Slow);

                GPIO_Init(GPIOC, GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Slow);

                CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);

  /* I2C  clock Enable*/

  CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);  

  

  /* Initialize I2C peripheral */

  I2C_Init(I2C1,40000, Addr, //I2C_MAX_FAST_FREQ

           I2C_Mode_I2C, I2C_DutyCycle_2,

           I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);

}



void I2C_3731_BufferWrite(u8* pBuffer,u16 WriteAddr,u8 NumByte)//I2Cдº¯Êý

{

    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//»ñȡָ¶¨µÄ±ê־״̬£¨ÅжÏ×ÜÏß·±Ã¦×´Ì¬£©

    

    I2C_GenerateSTART(I2C1, ENABLE);

     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//¼ì²âÖ¸¶¨ÐźÅ״̬£¨EV5ʼþ£©Èç¹ûûÓз¢ËÍÍê³ÉÔÚÕâÀïµÈ´ý£¬×¢Ò⣡ºÅµÄÓ¦ÓÃ


     I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS+((WriteAddr/256)<<1),I2C_Direction_Transmitter);//²»´óÓÚ24C16µÄÆ÷¼þµØÖ·

     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    

    I2C_SendData(I2C1,(u8)(WriteAddr));//µÍ8λ×Ö½ÚµØÖ·

    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));//£¨EV8ʼþ£©

    

    while(NumByte--)

    {

        I2C_SendData(I2C1,*pBuffer);

        pBuffer++;

        

        if(NumByte==0)

        {

            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        }

        else

        {

            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));

        }        

    }

    I2C_GenerateSTOP(I2C1,ENABLE);  //Í£Ö¹ÐźŠ  

}


void I2C_3731_BufferRead(u8* pBuffer,u16 ReadAddr,u8 NumByte)

{

    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));

    I2C_GenerateSTART(I2C1,ENABLE);    

    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));

    

//    if(EE_TYPE>AT24C16)

//    {

//        I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS,I2C_Direction_Transmitter);

//        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

//        

//        I2C_SendData(I2C1,(u8)(ReadAddr>>8));

//        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));

//    }

//    else

    {   //1010 000 0

        I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS+((ReadAddr/256)<<1),I2C_Direction_Transmitter);

        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    }

    

    I2C_SendData(I2C1,(u8)(ReadAddr));

    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));

    

    I2C_GenerateSTART(I2C1,ENABLE);    

    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));

    

    I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS,I2C_Direction_Receiver);

    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    

    while(NumByte)

    {

        if(NumByte==1)

        {

            I2C_AcknowledgeConfig(I2C1,DISABLE);

            I2C_GenerateSTOP(I2C1,ENABLE); 

        }

        

        if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED))

        {

            *pBuffer=I2C_ReceiveData(I2C1);

            pBuffer++;

            NumByte--;

        }

    }

    

    I2C_AcknowledgeConfig(I2C1,ENABLE);

}


//main

I2C_3731_Init(0); 


      for (i = 0; i < BUFFERSIZE; i++)

      {

        TxBuffer[i] = i;

      }

      I2C_3731_BufferWrite(TxBuffer,0x00,sizeof(TxBuffer));


推荐阅读

史海拾趣

ADL [ADL Embedded Solutions Inc]公司的发展小趣事

ADL Embedded Solutions Inc. 是一家专注于嵌入式计算解决方案的公司,以下是该公司发展的五个相关故事:

  1. 公司创立与早期发展: ADL Embedded Solutions Inc. 成立于1994年,总部位于美国科罗拉多州科罗拉多斯普林斯市。公司初期致力于为工业、军事、航空航天等领域提供嵌入式计算解决方案。其产品包括工业级嵌入式计算板卡、系统、模块等。

  2. 技术创新与产品推出: ADL 在嵌入式计算领域不断进行技术创新,并推出了多款具有竞争力的产品。公司的产品具有高性能、低功耗、高可靠性等特点,得到了客户的广泛认可。其产品广泛应用于军事航空、医疗、交通、工业自动化等领域。

  3. 客户合作与项目案例: ADL 与各行业的领先企业建立了长期稳定的合作关系,并参与了众多重要项目。例如,公司为航空航天领域的客户提供了符合严格标准的嵌入式计算解决方案,为医疗设备制造商提供了可靠的嵌入式计算板卡等。

  4. 全球市场拓展与国际化发展: ADL 通过不断拓展国内外市场,实现了全球化发展。公司在美国、欧洲和亚洲等地设有销售办事处和服务中心,为客户提供本地化的技术支持和服务。同时,ADL 的产品远销全球各地,深受国际客户的青睐。

  5. 未来展望与持续发展: ADL 将继续致力于技术创新和产品开发,满足客户不断变化的需求。公司将不断扩大在工业、军事、医疗等领域的市场份额,加强与客户的合作,保持行业领先地位,实现业务的持续增长和发展。

Azoteq公司的发展小趣事

最近,Azoteq宣布推出了一款电容、电感和霍尔效应组合传感器——IQS620。这款传感器是传感领域的重大突破,它将电容式触摸和接近传感、电感传感以及霍尔效应传感集成在一个低姿态的封装中。这种高度集成化的设计使得IQS620在可穿戴设备、移动设备和安全等多个领域都有广泛的应用前景。IQS620的推出,不仅展示了Azoteq在传感技术方面的深厚实力,也为其在未来的市场竞争中注入了新的活力。

这些故事展示了Azoteq公司在电子行业中的发展历程和取得的成就。从创立初期的LightSense™系列产品,到后续的电容式触摸和接近感应市场拓展,再到PowerSense™和ProxFusion®产品系列的推出,以及最新的IQS620传感器的发布,Azoteq始终紧跟市场趋势,不断创新,为客户提供高质量的半导体解决方案。

Bombardier Inc公司的发展小趣事

1976年,庞巴迪公司的航空业务经历了重大变革。其加拿大航空子公司被加拿大政府收购,成为加拿大主要的航空企业。在此期间,庞巴迪在电子系统方面的研发能力得到了进一步提升。公司开始涉足更先进的航空电子技术,如自动驾驶系统、导航系统等,为现代航空业的发展做出了重要贡献。

Electro Technik Industries公司的发展小趣事

作为一家具有社会责任感的企业,ETI始终关注环保问题。公司积极推广绿色生产理念,采用环保材料和工艺进行生产。同时,ETI还投入大量资金用于环保设施的建设和运营,减少了对环境的污染。此外,ETI还积极参与社会公益活动,为环保事业贡献自己的力量。这些举措使ETI在业界树立了良好的形象,赢得了社会各界的广泛赞誉。

艾迈斯(AMASS)公司的发展小趣事

艾迈斯(AMASS)公司创立之初,便专注于智能设备动力连接器领域。面对市场的激烈竞争和技术的不断更新,公司创始人凭借深厚的行业经验和前瞻性的眼光,带领团队攻克了一个又一个技术难关。他们深入市场调研,精准把握消费者需求,成功推出了一系列具有竞争力的连接器产品。这些产品不仅性能稳定、质量可靠,而且具有极高的性价比,迅速在市场上赢得了良好的口碑。

Adaptive Interconnect Electronics, Inc. [AIE]公司的发展小趣事

随着电子技术的飞速发展,AIE公司不断投入研发力量,推出了一系列具有创新性的测试配件产品。其中,AIE金属探头以其高精度、高稳定性的特点,受到了市场的广泛认可。此外,AIE还针对汽车行业推出了ADK汽车诊断试剂盒,为汽车维修和诊断提供了便捷、高效的解决方案。这些技术创新和产品升级不仅提升了AIE的市场地位,也推动了电子测试技术的不断进步。

问答坊 | AI 解惑

电子制动系统汽车用上飞机的刹车!!

汽车借用飞机科技早已屡见不鲜,从发动机涡轮增压技术,到空气动力学配件等都是将成熟的飞机技术成功转移到汽车上的典型案例。目前,又一项飞机技术将运用到未来汽车上,它就是电子制动系统。 电子制动系统在航空领域应用相当普遍,且制动 ...…

查看全部问答>

函数信号发生器制作方法的比较与分析

函数信号发生器制作方法的比较与分析…

查看全部问答>

问一下ARM中断函数的格式

void __irq watchdogIRQ(void) {         ledblink();         isBlink=~isBlink;         if(isBlink==0)         {           ...…

查看全部问答>

关于BIT伪指令的用法

我用的是非力谱的P89LPC935单片机,用这条指令结果是多少?? BUSY  BIT  09H 09H 好象不可以位寻址??…

查看全部问答>

求 用Borland c/c++ 4.5编译 uCOS-II时的一个插件

用Borland c/c++ 4.5编译 uCOS-II时,需要对Borland c/c++ 兼容汇编语言,需要一个TASM.EXE 插件,哪位兄弟有的话,给兄弟传一下。谢谢! 20weiliaoshei08@163.com …

查看全部问答>

程序不能显示大尺寸的JPEG图片????为何???

我的程序可以显示小尺寸的JPEG图片,但是大尺寸的就不行了,为什么呢? 高手可否指点一二呢?? 谢谢!…

查看全部问答>

关于pcb的问题

想画个板子  需要用到ethernet 100/1000 的原理图和pcb库  原理图还好可以自己画, 但是对于pcb库来说就有点难了 哪位大哥大姐有这两样  小弟谢谢喽  ~~~…

查看全部问答>

STM32F1系列的ADC采样的时钟可以用外部时钟吗?

我想用外部时钟进行AD采样,不知道是否可行。…

查看全部问答>

关于团的EK-LM3S811-ND板子

用的是IAR EW for ARM 6.30,驱动是光盘上的,不能下载和debug,难道只能用CSS或者keil?…

查看全部问答>