瑞昱rtl8762芯片通过I2C操作AW20108,从而实现多个LED的控制

瑞昱rtl8762芯片通过I2C操作AW20108,从而实现多个LED的控制

  • 1、引脚分布
  • 2、了解AW20108
    • 1)了解IC引脚
    • 2)如何控制
      • a、通信方式
      • b、如何点亮LED
  • 3、代码添加
    • 1)引脚宏定义
    • 2)初始化GPIO
    • 3)配置I2C结构体
    • 4)初始化及控制
  • 4、总结

本人还在学习、摸索rtl8762,如有错误之处,欢迎指出。

1、引脚分布

引脚名称引脚编号
SCKP3_2
DATAP3_3
INTNP2_2
ENP0_2

2、了解AW20108

资料来源:艾为官方,有需要的同学可以自取。

1)了解IC引脚

从下图可以看到,需要通过软件控制的IO口有4根,分别是:SDA、SCL、INTN、EN。硬件上目前是将EN直接拉高,所以EN不需要操作。
来自aw20108数据手册

2)如何控制

a、通信方式

aw20108是通过I2C控制,最大速率为400khz。器件地址通过由第25pin AD选择,硬件上与GND连接,所以器件地址为0x3A(如下图所示),大家根据自身硬件连接修改器件地址。
来自aw20108数据手册

b、如何点亮LED

aw20108可以同时控制108颗LED,而它是通过扫描控制。那么作为程序员,应该如何点亮LED呢?其实很简单,数据手册给出了两种方案:
 1、将ALLON位置1,通过改变某个LED的电流来点亮LED;
 2、将所有LED电流设为非0值(即有电流),再通过控制寄存器LEDONx来点亮LED;

两种方式各有优点:
 第一种:代码量略多,可以单独控制某个LED,从而不影响别的LED状态;
 第二种:代码量少,编写方便。由于一个寄存器LEDONx中,包含6个LED的状态,同时LEDONx是只写的,如果想做到点亮LED0的同时,不影响LED1的话,只能代码上使用变量保存寄存器的值。

所以,目前代码实现上使用的是第一种操作方式,以下代码也会以第一种方式展现。

3、代码添加

1)引脚宏定义

/***************************** IIC *****************************/
#define I2C_CLK_PIN             P3_2                                //< I2C 时钟线
#define I2C_DATA_PIN            P3_3                                //< I2C 数据线/************************** LED DRIVER **************************/
#define LED_DRIVER_I2C          I2C0
#define LED_INTN_PIN            P2_2
#define LED_EN_PIN              P0_2                                //< led驱动使能
#define LED_INTN_PIN_NUM        GPIO_GetPin(LED_INTN_PIN)
#define LED_EN_PIN_NUM          GPIO_GetPin(LED_EN_PIN)

2)初始化GPIO

初始化GPIO分为两组,1组为spi的引脚初始化,1组为普通IO的引脚初始化。

/*** @brief  :引脚初始化* @param  :NULL* @retval :NULL*/
static void gpio_init(void)
{RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);Pad_Config(I2C_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,PAD_OUT_ENABLE, PAD_OUT_HIGH);Pad_Config(I2C_DATA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,PAD_OUT_ENABLE, PAD_OUT_HIGH);Pinmux_Config(I2C_CLK_PIN, I2C0_CLK);Pinmux_Config(I2C_DATA_PIN, I2C0_DAT);//    GPIO_WRITE_BIT(LED_EN_PIN,   PAD_OUT_HIGH);GPIO_WRITE_BIT(LED_INTN_PIN, PAD_OUT_LOW);
}

3)配置I2C结构体

/*** @brief  :配置初始化* @param  :NULL* @retval :NULL*/
static void driver_init(void)
{RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);I2C_InitTypeDef  I2C_InitStruct;I2C_StructInit(&I2C_InitStruct);I2C_InitStruct.I2C_ClockSpeed           = 200000;                       //< aw20108最大支持400k速率I2C_InitStruct.I2C_DeviveMode           = I2C_DeviveMode_Master;I2C_InitStruct.I2C_AddressMode          = I2C_AddressMode_7BIT;I2C_InitStruct.I2C_SlaveAddress         = LED_DRIVER_I2C_ADDR;I2C_InitStruct.I2C_Ack                  = I2C_Ack_Enable;
//    I2C_InitStruct.I2C_RxThresholdLevel     = 12;I2C_Init(I2C0, &I2C_InitStruct);I2C_Cmd(I2C0, ENABLE);
}

