历史上的今天
返回首页

历史上的今天

今天是:2024年09月26日(星期四)

正在发生

2021年09月26日 | 基于IAR开发环境的STM8S模拟IIC代码

2021-09-26 来源:eefocus

基于IAR STM8 2.10开发环境,STM8S005K6单片机,模拟IIC方式读写AT24C16或AT24C32,已验证可以正常对AT24C32进行读写数据,只是有个疑问,对于单片机接SDA脚的IO口进行方向控制反而引起时序不正常而读写不了数据,例程中是将此IO口始终设置为输出,不知道会不会有隐患,有待测试...  


以下是代码,完整代码请下载附件,包含完整工程!


#include "24Cxx.h"


#include "stm8s.h"


#include "stm8s_gpio.h"




#define AT24C32_SETSDAIN  GPIO_Init(AT24C32_SDA_PORT, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT)


#define AT24C32_SETSDAOUT  GPIO_Init(AT24C32_SDA_PORT, GPIO_PIN_6, GPIO_MODE_OUT_OD_LOW_SLOW)




#define I2C_SLAW 0xA0        /*器件地址选择及写标志*/


#define I2C_SLAR 0xA1        /*器件地址选择及读标志*/






void nops(void)


{


//        asm("nop");


//        asm("nop");


        uint16_t i = 0;


        for (; i < 5; i++);


}






// 总线复位


void I2C_Reset(void)


{


        AT24C32_SCL_HIGH;


        AT24C32_SDA_HIGH;


}




// I2C操作严重错误


void I2C_Error(void)


{


        //复位I2C总线


        I2C_Reset();


        


        //进入死循环


        while (1)


        {


        }


}




// 发送起始条件


void I2C_Start_A(void) /*起始条件*/


{


        AT24C32_SCL_HIGH;


        nops();




        AT24C32_SDA_LOW;


        nops();




        AT24C32_SCL_LOW;


        nops();


}




// 停止条件


void I2C_Stop_A(void)


{


        AT24C32_SDA_LOW;


        nops();




        AT24C32_SCL_HIGH;


        nops();




        AT24C32_SDA_HIGH;


        nops();




        AT24C32_SCL_LOW;


        nops();


}




// 产生一个时钟信号


uint8_t I2C_GenerateClock(void)


{


        uint8_t bData = 0;


        uint16_t t = 0;


        


        AT24C32_SCL_HIGH;        


        nops();


        for (t = 0; t < 6; t++);


        


        if (AT24C32_READSDA)


        {


                bData = 1;


        }


        


        AT24C32_SCL_LOW;                


        nops();




        return bData;


}






// 应答位


void I2C_Ack(uint8_t bAckYes)


{


        if (bAckYes)


        {


                AT24C32_SDA_LOW;


        }


        else


        {


                AT24C32_SDA_HIGH;


        }


        


        I2C_GenerateClock();


        


        AT24C32_SDA_HIGH;


}




// 发送数据子程序, ucData为要求发送的数据


uint8_t I2C_Send(uint8_t ucData)


{


        uint8_t i;


        


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


        {


                if (ucData & 0x80)


                {


                        AT24C32_SDA_HIGH;


                }


                else


                {


                        AT24C32_SDA_LOW;


                }


                


                ucData <<= 1;


                


                I2C_GenerateClock();


        }


        


        AT24C32_SDA_HIGH;


        


        return (!I2C_GenerateClock());


}




// 读一个字节的数据,并返回该字节值


uint8_t I2C_Read(void)


{


        uint8_t ucData = 0;


        uint8_t i;


        


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


        {


                ucData <<= 1;


                


                if (I2C_GenerateClock())


                {


                        ucData |= 1;


                }


        }


        return ucData;


}




// 设置下一步操作的地址(一字节地址)


uint8_t I2C_SetAddress(uint16_t u16Addr)


{


        // 发送启动信号


        I2C_Start_A();




        // 发送访问地址


        return (I2C_Send(I2C_SLAW) && I2C_Send(u16Addr));


}




