数字电位器mcp4017驱动调试记录---stm32f072,I2C2

电位器mcp4017要比4561驱动简单,先看手册找到设备地址:

看读写时序发现没有寄存器地址什么的,直接是设备地址+读写命令+data

写一个字节:设备地址+写命令+要写的数据

实际波形:写数据20h

附上代码:i2c2.c

#include "i2c2.h"

uint32_t I2C_Timeout;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*f042的PB10 PB11是I2C1,F072的PB10 PB11是I2C2*/
void I2C2_GPIO_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStruct; 
	
	/* Enable  GPIOA clock */
	  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);	

  /*!< GPIO configuration */  
  /*!< Configure sEE_I2C pins: SCL */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
  GPIO_Init(GPIOB , &GPIO_InitStruct);
  
  /*!< Configure sEE_I2C pins: SDA */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
  GPIO_Init(GPIOB , &GPIO_InitStruct);
	
 /* Connect PXx to I2C_SCL*/
  GPIO_PinAFConfig( GPIOB , GPIO_PinSource10, GPIO_AF_1); 
  /* Connect PXx to I2C_SDA*/
   GPIO_PinAFConfig( GPIOB ,GPIO_PinSource11, GPIO_AF_1); 
}
/**
  * @brief  I2C接口初始化
  *         初始化为I2C1主机,7位地址模式,启用模拟滤波器,停用数字滤波器,
  *         启用应答,I2C传输速度100KHz
  * @param  无
  * @retval 无
  */
void I2C2_Init_Config(void)
{
  I2C_InitTypeDef I2C_InitStructure;
  
 // RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
  
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStructure.I2C_DigitalFilter = 0x01;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_Timing = 0x30E32E44;
  I2C_Init(I2C2, &I2C_InitStructure);
  
  I2C_Cmd(I2C2, ENABLE);
}
void I2C2_init(void)
{
  I2C2_GPIO_Configuration();
	I2C2_Init_Config();
}
/**
  * @brief  从I2C1总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
  * @param  driver_Addr:I2C器件地址
  * @param  start_Addr:起始字节地址(4017没用到,调用的时候写的是0,也可以直接去掉)
  * @param  number_Bytes:要读取的字节数量(小于一页)
  * @param  read_Buffer:存放读取数据的数组指针
  * @retval 是否读取成功
  */
I2C_Status I2C2_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer)
{
  uint8_t read_Num;
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
   
  I2C_TransferHandling(I2C2, driver_Addr, number_Bytes,  I2C_AutoEnd_Mode, I2C_Generate_Start_Read);//读命令
  
  for(read_Num = 0; read_Num < number_Bytes; read_Num++)
  {
    I2C_Timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
    {
      if((I2C_Timeout--) == 0)
      {
        return I2C_FAIL;
      }
    }
    
    read_Buffer[read_Num] = I2C_ReceiveData(I2C2);
  }
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }

  return I2C_OK;
}

/**
  * @brief  从I2C1的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
  * @param  driver_Addr:I2C器件地址
  * @param  start_Addr:起始字节地址(4017没用到,调用的时候写的是0)
  * @param  number_Bytes:要读取的字节数量(小于一页)
  * @param  write_Buffer:存放读取数据的数组指针
  * @retval 是否读取成功
  */
I2C_Status I2C2_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer)
{
  uint8_t write_Num;
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_TransferHandling(I2C2, driver_Addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);//写设备地址
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }

  I2C_TransferHandling(I2C2, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_No_StartStop);//
  
  for(write_Num = 0; write_Num < number_Bytes; write_Num++)
  {
    I2C_Timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET)
    {
      if((I2C_Timeout--) == 0)
      {
        return I2C_FAIL;
      }
    }
    
    I2C_SendData(I2C2, write_Buffer[write_Num]);
  }

  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  
  return I2C_OK;
}

#define MCP4017_adr  0x5e

