STM32--模拟I2C_2402--SDA_H,SDA_L

作者:breeze_life

转自:http://blog.csdn.net/breeze_life/article/details/6112057


=================================
I2C的引脚配置:

/* Configure I2C1 pins: SCL and SDA */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7; //??? QUS1:STM32内部结构
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;    //??? QUS2:种模式的区别
  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 ------------------------------------------------------- */

/*主函数的调用格式,重点。1主机存放数据的地址,2.2402写入地址,3. 写入个数

 如:#define   pr   ((u8*)0x2000f32c)  (pr,0,1) */
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  //STM32的两个很specil的寄存器,可很方便的实现GPIO的置1/置0的动作。
#define SCL_L         GPIOB->BRR  = GPIO_Pin_6  // QUS3:进一步了解这两个寄存器,区别于ODR/IDR ,初始化
   
#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) //QUS4:STM32中的bool 类型是不是和51中的sbit是一个类型
{
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;    //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);//设置器件地址+段地址  //1.第一次发送字节,被认为是器件地址(A0A1A2),以及段地址(页/片地址)
    if (!I2C_WaitAck())
{
I2C_Stop(); 
return FALSE;
}
    I2C_SendByte(count);   //设置段内地址     //2 第二次发送字节,被认为是被选中的片的内部地址
I2C_WaitAck();
  
while(NumByteToWrite--)
{
  I2C_SendByte(* pBuffer);  //3第三次发送就可以是写入/读取的内容的。
  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;
}

=================================

 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值