基于IAR开发环境的STM8S模拟IIC代码

发布者:blazings最新更新时间:2021-09-26 来源: eefocus关键字:IAR  开发环境  STM8S  模拟IIC 手机看文章 扫描二维码
随时随地手机看文章

基于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错误标志位

[1] [2]
关键字:IAR  开发环境  STM8S  模拟IIC 引用地址:基于IAR开发环境的STM8S模拟IIC代码

上一篇:STM8S GPIO模拟I2C的底层代码
下一篇:STM8S105 GPIO寄存器方法

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved