[APM32F0] 基于APM32F003的TPL0102驱动程序

[复制链接]
 楼主| Peixu 发表于 2024-10-25 17:23 | 显示全部楼层 |阅读模式
本帖最后由 Peixu 于 2024-10-25 17:26 编辑

TPL0102 是一种双通道数字电位器,常用于各种电子设备的音量控制、亮度调节等应用。它通过 I2C 总线与主控进行通信,能够实现精确的电位调节。本文将详细介绍如何使用 APM32F003 微控制器驱动 TPL0102。
TPL0102内部简化原理图如下所示:
TPL0102内有A、B两个电位器,通过IIC协议可以分别控制A、B两个电位器输出0-100K的电阻值,当然也可以将A、B两个电位器串联起来实现0-200K的电阻值输出。
bbecbf84be442c80ace492ca29cb6433
下来就是驱动代码实现:
1、首先是I2C 初始化这里使用的是模拟IIC 如下所示

  1. #include "i2c1.h"

  2. // 初始化I2C的GPIO引脚
  3. void I2C_Init(void) {
  4.        
  5.     GPIO_Config_T gpioConfig;

  6.     gpioConfig.mode = GPIO_MODE_OUT_OD;
  7.     gpioConfig.speed = GPIO_SPEED_10MHz;
  8.     gpioConfig.intEn = GPIO_EINT_DISABLE;
  9.     gpioConfig.pin = I2C_SCL_PIN | I2C_SDA_PIN;
  10.     GPIO_Config(I2C_GPIO_PORT, &gpioConfig);
  11.                 I2C_Stop();
  12. }

  13. /**
  14. * [url=home.php?mod=space&uid=247401]@brief[/url] I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号
  15. */
  16. void I2C_Start(void) {
  17.        
  18.         /*    _____
  19.          *SDA      \_____________
  20.          *    __________
  21.          *SCL           \________
  22.          */
  23.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  24.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  25.     timer_delay_ms(1);
  26.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  27.     timer_delay_ms(1);
  28.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  29.     timer_delay_ms(1);       
  30. }

  31. // 生成I2C停止条件
  32. void I2C_Stop(void) {
  33.     /*               _______
  34.      *SDA __________/
  35.      *          ____________
  36.      *SCL _____/
  37.      */       
  38.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  39.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  40.     timer_delay_ms(1);
  41.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  42.     timer_delay_ms(1);
  43. }

  44. // 发送I2C应答信号
  45. void I2C_Ack(void) {
  46.     /*           ____
  47.      *SCL ______/    \______
  48.      *    ____         _____
  49.      *SDA     \_______/
  50.      */       
  51.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  52.     timer_delay_ms(1);
  53.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  54.     timer_delay_ms(1);
  55.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  56. }

  57. // 发送I2C非应答信号
  58. void I2C_NAck(void) {
  59.     /*           ____
  60.      *SCL ______/    \______
  61.      *    __________________
  62.      *SDA
  63.      */       
  64.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  65.     timer_delay_ms(1);
  66.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  67.     timer_delay_ms(1);
  68.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  69. }

  70. // 发送一个字节
  71. void I2C_SendByte(uint8_t byte) {
  72.     for (uint8_t i = 0; i < 8; i++) {
  73.         if (byte & 0x80) {
  74.             GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  75.         } else {
  76.             GPIO_ClearBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  77.         }
  78.         byte <<= 1;
  79.         timer_delay_ms(1);
  80.         GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  81.         timer_delay_ms(1);
  82.         GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  83.     }
  84.     // 读取应答信号
  85.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  86.     timer_delay_ms(1);
  87.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  88.     timer_delay_ms(1);
  89.     GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  90. }

  91. // 读取一个字节
  92. uint8_t I2C_ReadByte(uint8_t ack) {
  93.     uint8_t byte = 0;
  94.     GPIO_SetBit(I2C_GPIO_PORT, I2C_SDA_PIN);
  95.     for (uint8_t i = 0; i < 8; i++) {
  96.         byte <<= 1;
  97.         GPIO_SetBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  98.         timer_delay_ms(1);
  99.         if (GPIO_ReadInputBit(I2C_GPIO_PORT, I2C_SDA_PIN)) {
  100.             byte |= 0x01;
  101.         }
  102.         GPIO_ClearBit(I2C_GPIO_PORT, I2C_SCL_PIN);
  103.         timer_delay_ms(1);
  104.     }
  105.     if (ack) {
  106.         I2C_Ack();
  107.     } else {
  108.         I2C_NAck();
  109.     }
  110.     return byte;
  111. }