// 设置下一步操作的地址(两字节地址)


uint8_t I2C_SetAddress16(uint16_t u16Addr)


{


        // 发送启动信号


        I2C_Start_A();


        // 发送从器件地址




        // 发送访问地址        


        return (I2C_Send(I2C_SLAW) && I2C_Send(u16Addr >> 8) && I2C_Send(u16Addr & 0xff));


}




// 向8位地址的器件( 如:24C02 )写数据  bAddressIs16bit = 0


// 向16位地址的器件( 如:24C32 )写数据 bAddressIs16bit = 1


void Write_Byte_24c32(uint8_t *pDat, uint16_t u16Addr, uint8_t ucNbyte, uint8_t bAddressIs16bit)


{


        uint8_t bWriteError = FALSE;        //写数据出错标志位


        uint8_t i;


        uint8_t ucDataBuf = 0;


        uint32_t Cnt = 0;




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


        {


                if (bAddressIs16bit)


                {


                        if (I2C_SetAddress16(u16Addr + i) == 0)


                        {


                                bWriteError = TRUE;


                                break;


                        }


                }


                else


                {


                        if (I2C_SetAddress(u16Addr + i) == 0)


                        {


                                bWriteError = TRUE;


                                break;


                        }


                }




                ucDataBuf = *(pDat + i);




                if (I2C_Send(ucDataBuf) == 0)


                {


                        bWriteError = TRUE;


                        break;


                }


                


                I2C_Stop_A();


                


                ucDataBuf = 12;


                


                do


                {


                        I2C_Start_A();


                } while ((++Cnt < 500000) && I2C_Send(I2C_SLAW) == 0);


                


                //如果50mS内还没有响应,则进入保护性报警状态


                if (Cnt == 500000)


                {


                        bWriteError = TRUE;


                        break;


                }


                


                I2C_Stop_A();


        }


        


        if (bWriteError)


        {


                I2C_Error();


        }


}




// 从8位地址的器件( 如:24C02 )读数据  bAddressIs16bit = 0


// 从16位地址的器件( 如:24C32 )读数据 bAddressIs16bit = 1


void Read_nByte_24c32(uint8_t *pDat, uint16_t u16Addr, uint8_t ucNbyte, uint8_t bAddressIs16bit)


