zoukankan      html  css  js  c++  java
  • STM32硬件IIC操作

    Stm32具有IIC接口,接口有以下主要特性

    多主机功能:该模块既可做主设备也可做从设备

    主设备功能

    C地址检测

    产生和检测7/10位地址和广播呼叫

    支持不同的通讯速度

    状态标志:

    发送器/接收器模式标志

    字节发送结束标志

    总线忙标志

    错误标志

    2个中断向量

    可选的拉长时钟功能

    具单字节缓冲器的DMA

    虽然很多人说STM的硬件IIC不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢,

    IIC借口一共有九个寄存器,比较重要的几个寄存器分别如下

    1.       CR1


    由这几个位我们可以正常产生标准IICSTART条件STOP条件,ACKNOACK

    CR2


    控制IIC的通行频率

    这两位检测IIC总线是否收到数据


     

    1.       对于硬件IIC的初始化流程包括

    1.       配置IO,配置为GPIO_Mode_AF_OD模式

    2.       选择IIC模式

    3.       选择是否使能自动应答以及设备地址长度

    4.       设置IIC总线的传输速率

    2.       硬件IIC的读写操作其实逻辑上和标准总线类似,也是发送地址等待ack发送数据等待ACK,但是因为有硬件的自动参与,所以我们不需要延时了

     

    具体代码如下

     

    void HmcIICInit(void)
    {
    	/*GPIO初始化*/
    	GPIO_InitTypeDef GPIO_InitStructure;
    	/* 配置硬件IIC需要的变量 */ 
    	I2C_InitTypeDef I2C_InitStructure; 
    
    	/* 使能与 I2C1 有关的时钟 */
    	RCC_APB2PeriphClockCmd  (RCC_APB2Periph_GPIOB,ENABLE ); 
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);  
    
    	/* PB6-I2C1_SCL、PB7-I2C1_SDA*/
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; 
    	GPIO_Init(GPIOB, &GPIO_InitStructure); 
    
    	/*IIC外设初始化*/
    
    	/* I2C 配置 */
    	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;     //配置为普通IIC模式
    	//I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; 
    	//I2C_InitStructure.I2C_OwnAddress1 = SlaveAddress; 
    	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  //使能自动应答   
    	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
    	I2C_InitStructure.I2C_ClockSpeed = 50000;   //5K的速度?
    
    
    	/* I2C1 初始化 */
    	I2C_Init(I2C1, &I2C_InitStructure);	   
    
    	/* 使能 I2C1 */
    	I2C_Cmd  (I2C1,ENABLE); 
    	/*允许应答模式*/
    	I2C_AcknowledgeConfig(I2C1, ENABLE);   
    }
    
    void HmcByteWrite(u8 addr,u8 dataValue)
    {
    	I2C_GenerateSTART(I2C1,ENABLE);
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
    	I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    
    	I2C_SendData(I2C1,addr);
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    	I2C_SendData(I2C1,dataValue);
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    	I2C_GenerateSTOP(I2C1,ENABLE);
    
    }
    
    u8 HmcByteRead(u8 addr)
    {
    	u8 dataValue;
    
    	while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
    
    	I2C_GenerateSTART(I2C1,ENABLE);//起始信号
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
    	I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);//发送设备地址+写信号
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
    
    	I2C_Cmd(I2C1,ENABLE);
    
    	I2C_SendData(I2C1,addr);//发送存储单元地址,从0开始
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    	I2C_GenerateSTART(I2C1,ENABLE);//起始信号
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
    	I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Receiver);//发送设备地址+读信号
    
    	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    
    	I2C_AcknowledgeConfig(I2C1,DISABLE);
    
    	I2C_GenerateSTOP(I2C1,ENABLE);
    
    	while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));
    
    	dataValue=I2C_ReceiveData(I2C1);//读出寄存器数据
    
    	return dataValue;
    }

  • 相关阅读:
    Android(java)学习笔记68:使用proguard混淆android代码
    SGU 194 Reactor Cooling
    关于流量有上下界的网络流问题的求解
    关于最小割的求解方法
    HDU 5311 Hidden String
    POJ 3548 Restoring the digits
    POJ 2062 HDU 1528 ZOJ 2223 Card Game Cheater
    ZOJ 1967 POJ 2570 Fiber Network
    HDU 1969 Pie
    HDU 1956 POJ 1637 Sightseeing tour
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4279440.html
Copyright © 2011-2022 走看看