2、TPL0102的代码读写:
  1. #include "tpl0102.h"

  2. #define TPL0102_ADDR 0x50  // TPL0102 I2C地址

  3. //TPL0102 Register Addresses
  4. #define TPL0102_REG_RA    0x00
  5. #define TPL0102_REG_RB    0x01

  6. void Test(void)
  7. {       
  8.         I2C_Init();
  9.        
  10.         // 设置电位器值
  11.         TPL0102_SetWiper(TPL0102_REG_RA, 0X66);  
  12.         TPL0102_SetWiper(TPL0102_REG_RB, 0X66);  

  13. }


  14. // 写入TPL0102寄存器
  15. void TPL0102_WriteReg(uint8_t reg, uint8_t value) {
  16.     I2C_Start();
  17.     I2C_SendByte(TPL0102_ADDR << 1);  // 发送设备地址和写命令
  18.     I2C_SendByte(reg);                // 发送寄存器地址
  19.     I2C_SendByte(value);              // 发送数据
  20.     I2C_Stop();
  21. }


  22. // 读取TPL0102寄存器
  23. uint8_t TPL0102_ReadReg(uint8_t reg) {
  24.     uint8_t value;
  25.     I2C_Start();
  26.     I2C_SendByte(TPL0102_ADDR << 1);  // 发送设备地址和写命令
  27.     I2C_SendByte(reg);                // 发送寄存器地址
  28.     I2C_Start();
  29.     I2C_SendByte((TPL0102_ADDR << 1) | 1);  // 发送设备地址和读命令
  30.     value = I2C_ReadByte(0);           // 读取数据
  31.     I2C_Stop();
  32.     return value;
  33. }

  34. // 设置TPL0102的电位器值
  35. void TPL0102_SetWiper(uint8_t wiper, uint8_t value) {
  36.     if (wiper == 0) {
  37.         TPL0102_WriteReg(TPL0102_REG_RA, value);  // 设置电位器0
  38.     } else if (wiper == 1) {
  39.         TPL0102_WriteReg(TPL0102_REG_RB, value);  // 设置电位器1
  40.     }
  41. }

  42. // 读取TPL0102的电位器值
  43. uint8_t TPL0102_GetWiper(uint8_t wiper) {
  44.     if (wiper == 0) {
  45.         return TPL0102_ReadReg(TPL0102_REG_RA);  // 读取电位器0
  46.     } else if (wiper == 1) {
  47.         return TPL0102_ReadReg(TPL0102_REG_RB);  // 读取电位器1
  48.     }
  49.     return 0;
  50. }
接下来按照TPL0102的手册就可以在main函数中进行测试了
  1. int main(void)
  2. {
  3.                 TMR4_Init();       
  4.                 I2C_Init();                       
  5.     while(1)
  6.     {                                               
  7.                         // 将目标电阻值映射到TPL0102的步进值                       
  8.                         TPL0102_SetWiper(TPL0102_REG_RA, 0Xff);  
  9.                         TPL0102_SetWiper(TPL0102_REG_RB, 0X00);  
  10.                 }
  11. }


ec2b4707d6f028738277a9a4ea1375e0
······
······
······
3b1eb3e472ba04a62854283bc1a26b10
我想看大海 发表于 2024-11-20 20:41 | 显示全部楼层
有没有用硬件IIC的案例
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

58

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

32

主题

58

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部