uint8_t BMP085_Temperature_Data_Buffer[5];
/****************************************************************************************************
函 数 名:read_mcp4561
函数说明:读寄存器值,读一个字节
输入形参:无
*****************************************************************************************************/
void read_mcp4017(void)
{
	uint8_t BMP085_TEMPERATURE_NUMBER = 1;
  if(I2C2_Read_NBytes(MCP4017_adr, 0, BMP085_TEMPERATURE_NUMBER, BMP085_Temperature_Data_Buffer) == I2C_FAIL)
  {
    
  }  
}
/****************************************************************************************************
函 数 名:write_mcp4561
函数说明:写寄存器值
输入形参:要写入的数组

*****************************************************************************************************/
void write_mcp4017(uint8_t *write_Buffer)
{

	if(I2C2_Write_NBytes(MCP4017_adr,0,1,write_Buffer)== I2C_FAIL )
	{
		if(I2C2_Write_NBytes(MCP4017_adr,0,1,write_Buffer)== I2C_FAIL )
		{}			
	}

}

i2c2.h

#ifndef __I2C1_H
#define __I2C1_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx.h"

/* Exported types ------------------------------------------------------------*/
typedef enum
{
  I2C_OK                                          = 0,
  I2C_FAIL                                        = 1
}I2C_Status;

/* Exported constants --------------------------------------------------------*/
#define I2C_TIMING                                0x00210507
#define I2C_TIMEOUT                               0x1000

/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void I2C2_init(void);
I2C_Status I2C2_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer); 
I2C_Status I2C2_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer); 
void read_mcp4017(void);
void write_mcp4017(uint8_t *write_Buffer);

#endif

应用:

BMP085_write_Data_Buffer[0] =0x20;

write_mcp4017(BMP085_write_Data_Buffer);    
Delay_ms(12);            
read_mcp4017();    

STM32 MCP41010 数字电位器是一种基于单片机接口设计的电子元件,它将传统的机械电位器的功能转换成了数字信号控制的模式,适用于需要精确、稳定且可远程调整电阻值的应用场景。MCP41010 是由 Microchip Technology Inc. 制造的一款 I2C 接口的数字电位器,能够提供 16 级可编程电阻值。 ### 技术特点: 1. **I2C 接口**:MCP41010 使用标准的 I2C 单总线通信协议,便于集成到基于 STM32 的微控制器系统中,减少了外部硬件连接的需求。 2. **可编程电阻值**:通过发送特定的数据包到设备,可以调整 MCP41010 内部的电阻值。这使得用户可以在系统运行期间动态改变电位器的位置,满足对精密控制有需求的应用场景。 3. **低功耗**:作为数字电位器MCP41010 拥有较低的静态电流消耗,适合于电源管理严格的系统应用。 4. **高精度**:相比于传统的机械电位器,数字电位器能够在更宽的温度范围内保持更高的精度和稳定性。 5. **尺寸紧凑**:由于不需要像传统电位器那样包含物理旋转部分,MCP41010 在封装上通常比同等功能的机械电位器小得多。 ### 应用示例: STM32 微控制器与 MCP41010 数字电位器的结合广泛应用于各种场合,包括但不限于音频均衡、照明控制系统、音量调节等需要精确控制电平或电压的应用。例如,在 LED 明暗控制项目中,通过调整 MCP41010 中的电阻值,可以实现 LED 光照亮度的精细控制。 ### 实现步骤: 为了在 STM32 上使用 MCP41010 数字电位器,你需要完成以下几个基本步骤: 1. **硬件连接**:将 MCP41010 的数据线(SDA)、时钟线(SCL)以及电源和接地端子连接至 STM32 的相应引脚。 2. **软件初始化**:配置 STM32I2C 接口模块,包括设置工作频率、中断处理等功能。 3. **发送命令**:编写程序向 MCP41010 发送命令以读取当前的电阻值,或者更新电阻值。这通常涉及到构建并发送包含寄存器地址和数据的 I2C 数据包。 4. **验证与调试**:通过测试程序确认数字电位器的响应是否如预期般准确,并对可能出现的问题进行调试---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值