4)初始化及控制

driver_led.c

#include "driver_led_driver.h"static void    aw20108_soft_reset(void);                            //< 驱动配置初始化
static void    aw20108_write_data(uint8_t reg, uint8_t data);       //< 写数据
static uint8_t aw20108_read_data (uint8_t reg);                     //< 读数据
static void    set_page(page_number_t page);                        //< 设置页
static void    all_led_light(uint8_t level);                        //< 设置电流/*** @brief    led驱动初始化* @param    NULL* @return   void*/
void aw20108_init(void)
{GPIO_WRITE_BIT(LED_EN_PIN, PAD_OUT_HIGH);DELAY_US(400);aw20108_soft_reset();
//    aw20108_read_id();
}/*** @brief    led驱动软件复位* @param    NULL* @return   void*/
static void aw20108_soft_reset(void)
{set_page(PAGE_0);aw20108_write_data(REG_SIZE,  0x08);        //< 选择9x12 LEDsaw20108_write_data(REG_SLPCR, 0x00);        //< 选择active modeaw20108_write_data(REG_FCD,   0x01);        //< 快速清屏aw20108_write_data(REG_GCCR,  0x18);        //< 最大电流20mA、强制LED为ONall_led_light(0);
}/*** @brief    读设备ID* @param    NULL* @return   设备ID*/
uint8_t aw20108_read_id(void)
{uint8_t device_id = 0;set_page(PAGE_0);device_id = aw20108_read_data(REG_IDR);DBG_DIRECT("[driver_led_driver] device id: 0x%x", device_id);return device_id;
}/*** @brief    设置LED电流* @param    level:led电流(亮度)* @return   void*/
static void all_led_light(uint8_t level)
{uint8_t i = 0;if (level > MAX_CURR_LEVEL){level = MAX_CURR_LEVEL;}set_page(PAGE_1);for(i = 0; i <= 0x6b; i++)          //< 所有灯对应的寄存器范围:0x00 ~ 0x6b{aw20108_write_data(i, 0x3f);}set_page(PAGE_2);for(i = 0; i <= 0x6b; i++)          //< 所有灯对应的寄存器范围:0x00 ~ 0x6b{aw20108_write_data(i, level);}
}/*** @brief    换页* @param    page:页码* @return   void*/
static void set_page(page_number_t page)
{tx_data[0] = REG_PAGE;tx_data[1] = page;i2c_write(LED_DRIVER_I2C, tx_data, 2);
}/*** @brief    写数据* @param    reg:寄存器、data:写入的数据* @return   void*/
static void aw20108_write_data(uint8_t reg, uint8_t data)
{tx_data[0] = reg;tx_data[1] = data;i2c_write(LED_DRIVER_I2C, tx_data, 2);
}/*** @brief    读数据* @param    reg:需读取的寄存器* @return   寄存器值*/
static uint8_t aw20108_read_data(uint8_t reg)
{uint8_t read_data = 0;tx_data[0] = reg;i2c_read(LED_DRIVER_I2C, tx_data, 1, &read_data, 1);return read_data;
}

driver_lcd.h

#ifndef __DRIVER_LED_DRIVER_H_
#define __DRIVER_LED_DRIVER_H_#include "hw_config.h"
#include "hw_led_aw20108.h"
#include "hw_i2c.h"#define LED_DRIVER_I2C_ADDR             0x3A
#define WRITE_BIT                       0
#define READ_BIT                        1#define LED_CURR_LEVEL                  0x04
#define MAX_CURR_LEVEL                  0x3F
#define MAX_LED_NUM                     99typedef enum{PAGE_0              = 0xC0,         //< 页0PAGE_1,PAGE_2,PAGE_3,PAGE_4,
}page_number_t;                         //< 页typedef enum{REG_IDR             = 0x00,REG_SLPCR           = 0x01,REG_GCCR            = 0x03,REG_FCD             = 0x04,REG_LEDON0          = 0x31,REG_SIZE            = 0x80,REG_PAGE            = 0xF0,
}reg_addr_t;                            //< 寄存器地址void    aw20108_init(void);
uint8_t aw20108_read_id(void);#endif

4、总结

    1)EN需要拉高,INTN需要拉低。
    2)根据自身硬件选择不同的控制方式。
    3)使用示波器或者逻辑分析仪抓波形,分析波形。


小白学习rtl8762过程中,如有不对之处,欢迎讨论,共同学习。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部