搜索
bottom↓
回复: 8

HMC5883L 模拟I2C程序STM32

[复制链接]

出0入0汤圆

发表于 2013-9-10 15:26:24 | 显示全部楼层 |阅读模式
不多说,直接上程序

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-9-12 18:16:21 | 显示全部楼层
专门为新手准备的。。。

出0入17汤圆

发表于 2014-3-31 22:16:34 | 显示全部楼层
楼主好人啊,我用STM8L模拟的,读出来的全是0xff, 感觉是I2C没搞定,参考下楼主的

出0入0汤圆

发表于 2014-4-1 21:30:57 | 显示全部楼层
radar_12345 发表于 2014-3-31 22:16
楼主好人啊,我用STM8L模拟的,读出来的全是0xff, 感觉是I2C没搞定,参考下楼主的 ...

如果读出来全F,检查一下你IO口模式设置是不是对的。
I2C的IO口需要设置为开漏输出,然后在线上加上拉电阻。

话说楼主为什么要用STM32模拟I2C呢?STM32不应该带硬件I2C控制器吗?

出0入0汤圆

发表于 2014-6-11 19:33:31 | 显示全部楼层
#在这里快速回复这个模拟I2C的代码也是在本站下载的,原来是访问EEPROM的。  我使用STM32来访问I2C接口的铁电存储器,FM24CL16,2K字节,比访问EEPROM要方便一点,所以简单修改了一下,比原来少很多。  感谢ground网友提供的原始代码! FM24CL16的手册由于文件服务器问题,暂时传不上来。等阿莫弄好了再传吧。   代码就不打包了,直接贴上来了 ================================= I2C的引脚配置:  /* Configure I2C1 pins: SCL and SDA */   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;   GPIO_Init(GPIOB, &GPIO_InitStructure); ================================= /******************************************************************************* * File Name          : i2c_fram.h * Author             : MCD Application Team * Version            : V2.0.1 * Date               : 06/13/2008 * Description        : Header for i2c_ee.c module *******************************************************************************/ /* Define to prevent recursive inclusion ------------------------------------ */ #ifndef __I2C_FRAM_H #define __I2C_FRAM_H  /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h"  /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/   /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */   bool I2C_FRAM_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite); bool I2C_FRAM_BufferRead(u8* pBuffer, u16 ReadAddr, u16 NumByteToRead);  #endif /* __I2C_FRAM_H */  ================================= /******************************************************************************* * File Name          : i2c_fram.c * Author             : Appcat * Version            : V0.0.1 * Date               : 07/11/2009 * Description        : This file provides a set of functions needed to manage the *                      communication between I2C peripheral and I2C FM24CL16 FRAM. *******************************************************************************/  /* Includes ------------------------------------------------------------------*/ #include "i2c_fram.h"  /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define I2C_Speed              100000 #define I2C1_SLAVE_ADDRESS7    0xA0 #define I2C_PageSize           256  #define SCL_H         GPIOB->BSRR = GPIO_Pin_6 #define SCL_L         GPIOB->BRR  = GPIO_Pin_6      #define SDA_H         GPIOB->BSRR = GPIO_Pin_7 #define SDA_L         GPIOB->BRR  = GPIO_Pin_7  #define SCL_read      GPIOB->IDR  & GPIO_Pin_6 #define SDA_read      GPIOB->IDR  & GPIO_Pin_7   /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ vu8 FRAM_ADDRESS;  /* Private function prototypes -----------------------------------------------*/  /**/ void I2C_delay(void) {            u8 i=150; //这里可以优化速度        ,经测试最低到5还能写入    while(i)     {       i--;     }  }  bool I2C_Start(void) {         SDA_H;         SCL_H;         I2C_delay();         if(!SDA_read)return FALSE;        //SDA线为低电平则总线忙,退出         SDA_L;         I2C_delay();         if(SDA_read) return FALSE;        //SDA线为高电平则总线出错,退出         SDA_L;         I2C_delay();         return TRUE; }  void I2C_Stop(void) {         SCL_L;         I2C_delay();         SDA_L;         I2C_delay();         SCL_H;         I2C_delay();         SDA_H;         I2C_delay(); }  void I2C_Ack(void) {                 SCL_L;         I2C_delay();         SDA_L;         I2C_delay();         SCL_H;         I2C_delay();         SCL_L;         I2C_delay(); }  void I2C_NoAck(void) {                 SCL_L;         I2C_delay();         SDA_H;         I2C_delay();         SCL_H;         I2C_delay();         SCL_L;         I2C_delay(); }  bool I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK {         SCL_L;         I2C_delay();         SDA_H;                                 I2C_delay();         SCL_H;         I2C_delay();         if(SDA_read)         {       SCL_L;       return FALSE;         }         SCL_L;         return TRUE; }  void I2C_SendByte(u8 SendByte) //数据从高位到低位// {     u8 i=8;     while(i--)     {         SCL_L;         I2C_delay();       if(SendByte&0x80)         SDA_H;         else          SDA_L;            SendByte<<=1;         I2C_delay();                 SCL_H;         I2C_delay();     }     SCL_L; }  u8 I2C_ReceiveByte(void)  //数据从高位到低位// {      u8 i=8;     u8 ReceiveByte=0;      SDA_H;                                     while(i--)     {       ReceiveByte<<=1;             SCL_L;       I2C_delay();           SCL_H;       I2C_delay();               if(SDA_read)       {         ReceiveByte|=0x01;       }     }     SCL_L;     return ReceiveByte; }  bool I2C_FRAM_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite) {         u8 Addr = 0, count = 0;          Addr = WriteAddr / I2C_PageSize;          count = WriteAddr % I2C_PageSize;          Addr = Addr << 1;          Addr = Addr & 0x0F;            FRAM_ADDRESS = I2C1_SLAVE_ADDRESS7 | Addr;      if (!I2C_Start()) return FALSE;     I2C_SendByte(FRAM_ADDRESS);//设置器件地址+段地址      if (!I2C_WaitAck())         {                 I2C_Stop();                  return FALSE;         }     I2C_SendByte(count);   //设置段内地址               I2C_WaitAck();                            while(NumByteToWrite--)         {           I2C_SendByte(* pBuffer);           I2C_WaitAck();       pBuffer++;         }         I2C_Stop();           //注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)           //Systick_Delay_1ms(10);         return TRUE; }   //读出1串数据          bool I2C_FRAM_BufferRead(u8* pBuffer, u16 WriteAddr, u16 NumByteToRead) {                         u8 Addr = 0, count = 0;      Addr = WriteAddr / I2C_PageSize;          count = WriteAddr % I2C_PageSize;          Addr = Addr << 1;          Addr = Addr & 0x0F;            FRAM_ADDRESS = I2C1_SLAVE_ADDRESS7 | Addr;                  if (!I2C_Start()) return FALSE;      I2C_SendByte(FRAM_ADDRESS);//设置器件地址+段地址       if (!I2C_WaitAck())          {                 I2C_Stop();                  return FALSE;         }      I2C_SendByte(count);   //设置低起始地址           I2C_WaitAck();     I2C_Start();     I2C_SendByte(FRAM_ADDRESS | 0x01);     I2C_WaitAck();     while(NumByteToRead)     {       *pBuffer = I2C_ReceiveByte();       if(NumByteToRead == 1)I2C_NoAck();       else I2C_Ack();        pBuffer++;       NumByteToRead--;     }     I2C_Stop();     return TRUE; }

出0入0汤圆

发表于 2014-6-25 16:28:21 | 显示全部楼层
楼主的角度算法程序有问题,0度和360度那里会不正常

出0入0汤圆

发表于 2015-6-15 16:59:38 | 显示全部楼层
楼主好人啊,言简意赅

出0入0汤圆

发表于 2015-8-28 12:36:01 | 显示全部楼层
楼主你好,你写过罗盘校准吗?我读出来的数据在0和360度附近的+-50度变化特别大,不连续,一下能跳好几十、、、、

出0入0汤圆

发表于 2016-1-16 20:29:12 | 显示全部楼层
LZ好人,下载下来试试。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-3 22:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表