4082|0

71

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

STM32F746 模拟I2C读取电子罗盘数据 [复制链接]

本帖最后由 天天好心情亲 于 2015-12-12 14:23 编辑

STM32F746官方没有模拟I2C例程,于是小编自己参考网上的一些大神的资料,自己写了一个模拟I2C读取电子罗盘数据的程序 /***************I2C程序***********************************/#include "stm32f7xx_hal_conf.h"

#define I2C_TIMING      0x40912732
/* I2C1 init function */
void I2C1_Config(void)
{
        I2C_HandleTypeDef I2c1Handle;
        GPIO_InitTypeDef gpioInitStruct;       
        __GPIOB_CLK_ENABLE();
        __I2C1_CLK_ENABLE();
        gpioInitStruct.Pin       =  GPIO_PIN_9|GPIO_PIN_8;
  gpioInitStruct.Mode      = GPIO_MODE_OUTPUT_PP;//GPIO_MODE_AF_OD;
  gpioInitStruct.Pull      = GPIO_PULLUP;
  gpioInitStruct.Speed     = GPIO_SPEED_HIGH;
  gpioInitStruct.Alternate = I2Cx_SCL_SDA_AF;
  HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInitStruct);


  I2c1Handle.Instance = I2C1;
  I2c1Handle.Init.Timing = DISCOVERY_I2Cx_TIMING;//0x00303D5D;
  I2c1Handle.Init.OwnAddress1 = 0;
  I2c1Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  I2c1Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  I2c1Handle.Init.OwnAddress2 = 0;
  I2c1Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  I2c1Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  I2c1Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  HAL_I2C_Init(&I2c1Handle);

    /**Configure Analogue filter
    */
  HAL_I2CEx_AnalogFilter_Config(&I2c1Handle, I2C_ANALOGFILTER_ENABLE);

        I2C1_SCL_H;;
        I2C1_SDA_H;;
}

uint32_t I2CStep;
void I2C1_Delay(void)
{
        I2CStep=150;
        while(I2CStep--);
}       
uint8_t I2C1_Start(void)
{
        I2C1_SDA_H;
        I2C1_Delay();
        I2C1_SCL_H;
        I2C1_Delay();
        if(!I2C1_SDA) return 0;     //   如果数据线忙,则推退出
        I2C1_SDA_L;
        return 1;
}
void I2C1_Stop(void)
{
        I2C1_SCL_L;
        I2C1_Delay();
        I2C1_SDA_L;
        I2C1_Delay();
        I2C1_SCL_H;
        I2C1_Delay();
        I2C1_SDA_H;
        I2C1_Delay();
}
void I2C1_Ack(void)
{
        I2C1_SCL_L;
        I2C1_Delay();
        I2C1_SDA_L;
        I2C1_Delay();
        I2C1_SCL_H;
        I2C1_Delay();
        I2C1_SCL_L;
        I2C1_Delay();
}
void I2C1_NAck(void)
{
          I2C1_SCL_L;
    I2C1_Delay();
    I2C1_SDA_H;
    I2C1_Delay();
    I2C1_SCL_H;
    I2C1_Delay();
    I2C1_SCL_L;
    I2C1_Delay();
}
uint8_t I2C1_WaitAck(void)
{
                I2C1_SCL_L;
    I2C1_Delay();
    I2C1_SDA_H;                       
    I2C1_Delay();
    I2C1_SCL_H;
    I2C1_Delay();
    if(I2C1_SDA)
    {
                I2C1_SCL_L;
                return 0;
    }
    I2C1_SCL_L;
    return 1;
}
void I2C1_SendByte(uint8_t SendByte) //
{
    uint8_t i=8;
    while(i--)
        {
                I2C1_SCL_L;
                I2C1_Delay();
                if(SendByte&0x80)
                        I2C1_SDA_H;
                else
                        I2C1_SDA_L;
                SendByte<<=1;
                I2C1_Delay();
                I2C1_SCL_H;
                I2C1_Delay();
        }
        I2C1_SCL_L;
}
uint8_t I2C1_ReceiveByte(void)  //
{
        uint8_t i=8;
        uint8_t ReceiveByte=0;

        I2C1_SDA_H;                               
        while(i--)
        {
                ReceiveByte<<=1;      
                I2C1_SCL_L;
                I2C1_Delay();
                I2C1_SCL_H;
                I2C1_Delay();       
                if(I2C1_SDA)
                {
                        ReceiveByte|=0x01;
                }
        }
        I2C1_SCL_L;
        return ReceiveByte;
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
uint8_t I2C1_Read_Byte(unsigned char ack)
{
        unsigned char i,receive=0;
        I2C1_SDA;//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        I2C1_SCL_L;
                                I2C1_Delay();
                                I2C1_SCL_H;
        receive<<=1;
        if(I2C1_SDA)receive++;   
                                I2C1_Delay();
    }                                         
    if (ack)
        I2C1_Ack();//发送nACK
    else
        I2C1_NAck(); //发送ACK   
    return receive;
}
/***********************************************************************************
*
*     MPU6050用到的函数
*
*
*
**************************************************************************************/
/**************************实现函数********************************************
*函数原型:                unsigned char I2C_ReadOneByte(unsigned char rI2C_Add,unsigned char addr)
*功  能:            读取指定设备 指定寄存器的一个值
输入        I2C_Addr  目标设备地址
                addr           寄存器地址
返回   读出来的值
*******************************************************************************/
unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)
{
        unsigned char res=0;

        I2C1_Start();       
        I2C1_SendByte(I2C_Addr);           //发送写命令
        res++;
        I2C1_WaitAck();
        I2C1_SendByte(addr); res++;  //发送地址
        I2C1_WaitAck();          
        //IIC_Stop();//产生一个停止条件       
        I2C1_Start();       
        I2C1_SendByte(I2C_Addr+1); res++;          //进入接收模式                          
        I2C1_WaitAck();
        res=I2C1_Read_Byte(0);          
  I2C1_Stop();//产生一个停止条件

        return res;
}