{


        uint8_t bReadError标志寄存器 = FALSE;        //读EEPROM错误标志位

推荐阅读

史海拾趣

DFI公司的发展小趣事

DFI深知产品质量对于企业的重要性。因此,公司从设计到生产,都实施了严格的质量管理。在产品设计阶段,DFI的专责团队会对电路、机构和零组件进行严格的测试与检验,确保每个专案的设计和质量都具备一致的高质量。在生产阶段,所有产品出货前都必须通过完整的产品内部检验,以确保产品的可靠性和耐久性。这些质量管理措施使DFI的产品在市场上享有良好的口碑,也为公司赢得了众多客户的信任。

思博科技(Cybermax)公司的发展小趣事

为了确保产品质量和客户满意度,思博科技高度重视质量管理体系建设。公司引进了先进的质量管理理念和工具,建立了完善的质量管理体系。同时,公司还通过了ISO9001质量管理体系认证和多项行业认证。这些认证不仅证明了公司在质量管理方面的实力,还为客户提供了可靠的质量保证。

AiT Semiconductor Inc公司的发展小趣事

随着技术的不断成熟和产品的不断完善,AiT公司开始积极拓展市场。他们通过参加国际电子展会、与国内外知名企业建立合作关系等方式,不断提升品牌知名度和市场份额。同时,公司还针对不同行业和领域的需求,推出了定制化的半导体解决方案,进一步扩大了应用范围。这一系列的举措使得AiT公司在市场中实现了跨越式发展。

EKIT公司的发展小趣事

2023年10月,华为坤灵(HUAWEI eKit)在香港成功举办了分销新品发布会。针对香港市场的特点,HUAWEI eKit展示了面向SOHO办公、酒店餐饮、商业地产、零售商超等场景的新品,并通过整合政策、产品、解决方案、服务和数字工具平台等措施,助力香港区域分销伙伴不断开拓中小企业市场。通过与联强国际(香港)有限公司(SYNNEX)的紧密合作,HUAWEI eKit成功吸引了超过100名香港分销商参与此次发布会,进一步巩固了其在香港市场的地位。

DAPAudio公司的发展小趣事

随着公司产品的不断成熟和市场的逐渐扩大,DAPAudio开始将目光投向国际市场。通过与国际知名品牌的合作和自身的市场拓展努力,DAPAudio的产品逐渐进入欧美等发达国家和地区的市场。在国际市场上,DAPAudio凭借其卓越的产品性能和优质的服务赢得了广泛的赞誉和认可。

FOSLINK公司的发展小趣事

面对全球气候变化的严峻挑战,FOSLINK公司积极响应国家关于绿色发展的号召,将绿色转型作为企业发展的重要方向。公司致力于研发和生产低能耗、环保型的电子产品,并不断优化生产工艺流程,减少资源消耗和环境污染。同时,FOSLINK还积极推广绿色供应链管理,与供应商和客户共同构建绿色、低碳的产业链生态。这一系列的绿色转型举措,不仅彰显了FOSLINK的社会责任感,也为其赢得了更多消费者的青睐和支持。

问答坊 | AI 解惑

1.5V升压3.3V_5V[转载]

原文如下: ◆電池1本時(入力電圧1.5V時)  ・3.3V 最大負荷電流 約160mA=効率約81%  ・5.0V 最大負荷電流 約70mA ※出力5Vでは電池2本での使用を推奨します。 ◆電池2本時(入力電圧3. ...…

查看全部问答>

红外发射与接收程序

红外发射接收源程序…

查看全部问答>

如何实现恒压恒流充电?

来自 电子工程师技术交流(12425841)…

查看全部问答>

STM32热重启死机问题?

程序运行中需要运行 NVIC_SystemReset();这个函数,一旦运行就会死机 没办法单步调试,所以问下大家问题可能出在哪里? 重新上电启动就没有问题。谢谢大家了!…

查看全部问答>

ccs中调试程序出现问题

程序编译可以通过,但是rebuid all时会出现错误,如 Reset_VEC        B    _cy_begin                \\"pwm_generate_vec.asm\\", line 7:  AN IDENTIF ...…

查看全部问答>

请问大家一个关于iar for msp430仿真的问题!!

1、我用FET_examples目录中FET140文件夹下,fet140_ta01.c文件组建项目。 2、在iar for msp430 环境中,用软件模拟为什么不能进入定时中断呢? 3、是不是因为没有smclk的原因?在这个环境中如何设置lfx 和x2呢?并并我修改了程序,将 ...…

查看全部问答>

看看我的程序的警告:

Warning (14130): Reduced register \"current_state[7]~reg0\" with stuck data_in port to stuck value GNDWarning (14130): Reduced register \"current_state[6]~reg0\" with stuck data_in port to stuck value GNDWarning: Converted presett ...…

查看全部问答>

protelDXP 元件名系表--分立元件库中英文对照

protelDXP 元件名系表--分立元件库中英文对照…

查看全部问答>

单片机的抗干扰措施

单片机在嵌入式系统应用中,抗干扰性能是系统可靠性的重要指标,抗干扰设计是单片机系统研制中不可忽视的一个重要内容。下面就由福州卓跃教育就这问题做一具体介绍.        随着科学技术的迅速发展,单片机在各个领域中的 ...…

查看全部问答>

液晶19264底层驱动程序

#define  uchar unsigned char#define  uint  unsigned intuchar Page;     uchar Col,cc=0,dd=0; bdata char com_data;sbit mos_bit=com_data^7; void wtcom(void); /********************引脚 ...…

查看全部问答>