JL杰理蓝牙芯片交流论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 595|回复: 0

FAQ:AD16 LEDC示例

[复制链接]

13

主题

0

回帖

55

积分

普通会员

Rank: 3Rank: 3

积分
55
发表于 2023-6-28 14:54:55 | 显示全部楼层 |阅读模式

注册登录,了解更多芯片技术。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、概述
AD16支持一路硬件LEDC对灯带进行驱动和控制,LEDC通过DMA数据传输,可通过配置可以使led灯带显示不同颜色变化。在使用之前需要将JL_LEDCK->CLK寄存器的[1-0]置0,然后在进行相关配置。否则可能出现异常。
二、示例驱动代码
typedef enum {          //由48M时钟源算出的时间单位    t_21ns,    t_42ns,    t_63ns,    t_125ns,    t_250ns,    t_500ns,    t_1us,    t_2us,    t_4us,} t_unit_enum;        struct ledc_platform_data {                                                                                                                                                                      u8 port;            //输出引脚    u8 idle_level;      //当前帧的空闲电平,0:低电平, 1:高电平    u8 out_inv;         //起始电平,0:高电平开始, 1:低电平开始    u8 bit_inv;         //取数据时高低位镜像,0:不镜像,1:8位镜像,2:16位镜像,3:32位镜像    t_unit_enum t_unit; //时间单位    u8 t1h_cnt;         //1码的高电平时间 = t1h_cnt * t_unit;    u8 t1l_cnt;         //1码的低电平时间 = t1l_cnt * t_unit;    u8 t0h_cnt;         //0码的高电平时间 = t0h_cnt * t_unit;    u8 t0l_cnt;         //0码的低电平时间 = t0l_cnt * t_unit;    u32 t_rest_cnt;     //复位信号时间 = t_rest_cnt * t_unit;    void (*cbfun)(void);//中断回调函数};                   #define LEDC_PLATFORM_DATA_BEGIN(data) \    const struct ledc_platform_data data = {        #define LEDC_PLATFORM_DATA_END()  \};static void (*ledc_isr_cbfun)(void) = NULL;volatile u8 ledc_busy = 0;              ___interrupt                            void ledc_isr(void)                     {                                           if (JL_LEDC->CON & BIT(7)) {        //PND        JL_LEDC->CON |= BIT(6);         //CPND        if (ledc_isr_cbfun) {                       ledc_isr_cbfun();                   }                                   }                                       ledc_busy = 0;                      }                                                                               static u8 t_div[9] = {1, 2, 3, 6, 12, 24, 48, 96, 192};                                                                                                                                      void ledc_init(const struct ledc_platform_data *arg){                                           gpio_set_die(arg->port, 1);             gpio_set_direction(arg->port, 0);     gpio_set_pull_up(arg->port, 0);      gpio_set_pull_down(arg->port, 0);     gpio_och_sel_output_signal(arg->port, OUTPUT_CH_SIGNAL_GP_LEDC);  //OUTPUT_CHANNEL自动分配                                            //std_48M                               JL_LEDCK->CLK &= ~(0b11 << 0);       JL_LEDCK->CLK |= (0b10 << 0);           //set div                               JL_LEDCK->CLK &= ~(0xff << 8);       JL_LEDCK->CLK |= ((t_div[arg->t_unit] - 1) << 8);                                             JL_LEDC->CON = BIT(6);  //CPND                                               if (arg->cbfun) {           //异步工作方式,建议用于传输数据量较大的应用        JL_LEDC->CON |= BIT(5); //IE        request_irq(IRQ_LEDC_IDX, IRQ_LEDC_IP, ledc_isr, 0);        ledc_isr_cbfun = arg->cbfun;     }                                                                         if (arg->idle_level) {                   JL_LEDC->CON |= BIT(4);          }                                    if (arg->out_inv) {                      JL_LEDC->CON |= BIT(3);          }                                                                         JL_LEDC->CON |= (arg->bit_inv << 1);                                                                                                                                                      /**********配置信号高低电平时间*******/                                       JL_LEDC->TIX = 0;                    JL_LEDC->TIX |= ((arg->t1h_cnt - 1) << 24);    //输出1码高电平时间,单位CNT_CK,实际值减1    JL_LEDC->TIX |= ((arg->t1l_cnt - 1) << 16);    //输出1码低电平时间,单位CNT_CK,实际值减1    JL_LEDC->TIX |= ((arg->t0h_cnt - 1) << 8);     //输出0码高电平时间,单位CNT_CK,实际值减1    JL_LEDC->TIX |= ((arg->t0l_cnt - 1) << 0);     //输出0码低电平时间,单位CNT_CK,实际值减1/************************************/                                        JL_LEDC->RSTX = 0;                   JL_LEDC->RSTX |= (arg->t_rest_cnt << 8);      //每一帧开始复位有效时间长度,单位CNT_CK                                         log_info("JL_LEDCK->CLK = 0x%x\n", JL_LEDCK->CLK);    log_info("JL_LEDC->CON = 0x%x\n", JL_LEDC->CON);    log_info("JL_LEDC->TIX = 0x%x\n", JL_LEDC->TIX);    log_info("JL_LEDC->RSTX = 0x%x\n", JL_LEDC->RSTX);}void ledc_send_rgbbuf(u8 *rgbbuf, u32 buf_len, u16 again_cnt){                                      if (JL_LEDC->CON & BIT(5)) {     //用于异步工作方式,防止数据重入        while (ledc_busy);              }                                  JL_LEDC->ADR = (u32)rgbbuf;         JL_LEDC->FD = buf_len * 8;       //FD_LEN RGB灯配置为灯数量n*3*8,即为不重复n个LED数据循环    JL_LEDC->LP = again_cnt;         //FD_LEN重复次数,即将JL_LEDC->FD的数据在一次循环中重复发送,0则不重复    ledc_busy = 1;                   //防止打断上一次发送的数据,用于异步工作方式    JL_LEDC->CON |= BIT(0);          //启动       if (!(JL_LEDC->CON & BIT(5))) {  //用于同步工作方式(无中断),建议用于发送数据量较少的应用                                                                                                                                                                while (!(JL_LEDC->CON & BIT(7)));        JL_LEDC->CON |= BIT(6);         }                               }                                   #if 0                               // *INDENT-OFF*                     /*******************************    参考示例 ***********************************/#define LED_NUM  10                 static u8 ledc_test_buf[LED_NUM * 3] __attribute__((aligned(4))); //RGB灯数据BUFstatic void ledc_callback()        {                                      putchar('c');                  }LEDC_PLATFORM_DATA_BEGIN(ledc0_data)    .port = IO_PORTA_04,               .idle_level = 0,                   .out_inv = 0,     .bit_inv = 1,                      .t_unit = t_42ns,                  .t1h_cnt = 24,    .t1l_cnt = 7,                      .t0h_cnt = 7,                      .t0l_cnt = 24,                                                                                                                                                                               .t_rest_cnt = 200,                 .cbfun = ledc_callback,        LEDC_PLATFORM_DATA_END()                                              void delay_10ms(u32 tick);         void wdt_clear(void);              void ledc_test(void)               {                                      log_info("*************  ledc test  **************\n");                                       ledc_init(&ledc0_data);                                               /* ledc_test_buf[0] = 0; */        /* ledc_test_buf[1] = 85; */       /* ledc_test_buf[2] = 170; */      for (u8 i = 0; i < sizeof(ledc_test_buf); i++) {        ledc_test_buf = (u8)rand();    }                 u16 again_cnt = 0;    while (1) {           wdt_clear();        for (u8 i = 0; i < sizeof(ledc_test_buf); i++) {            ledc_test_buf = (u8)rand();        }        ledc_send_rgbbuf(ledc_test_buf, sizeof(ledc_test_buf), again_cnt);        delay_10ms(10);                  }                                }#endif

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|JL杰理蓝牙芯片交流论坛 ( 粤ICP备18068352号 )

GMT+8, 2024-10-25 03:28 , Processed in 0.076101 second(s), 22 queries .

Powered by yunthinker云信

© 2001-2023 yunthinker Team.

快速回复 返回顶部 返回列表