/**************************实现函数********************************************
*函数原型:                u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)
*功  能:            读取指定设备 指定寄存器的 length个值
输入        dev  目标设备地址
                reg          寄存器地址
                length 要读的字节数
                *data  读出的数据将要存放的指针
返回   读出来的字节数量
*******************************************************************************/
uint8_t IICreadBytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data){
    uint8_t count = 0;

        I2C1_Start();
        I2C1_SendByte(dev);           //发送写命令
        I2C1_WaitAck();
        I2C1_SendByte(reg);   //发送地址
  I2C1_WaitAck();          
        I2C1_Start();
        I2C1_SendByte(dev+1);  //进入接收模式       
        I2C1_WaitAck();

    for(count=0;count
                 if(count!=length-1)data[count]=I2C1_Read_Byte(1);  //带ACK的读数据
                         else  data[count]=I2C1_Read_Byte(0);         //最后一个字节NACK
        }
    I2C1_Stop();//产生一个停止条件
    return count;
}

/**************************实现函数********************************************
*函数原型:                u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data)
*功  能:            将多个字节写入指定设备 指定寄存器
输入        dev  目标设备地址
                reg          寄存器地址
                length 要写的字节数
                *data  将要写的数据的首地址
返回   返回是否成功
*******************************************************************************/
uint8_t IICwriteBytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data){

        uint8_t count = 0;
        I2C1_Start();
        I2C1_SendByte(dev);           //发送写命令
        I2C1_WaitAck();
        I2C1_SendByte(reg);   //发送地址
  I2C1_WaitAck();
        for(count=0;count                 I2C1_SendByte(data[count]);
                I2C1_WaitAck();
         }
        I2C1_Stop();//产生一个停止条件

    return 1; //status == 0;
}

/**************************实现函数********************************************
*函数原型:                u8 IICreadByte(u8 dev, u8 reg, u8 *data)
*功  能:            读取指定设备 指定寄存器的一个值
输入        dev  目标设备地址
                reg           寄存器地址
                *data  读出的数据将要存放的地址
返回   1
*******************************************************************************/
uint8_t IICreadByte(uint8_t dev, uint8_t reg, uint8_t *data){
        *data=I2C_ReadOneByte(dev, reg);
    return 1;
}

/**************************实现函数********************************************
*函数原型:                unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data)
*功  能:            写入指定设备 指定寄存器一个字节
输入        dev  目标设备地址
                reg           寄存器地址
                data  将要写入的字节
返回   1
*******************************************************************************/
unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data){
    return IICwriteBytes(dev, reg, 1, &data);
}

/**************************实现函数********************************************
*函数原型:                u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)
*功  能:            读 修改 写 指定设备 指定寄存器一个字节 中的多个位
输入        dev  目标设备地址
                reg           寄存器地址
                bitStart  目标字节的起始位
                length   位长度
                data    存放改变目标字节位的值
返回   成功 为1
                失败为0
*******************************************************************************/
uint8_t IICwriteBits(uint8_t dev,uint8_t reg,uint8_t bitStart,uint8_t length,uint8_t data)
{

    uint8_t b;
    if (IICreadByte(dev, reg, &b) != 0) {
        uint8_t mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);
        data <<= (8 - length);
        data >>= (7 - bitStart);
        b &= mask;
        b |= data;
        return IICwriteByte(dev, reg, b);
    } else {
        return 0;
    }
}

/**************************实现函数********************************************
*函数原型:                u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)
*功  能:            读 修改 写 指定设备 指定寄存器一个字节 中的1个位
输入        dev  目标设备地址
                reg           寄存器地址
                bitNum  要修改目标字节的bitNum位
                data  为0 时,目标位将被清0 否则将被置位
返回   成功 为1
                失败为0
*******************************************************************************/
uint8_t IICwriteBit(uint8_t dev, uint8_t reg, uint8_t bitNum, uint8_t data){
    uint8_t b;
    IICreadByte(dev, reg, &b);
    b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
    return IICwriteByte(dev, reg, b);
}

//------------------End of File----------------------------


i2c初始化程序.png (95.6 KB, 下载次数: 3)

i2c初始化程序

i2c初始化程序

I2C模拟程序.png (49.18 KB, 下载次数: 3)

I2C模拟程序

I2C模拟程序

读取电子罗盘的数据.png (68.37 KB, 下载次数: 3)

读取电子罗盘的数据

读取电子罗盘的数据

串口数据.png (12.59 KB, 下载次数: 0)

串口数据

串口数据

I2C.txt

9.53 KB, 下载次数: 21

I2C

STM32f746模拟I2C 读取HMC5883L.txt

1.71 KB, 下载次数: 20

STM32f746模拟I2C 读取HMC5883L

此帖出自stm32/stm8论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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