KDocs 研发资料库
  • 音频技术应用文档入口汇总
  • 杰理WINDOWS环境安装及其他事项
  • LINUX安装和编译
  • Linux环境编译SDK教程(ubuntu18.04)
  • 音频类补丁汇总表
  • 认证资料获取汇总(最新资料后台会更新)
  • 《Hi-Res申请指南v1.0》
  • FreeRTOS 开源协议版本
  • uCOS 开源协议版本信息
  • 各个模块关键资料汇总
  • 软件调试方法
  • Makefile编译
  • 提bug的规范
  • 常规设备使用指导
  • 对外特别发布开发注意点信息汇总
  • AD697X软件问题整理
  • AC700N软件问题整理
  • AC701X耳机软件问题整理
  • 951&961软件问题整理
  • AC104X软件问题整理
  • AC128N问题整理文档
  • 可视化工具调试问题整理
  • 耳机资料汇总
  • AC704N、 AC705N相关应用
  • AC695N&AC696N&AC608N音箱问题整理
  • JL701N音箱问题整理
  • AC692X软件问题整理
  • AC706N音箱问题整理
  • JL701N音箱问题整理(可视化工具SDK)
  • JL703N音箱问题整理
  • JL709N(JL689N)音箱问题整理
  • JL7094系列-入门到进阶开发指导
  • AC210N音箱问题整理
  • 无线麦系列版本支持指南
  • AW32N无线麦问题整理
  • lAD697X&JL701X 无线麦软件共性问题整理
  • AC706N无线麦问题整理
  • AW36N无线麦问题整理
  • AC710X无线麦问题整理
  • 唤醒源获取及唤醒IO设置
  • 电源
  • LVD
  • 长按复位配置方法
  • 低功耗应用
  • TIMER
  • UART
  • SPI
  • 内部FLASH空间添加用户自定义区域
  • IIC
  • GPIO
  • MCPWM
  • SD&U盘
  • 时钟&晶振
  • GPCNT
  • IO口crossbar映射功能
  • 文件系统使用总结
  • 复用应用
  • LINEIN_AUX相关应用
  • IIS音频接口应用
  • SPDIF模式相关(HDMI_ARC、光纤、同轴)
  • PDM LINK
  • 外设相关应用
  • 蓝牙相关
  • 杰理蓝牙距离调试文档
  • TWS耳机配对方式使用及生产把控指南
  • GFP谷歌快连及其认证流程指引
  • 蓝牙发射器(bt_emitter)相关
  • BLE应用
  • 关于提升BLE传输速率说明
  • BLE测试数据
  • MUSIC 模式相关应用
  • MIDI音乐实现
  • PC相关应用
  • FM相关应用
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20250107
  • fm应用详细设计说明书
  • 杰理FM硬件指南-20230315
  • ADC模块
  • AUDIO相关应用
  • 新Tools的音效调试使用
  • 混响应用使用说明
  • 音效调式
  • 音箱耳机低音小音量增强实现方法
  • DAC输出功率调试
  • DAC性能测试指南
  • 针对各类底噪、电流声分析流程
  • 录音相关应用
  • OPUS编解码相关
  • RTC相关应用
  • 升级相关
  • UI相关应用
  • 通话调试流程指南
  • 通话相关应用
  • 省电容mic使用手册
  • 如何测试验证手表通话系统的语音失真 V1.0
  • AC695X_AC696X_AD697X 常见通话问题处理参考资料
  • 通话调试问题确定步骤
  • 内置触摸调试指南
  • 低功耗内置触摸介绍V2.2
  • 触摸相关文档
  • AC697X、AC698X内置触摸调试及整改方法V1.0
  • 产测相关应用
  • AC63X BLE DUT测试介绍
  • 兆华序列使用简易说明
  • JL_1T2蓝牙测试盒音频文件更换说明
  • ENC相关应用入口汇总
  • ANC相关应用入口汇总
  • JL DMS通话调试手册-V3.9.4
  • ANC-ENC结构设计要点-20240407
  • 半入耳式ANC耳机器件选型与结构设计指南V1.0
  • JL 耳道自适应调试指南
  • ANC相关问题处理
  • ANC调试文档
  • 评估蓝牙耳机通话上行降噪性能的方法 V1.0 (2)
  • FCC 或者 BQB 认证相关应用
  • BQB profile 测试中常遇到的问题点汇总
  • 蓝牙参数整理20210811
  • 杰理科技认证问题参考
  • 无线音频产品开发指南
  • 无线麦系列从入门到进阶开发指导
  • 量产烧录相关说明
  • 一拖八烧录器远程过程调用说明
  • 量产相关建议
  • EffectTool(eq)调试工具说明文档
  • AC897AD697系列的EQ调试方法-V3
  • 杰理调音指南-20220622
  • 音效模块总结
  • 简要调音步骤指引(可视化)
  • 耳机充电与通信调试指南
  • 充电仓硬件调试指南
  • 充电仓软件问题整理
  • AC951常用说明
  • AC951_AC961_开发板使用说明V1.0
  • 彩屏仓AC982 入门指导及FAQ
  • 蓝牙音频APP相关应用
  • 手机APP的简介和开发流程
  • 蓝牙音频系列-硬件设计指南
  • 静电测试及整改方法-20220706
  • TWS耳机底噪整改指南V1.2
  • 杰理蓝牙距离调试文档
  • 蓝牙RF硬件设计与调试V1.1-20250219
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20241228
  • 音效调试指南
  • 无线话筒K歌音箱标准开发流程
  • 杰理科技 700N TWS耳机产品标准-202303
  • 杰理科技 701N 广播产品标准-202303
  • JL-HAT ANC高效产测自适应
  • 无线话筒测试板使用介绍
  • 一拖八频偏校准使用说明
  • 领夹麦产测工具使用介绍
  • Dongle量产测试说明
  • Dongle+Tws或头戴式 SDK通过工具绑定配对功能说明文档
  • 双麦ENC产测宏配置验证方法 V1.0
  • JL耳机方案麦克风声学测试指令_V1.0
  • JL耳机方案麦克风声学测试指令_V2.0
  • JL_ENC自动测试命令_V0.0.1
  • JL蓝牙测试盒用例说明
  • LDAC自测环境搭建_ubuntu
  • 延迟小板使用手册
  • 杰理库文件的制作及添加实现过程
  • 关于 AC635N&AC636N系列免晶振兼容性补丁 说明
  • 关于 AC63系列VM兼容性修复补丁_20250224 说明
  • 关于 AC632N &AE632N_ 蓝牙& 低功耗兼容性修复补丁 说明
  • AD698N和AC638N电压优化补丁V3说明
  • 关于 AC635N&AC636N漏电和E&G版兼容联合补丁 说明
  • AD698N和AC638N电压优化补丁V2说明
  • 702相关应用
  • 2024-4-30 发布歌词显示SDK开发注意事项
  • BQB RF & FCC 认证测试固件问题汇总及源码
  • BQB profile 测试中常遇到的问题点汇总
  • 进dut测试模式方法及固件
  • 704-频偏修改bin文件合集
  • 701手表BQB PROFILE认证注意事项
  • 认证的干扰规避整改
  • 海外CRA认证报告生成说明
  • JL700N可视化工具问题处理文档
  • JL701X可视化工具问题处理文档
  • JL701N_earphone_release_v1.6.0_ANC 低功耗问题补丁
  • JL708X可视化工具问题处理文档
  • JL709N可视化工具问题处理文档
  • JLstudio可视化工具使用说明
  • 一拖二-串口_蓝牙_app在线EQ、通话参数及调试方式和内置触摸调试
  • 可视化JL701M_DONGLE_SDK添加MIC为发射源
  • 可视化JL701M_DONGLE_SDK添加按键切换usb audio与MIC发射源
  • JL701M_DONGLE_SDK_1.0.0_dongle输入linein输出dac
  • 701可视化_a2dp_to_le_demo说明
  • 耳机系列demo汇总
  • JL7018F&JL7006F_7003F AUX IIS
  • 一键连接应用
  • 普通SDK动态开关一拖二功能
  • 蓝牙分析仪(EllisysBluetoothAnalyzer)抓包例程
  • TWS配对常见应用
  • APP自定义按键的demo
  • AC700N 播歌双EQ DEMO示例及说明
  • AC698V164 MIC与蓝牙音乐共同输出DAC demo
  • 添加第三方算法以及多算法授权流程
  • 空间音频配置方法
  • 普通高低电平TWS耳机控制通讯
  • 入耳检测状态更新demo解析
  • 资源优化(非可视化的SDK)
  • 资源优化(可视化SDK)
  • 翻译耳机、语音识别应用demo
  • 耳机抗干扰问题排查和优化
  • AC698D2 抗干扰优化
  • AC696X软件问题整理
  • AC695X软件问题整理
  • AC695X软件问题整理_1722249702
  • AC608X软件问题整理
  • JL701N_2T1_DUPLEX 应用软件问题汇总
  • le_audio_1.0.0_patch05 以及之前的版本IRkey 功能异常修改
  • AC706N-le_audio-200SDK有线_无线麦录音demo
  • jl701n_le_audio_v200patch02 IO串口升级修改串口单次发送字节长度的修改办法
  • 703创建IIS 输入dac输出音频流demo
  • 703将媒体流音频同时上传PC_mic录音demo实现
  • 703四路IIS输入输出demo
  • 底噪调试
  • AW328A烧录说明
  • 文档合集
  • AC706N_wireless_mic_release_PATCH_20240712 补丁 说明
  • AC706N_wireless_mic_release_PATCH_20240726 补丁 说明
  • AC706N_wireless_mic_release_V1.0.0、1.0.1、1.0.2 补丁 说明
  • AC706N_wireless_mic_release_V1.1.2 中的2T1应用 RX端不绑定配对,TX端实现绑定配对的修改方法
  • 各系列省晶振实现方法
  • iis tx rx说明文档
  • spdif信号
  • 蓝牙电话本
  • 安卓手机同步时间补丁
  • CDC配置
  • PC模式下增加Teams唤起功能
  • 杰理HDMIARC开发实现过程
  • AC701N patch06之前的版本用第三方算法节点实现新版本的pcm delay节点功能
  • (K歌音箱)各SDK音效配置相关说明
  • 长文件录音
  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
  • 使用硬件数字增益控制通话下行音量(可视化)
  • 杰理小牛产测资料
  • ENC配置说明
  • 通话调试流程指引
  • ANC相关功能demo
  • 无线麦硬件资料汇总
  • 无线麦相关应用
  • 无线麦复杂功能补丁包汇总
  • 无线话筒形态SDK程序&开发经验&问题点分享
  • 双模式结合应用问题汇总
  • 无线麦距离优化案例
  • 无线麦系列中的双工形态(duplex)演变开发对讲机方案开发资料
  • 音箱入门到进阶指导文档(编写中)
  • 蓝牙耳机品控和生产技巧
  • 982过_欠压标志获取异常
  • 如何获取最新涂鸦SDK及库文件
  • 无线话筒K歌音响-调音标准流程
  • 无线话筒产测流程

UI相关应用

📎 原始文档:https://www.kdocs.cn/l/ckhf4dZtUTjJ UI相关应用

  1. 128*64点阵液晶模块 (黑白屏) image

程序配置

  • 配置UI相关配置 宏配置
//*********************************************************************************//
//                                  UI 配置                                        //
//*********************************************************************************//
#define TCFG_UI_ENABLE                         ENABLE_THIS_MOUDLE     //UI总开关
#define CONFIG_UI_STYLE                     STYLE_JL_SOUNDBOX
// #define CONFIG_UI_STYLE                  STYLE_UI_SIMPLE //这是309 sdk ui 风格 需要再开启TCFG_SIMPLE_LCD_ENABLE
// #define TCFG_UI_LED7_ENABLE                  ENABLE_THIS_MOUDLE     //UI使用LED7显示
// #define TCFG_UI_LCD_SEG3X9_ENABLE         ENABLE_THIS_MOUDLE     //UI使用LCD段码屏显示
// #define TCFG_LCD_ST7735S_ENABLE            ENABLE_THIS_MOUDLE
// #define TCFG_LCD_ST7789VW_ENABLE            ENABLE_THIS_MOUDLE
#define TCFG_LRC_LYRICS_ENABLE              ENABLE_THIS_MOUDLE  //歌词显示
#define TCFG_LCD_OLED_ENABLE                ENABLE_THIS_MOUDLE
#define TCFG_SPI_LCD_ENABLE                 ENABLE_THIS_MOUDLE //spi lcd开关
#define TCFG_SIMPLE_LCD_ENABLE              DISABLE_THIS_MOUDLE//去ui 框架的驱动开关 开启请关闭了TCFG_SPI_LCD_ENABLE
#define TCFG_TFT_LCD_DEV_SPI_HW_NUM             1// 1: SPI1    2: SPI2 配置lcd选择的spi口
#define LCD_SPI_INTERRUPT_ENABLE             0//默认开启 需要主动关闭
#define ALL_KEY_EVENT_CLICK_ONLY             1     //是否全部按键只响应单击事件

IO配置

#if (TCFG_SPI_LCD_ENABLE || TCFG_SIMPLE_LCD_ENABLE)

LCD_SPI_PLATFORM_DATA_BEGIN(lcd_spi_data)

#if TCFG_LCD_OLED_ENABLE
    .pin_reset    = IO_PORTC_01,
    .pin_cs        = IO_PORTC_03,
    .pin_rs        = IO_PORTC_02,
    .pin_bl     = IO_PORTC_00,
#else
    .pin_reset    = -1,
    .pin_cs        = IO_PORTC_03,
    .pin_rs        = IO_PORTC_02,
    .pin_bl     = IO_PORTC_01,
#endif

#if (TCFG_TFT_LCD_DEV_SPI_HW_NUM == 1)
    .spi_cfg    = SPI1,
    .spi_pdata  = &spi1_p_data,
#elif (TCFG_TFT_LCD_DEV_SPI_HW_NUM == 2)
    .spi_cfg    = SPI2,
    .spi_pdata  = &spi2_p_data,
#endif
LED7_PLATFORM_DATA_END()

const struct ui_devices_cfg ui_cfg_data = {
    .type = TFT_LCD,
    .private_data = (void *)&lcd_spi_data,
};
#endif
  • 液晶屏初始化代码 根据使用的屏的驱动自行修改
//初始化SSD1306
static void SPI_OLED_Init(void)
  • 不同规格液晶屏大小修改
#define SCR_X 0        ///屏幕起始点X的偏移
#define SCR_Y 0        ///屏幕起始点Y的偏移
#define SCR_W 128       ///刷新屏幕的宽度,与LCD_W 一致
#define SCR_H 64        ///刷新屏幕的高度,与LCD_H 一致
#define LCD_W 128       
#define LCD_H 64
#define LCD_BLOCK_W 128    //显存buf的大小设定
#define LCD_BLOCK_H 64     //显存buf的大小设定
#define BUF_NUM 2           ///buf 数量

DEMO程序

硬件接口:(一组SPI口+3个普通GPIO)如下

主控接口1LCD屏接口
LCD_DATASDA
LCD_CLKSCK
LCD_A0RS
LCD_RESRST
LCD_CSCS

imageimage 程序:
AC695N_soundbox_sdk_release_3.1.0 OLEDDEMO:
https://gitlab.zh-jieli.com/soundbox/novisualization/ac695n_soundbox_sdk/-/tree/feature_310_OLED
【金山文档】 jl701n_soundbox_release_v1.3.0_OLED
【金山文档】 jl701n_soundbox_release_v1.4.1_OLED
demo_701142_OLED_lrc.zip(文本单字滚动)
demo_701_142_oled_pixscoll.zip(实现文字像素点滚动)
feature_695_310_OLED_pixscoll.zip(实现文字像素点滚动)

点阵屏歌词字库相关(蓝牙歌词,普通歌词):

点阵屏歌词字库相关(蓝牙歌词,普通歌词).otl
ac695n_soundbox_sdk_310_纯歌词文件输出.7z( 不跑内置UI系统,可以通过外发做显示,输出格式为UTF8)

UNICODE字库显示(可以同时显示中文韩文日文等):

UNICODE字库显示.otl

字模提取工具说明

字模提取工具说明.otl
2. 音箱可视化彩屏 音箱可视化彩屏-入门到进阶开发指导.otl(持续更新中)
3. HUB75/IO屏

  1. ic选型
屏幕类型io互推单色屏HUB75单色屏HUB75彩屏
ic类型AD101CAD172A8AW302B
屏像素12*12016x9616x96
资料硬件硬件硬件
仓库地址代码地址
  1. HUB75屏调试
  • 硬件资料 驱动ic:
    HUB75驱动ic资料
    单色原理图:
    16X96 LED阵列标准原理图V1.0
    12X72单色LED_V1.0.pdf
    彩色原理图:
    16X96 RGB_LED阵列标准原理图V1.0
    原理图说明:
    1. JIN1是接线座
    2. BR1电阻控制每一个输出的电流。Iout =18800/BR1 mA
    3. 原理图设计是逐行扫描,SM16208SC控制一行中的每一个灯,如需增加一行中的灯数量,增加SM16208SC,级联下去即可。
    4. SM5166PS控制行输出,如需增加行数,增加SM5166PS级联即可。
    5. U1作电平转换
    6. RGB效果相当于在单色灯的寄出上增加两个LED,行数不变,灯数增加,增加SM16208SC,增加数据SDI输入既可以。
    7. 单元亮灯的原理如下图 image 图源:https://www.sparkfun.com/news/2650
      相关资料:
      关于LED点阵屏单元板的通信接口——HUB75 - 哔哩哔哩
  • 驱动说明

背景

  1. 屏幕驱动目前做的是32扫32行128列,没有做32扫64行128列。
  2. 驱动使用4线spi三data引脚与模块的R1 G1 B1连接 image
  3. 屏幕模块R1/G1/B1 R2/G2/B2共用同一个clk所以能实现32扫显示64行的效果
    1. 也是由于这个原因导致四线spi只能同时驱动1/64行不能实现2/64,如果需要实现2/64的显示需要6线并行输出的设备

大致流程:

flowchart

编译

ac701n_soundbox_sdk-lvgl-led-20240106.7z
windows下使用Makefile编译
image

驱动代码

相关头文件:
led_drive.h、led_run.h、head.h

硬件引脚定义:
#define SPI_HW_NUM  SPI2//可选择spi1-2
#define SPI_PI_CLK          IO_PORTA_02//clk
//第一组io
#define SPI_0_PI_D0_R       IO_PORTA_03//R
#define SPI_0_PI_D1_G       IO_PORTA_04//G
#define SPI_0_PI_D1_B       IO_PORTA_05//B
#define SPI_0_PI_D3_NULL    IO_PORTG_05//无效引脚
//SM_5166
#define SM_5166_PORTA  IO_PORTB_03
#define SM_5166_PORTB  IO_PORTB_04
#define SM_5166_PORTC  IO_PORTB_05
#define SM_5166_PORTD  IO_PORTB_06
#define SM_5166_PORTE  IO_PORTB_07
//SM_1620
#define SM_1620_LE_PORT IO_PORTG_03
#define SM_1620_OE_PORT IO_PORTG_04
屏幕、颜色相关配置:
#define SINGLE_WIDTH   (128)//宽
#define SINGLE_HEIGHT  (32)//高
#define SCAN_LIN (32)//N扫行
#define  FRAME_BUFF_NUMBER  (2)//帧缓存数
#define DEPTH_LEVEL (32)//颜色梯度 R(0-N) G(0-N) B(0-N) RGB565这里就要设置为32
初始化led驱动
void led_run_init(void);
void app_task_loop()
{
    led_run_init();
    ...
}
数据更新接口
void led_display_one_frame(COLOUR_RGB rgb[SINGLE_HEIGHT][SINGLE_WIDTH]);
  • 软件配置 参考程序是基于开源LVGLUI框架,最终输出数据使用RGB灯板驱动进行对接。
输出对接函数
LV_ATTRIBUTE_FAST_MEM static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)

现在LVGL适配屏幕限制了只能RGB565输出。但是不用过于担心,程序中做了一次转换为RGB888格式。现在屏驱能适配到32个梯度即0x20=32。不会影响最终的输出精度。

修改HUB75灯板驱动大小
//修改HUB75灯板大小,以128*32灯板为例,只做初始化使用,方便在LVGL获取准确大小,不做最终输出函数。
#define SCR_X 0
#define SCR_Y 0
#define SCR_W 128
#define SCR_H 32
#define LCD_W 128
#define LCD_H 32
#define LCD_BLOCK_W 128
#if (defined(TCFG_SMART_VOICE_ENABLE) && (TCFG_SMART_VOICE_ENABLE == 1))
#define LCD_BLOCK_H 20
#else /*TCFG_SMART_VOICE_ENABLE == 0*/
#define LCD_BLOCK_H 32
#endif /*TCFG_SMART_VOICE_ENABLE*/
#define BUF_NUM 2

LVGL参考指南:

彩屏LVGL UI设计及工具使用.otl

LVGL修改控件位置以及大小:

在void setup_scr_screen(lv_ui *ui)函数中,默认只做了一个页面,如有需要可以按照指南新增页面。

    ui->screen = lv_obj_create(NULL);
    lv_obj_set_size(ui->screen, 128, 32);    //修改整个屏幕大小

    //Write style for screen, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT.
    lv_obj_set_style_bg_opa(ui->screen, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui->screen, lv_color_hex(0x000000), LV_PART_MAIN|LV_STATE_DEFAULT);

    //Write codes screen_MUSIC_SRC
    ui->screen_MUSIC_SRC = lv_label_create(ui->screen);
    lv_label_set_text(ui->screen_MUSIC_SRC, "深圳市杰理微电子科技有限公司");
    lv_label_set_long_mode(ui->screen_MUSIC_SRC, LV_LABEL_LONG_SCROLL_CIRCULAR);
    lv_obj_set_pos(ui->screen_MUSIC_SRC, 0, 0);        //修改控件起始位置
    lv_obj_set_size(ui->screen_MUSIC_SRC, 128, 16);    //修改控件大小

支持功能:LED灯板只是一个显示器件,和程序对接好了之后,只用当作屏幕一样使用,所以LVGL能够使用的内容,如图片显示等都可以在这个程序中实现并显示。

LVGL修改文本控件内容:

注意:UI控件的操作要求只在UI线程中进行调用,在其他线程中直接调用有概率出现死机复位。

//按照程序示例在其他线程调用,并post出来消息事件,集中在UI线程中处理
void show_music_src(u8 *info)
{
  strcpy(user_msg[MUSIC_SRC].info,info);    //参数输入格式为UTF8格式。
  lvgl_user_send_msg(MUSIC_SRC);
}
void show_music_now_time(u8 min,u8 sec)
{
  u8 info[10];
  sprintf(info,"%02d:%02d",min,sec);
  g_printf(">>>nowtime:%s",info);

  strcpy(user_msg[MUSIC_NOW_TIME].info,info);
  lvgl_user_send_msg(MUSIC_NOW_TIME);
}
void show_music_music_time(u8 min ,u8 sec)
{
  u8 info[10];
  sprintf(info,"%02d:%02d",min,sec);
  g_printf(">>>musictime:%s",info);
  strcpy(user_msg[MUSIC_TIME].info,info);
  lvgl_user_send_msg(MUSIC_TIME);
}

void lvgl_user_send_msg(u8 msg_event){
    int msg[8];
    msg[0] = UI_MSG_USER_MSG;
    msg[1] = msg_event;
    post_ui_msg(msg, 2);    
}
void ui_user_msg_dispose(u8 id)
{
    switch (id)
    {
    case MUSIC_SRC:
      y_printf(">>%s,[%d]0x%x",__func__,id, user_msg[MUSIC_SRC].info);
        lv_label_set_text(guider_ui.screen_MUSIC_SRC, user_msg[MUSIC_SRC].info);
      break;
    case MUSIC_TIME:
        lv_label_set_text(guider_ui.screen_MUSIC_TIME, user_msg[MUSIC_TIME].info);
    break;
    case MUSIC_NOW_TIME:
        lv_label_set_text(guider_ui.screen_NOW_TIME, user_msg[MUSIC_NOW_TIME].info);
    break; 
    
    default:
      break;
    }
}

如果跨线程调用的情况会出现以下打印:
image

LVGL修改文本控件颜色:

参照杰理LVGL指南和LVGL官方手册配置就可以,其中lv_example_label_4()是有幻彩色字体输出,但是使用的是画布储存,占用了(长宽颜色数据量)RAM和CPU,非常占用资源,推荐使用以下函数在驱动层面上换颜色输出渐变数据,修改宏定义即可实现原色彩和渐变设输出。

void led_display_one_frame(COLOUR_RGB rgb[SINGLE_HEIGHT][SINGLE_WIDTH]){
    if(!drive_info.drive || !rgb || drive_info.drive->to_flag ||drive_info.drive->frame_next!=drive_info.drive->frame)return;
    
    #if 1//变色
    for(int i=0;i<SINGLE_WIDTH;i++){
        hsv_tale[i].h= (hsv_tale[i].h+10)%MAX_H;
        hsv2rgb(hsv_tale+i,rgb_tale+i);
    }

    for(int h=0;h<SINGLE_HEIGHT;h++){
        for(int w=0;w<SINGLE_WIDTH;w++){
            if(rgb[h][w].r ||rgb[h][w].g||rgb[h][w].b){
                rgb[h][w]=rgb_tale[w];
            }
        }
    }
    #endif
    // r_printf("A");
    memcpy(drive_info.drive->rgb,rgb,sizeof(drive_info.drive->rgb));

    #if 0//直接转换数据
    u8 frame_next;
    frame_next=(drive_info.drive->frame_next+1)%FRAME_BUFF_NUMBER;
    for (int i = 0; i < DEPTH_LEVEL; i++){
        led_rgb2spi_data(drive_info.drive->rgb,SINGLE_WIDTH*SINGLE_HEIGHT,drive_info.drive->send_buff[frame_next][i],i);
    }
    drive_info.drive->frame_next=frame_next;
    #else
    os_sem_post(&drive_info.sem);
    #endif
}

LVGL修改字库字模大小:

生成字库工具:lv_charging_case\res-pack-tools\字库工具\LvglFontTool_V0.4\LvglFontTool\LvglFontTool.exe
以修改为12*12规格字库并显示为例:

  • 修改字库:生成之后,替换myFont.c和myFont.bin(),注意__user_font_getdata函数中的内容不要改变 image
  • 修改LVGL相关大小初始化

LVGL DEMO

备注:如果有更新程序,我们会后台更新,请保持关注,谢谢!
代码仓库:
module / 拼接屏 / demo · GitLab

701

lvgl:ac701n_soundbox_sdk-lvgl-led-20240106.7z
内部UI框架:jl701n_soundbox_release_v1.4.2_内部UI框架_io拓展屏驱动歌词滚动显示demo.rar

695

内部UI框架:ac695_310SDK_LEDBOARD_demo.7z
字库工具:unicode字库工具.7z

显示效果

歌词显示视频效果.zip

使用内部UI框架进行UI调试的系列步骤

使用内部UI框架进行UI调试的系列步骤.otl
3. 单MCU IO互推LED点阵屏

  • AD101C硬件资料 ( 主推) 【金山文档 | WPS云文档】 AD101C 原理图及真值表
    AD101C 原理图及真值表.zip
  • AD101C程序编译加key说明 AD101C程序编译加key说明.otl
  • AD101C强制升级工具烧录下载 image
  • 串口升级工具 ad100_uart_update_tools.zip
    规范串口升级使用办法:
  1. 所有的空片都要先用烧写器烧录一遍程序,然后再使用串口升级,尽可能不使用spi升级,详情请参考下面文档中的第二大点。 AD101C强制升级工具烧录下载(ad100_uart_update_tools)使用说明补充.otl
    spi烧录报错问题尝试修改办法(目前测试版本,后续会更新):
    AD101C使用强制升级工具spi 烧录不了问题处理(测试版本).otl

  2. LCD断码屏

寄存器使用说明

在“AC695N用户手册V1.2.pdf”中第13章:
image 注意点:LCD断码屏的COM 口只能顺序使用,不能打乱顺序使用。

DEMO程序:

链接:https://pan.baidu.com/s/19OQKNMsSTVAr76FPqfXXAw
提取码:8888

AC460X\AC690X\AC692X LCD屏调式参考资料资料

备注:AC460X、AC690X、AC692X LCD点阵屏这块用的UI工具和程序流程都是一样的。
【金山文档】 17-UI工具
https://kdocs.cn/l/ctouHDb9uOA5

【金山文档】 AC46 UI使用说明
https://kdocs.cn/l/cdJ5QFhxwuPf

【金山文档】 AC692X_lcd点阵屏只显示英文字符说明文档
https://kdocs.cn/l/cbPjE1M70nyo

【金山文档】 12864点阵屏菜单_2018年11月7日170226
https://kdocs.cn/l/cnMCUamOrI2R

【金山文档】 692x频谱-20181220-V1
https://kdocs.cn/l/cgR0UOBhIOQo

DEMO:

【金山文档】 AC692x_SDK_release_V2.6.3(带LCD屏和频谱显示)
https://kdocs.cn/l/chHrN0XdpqCa

  1. 单线串行控制幻彩灯珠

思路

  • 颜色数据(R G B)->SPI数据->do(数据)引脚模拟灯珠通信协议

要点

  • 确保spi的数据发送的精确度,系统时钟跑最高、spi时钟跑最高
    • 系统时钟:AC695N最高240MHz、AC696N最高192MHz
    • spi时钟:如果库里面没有做限制可以设置为 80MHz
  • 发送数据时,用最后一个字节的第7位来控制发送完数据之后do引脚的高低电平
    • 最后一个字节的bit7为1,发送完数据之后do引脚为高电平,反之亦然。

灯珠资料

  1. 芯片级联方法 image
  2. 数据传输 image 注:其中 D1 为 MCU 端发送的数据,D2、D3、D4 为级联电路自动整形转发的数据
  3. 24bit 数据结构 image 注:高位先发,按照 GRB 的顺序发送数据
  4. 时序波形 image
  5. 通信信号传输定义
参数名称参数符号最小值典型值最大值单位
输入 0 码高电平时间Tin0h0.200.280.35us
输入 1 码高电平时间Tin1h0.650.91.0us
输入 0 码低电平时间T0L1.551.7230us
输入 1 码低电平时间T1L1.101.1030us
0 码/1 码周期T0/T11.75-35us
RESET 码低电平时间reset100150-us

注: a:5050RGB 主要根据高电平时间判断“0”码和“1”码。高电平时间介于 200ns~410ns,IC 判断为“0”码,高电平时间介于 640ns~1000ns,判断为“1”码。 “0”码和“1”码的低电平代表此码结束,准备接收下一数据码。
b:低电平复位时间最小为 100us,为了留有裕度,一帧数据传输过程中(包括 24bit 和 24bit 之间、bit 和 bit 之间)不要中断超过 35us,否则可能会被 IC 认为是 RESET。中断时间在 35us 之内, 控制器可以进行正常数据传输等其他操作。

步骤

  • spi波特率
    • spi数据发送0x55使用逻辑分析仪看数据高低电平翻转时间T
    • 需要同时满足
      • 码元周期(T0H+T0L或者T1H+T1L)=T*8
      • spi发送数据时高低电平翻转的时间T,必须满足:T0H=Tn1,T0L=T(8-n1);T1H=Tn2,T1L=T(8-n2)
        • n1、n2取值1-7
  • 转换码
    • 使用一个字符spi的发送时间来模拟0码/1码的时序波形
    • 字符bit中1/0控制0码/1码时序波形的高和低
    • 字符bit中连续的1/0控制0码/1码时序波形的高和低持续时间

eg:
- 如5. 通信信号传输定义T0H 取值范围是0.20us-0.35us T0L 取值范围是1.55us-30us 满足以上两点 - T=0.3us - n1=7 T0H:T0L=1:7 - n2=5 T1H:T1L=5:3 image 0码:0X80
1码:0XF8
也就是说spi发送0X80就是发送了0码,发送0XF8就是发送1码

  • 优化转换码
    • spi硬件上发送数据时每两个字节中间会有一个时间间隔
    • 发送每个字符第一bit的时间不是很精确 image 以上两个因素可以使用码元的低电平对时间敏感度低(码元的低电平时间容错时间长)这个特性改善对模拟的波形进行优化。
      实际操作就是发送字符的7bit和0bit为0,可以把字符数据整体右移一个bit。
      原来的0码0X80变为0X40
      原来的1码0XF8变为0X7C

验证spi发送数据是否符合灯的规格

https://kdocs.cn/l/ceRX3DmLZQAq
image

代码注意点

1. 695 310SDK 、696 170SDK、706 SDK 本身有led spi驱动在led_spi.c文件中
- 706sdk一定要注意程序中的接口是否与下面的接口一样不然会有些问题
    - 706音箱sdk初始化接口
/***
#############################音箱 SDK######################################
#706 在使用led_spi.c中的接口去发送数据会遇到映射引脚、与硬件引脚同时有波形
#原因没有断开硬件引脚信号
#设置顺序是要先映射引脚 再断开硬件引脚信号
***/
void led_spi_init(void)
{
    if ((u32)LED_SPI == (u32)JL_SPI0) {
        spi_do = LED_SPI_PORT;
        gpio_set_function(IO_PORT_SPILT(spi_do), PORT_FUNC_SPI0_DA0);//设置引脚映射
        SFR(JL_IOMC->IOMC0, 16, 1, 1);//断开硬件引脚信号
        request_irq(IRQ_SPI0_IDX, LED_SPI_IRQ_PRIORITY, led_spi_isr, 0);
    } else if ((u32)LED_SPI == (u32)JL_SPI1) {
        spi_do = LED_SPI_PORT;
        gpio_set_function(IO_PORT_SPILT(spi_do), PORT_FUNC_SPI1_DA0);//设置引脚映射
        SFR(JL_IOMC->IOMC0, 18, 1, 1);//断开硬件引脚信号
        request_irq(IRQ_SPI1_IDX, LED_SPI_IRQ_PRIORITY, led_spi_isr, 0);
    }
    gpio_set_mode(IO_PORT_SPILT(spi_do), PORT_OUTPUT_LOW);

    os_sem_create(&led_spi_sem, 1);

    LED_SPI->BUF = 0;
    LED_SPI->CON = 0x4021;
    LED_SPI->CON1 = 0;
}

    - 706无线mic初始化接口
/***
#############################无线mic SDK######################################
#706 在使用led_spi.c中的接口去发送数据会遇到第一个灯的颜色异常
#原因发完数据之后引脚为高电平导致
#LED_SPI->BUF的第7位影响发送完数据引脚电平的高低 不赋值为随机
#LED_SPI->CON1为控制数据发送的流控方式:0:【7,6,5,4,3,2,1,0】1:【0,1,2,3,4,5,6,7】2:【3,2,1,0,7,6,5,4】3:【4,5,6,7,0,1,2,3】
***/
void led_spi_init(void)
{
    gpio_set_die(LED_SPI_IO, 1);
    gpio_set_direction(LED_SPI_IO, 0);
    gpio_set_pull_up(LED_SPI_IO, 0);
    gpio_set_pull_down(LED_SPI_IO, 0);
    gpio_write(LED_SPI_IO, 0);
    gpio_och_sel_output_signal(LED_SPI_IO, OUTPUT_CH_SIGNAL_SPI1_DO);//设置引脚映射
    SFR(JL_IOMC->IOMC0, 18, 1, 1);//断开硬件引脚信号
    request_irq(IRQ_SPI1_IDX, 0, led_spi_isr, 0);
    os_sem_create(&led_spi_sem, 1);

    LED_SPI->BUF = 0;
    LED_SPI->CON = 0x4021;
    LED_SPI->CON1 = 0;
}
2. 刷新数据是使用的定时器尽量使用sys_timer_add等非中断中执行接口
3. 使用spi.c中的接口发送数据时需要在发送时重新设置spi、sys时钟和spi波特率
4. 使用SPI组时,不能将该组的CLK引脚拉去做输出功能(只要初始化了SPI组,该组CLK引脚就会工作),SPI引脚可以映射的话可以使用。
/*
 * @brief 设置波特率
 * @parm spi  spi句柄
 * @parm baud  波特率
 * @return 0 成功,< 0 失败
 */
int spi_set_baud(spi_dev spi, u32 baud)
{
    //SPICK = sysclk / (SPIx_BAUD + 1)
    //=> SPIx_BAUD = sysclk / SPICK - 1
    u8 id = spi_get_info_id(spi);
    u32 sysclk;

    #define SYS_CLK_MAX (240000000L)
    #define SPI_CLK_MAX (60000000L)
    if(SYS_CLK_MAX>clk_get("sys")){
        clk_set("sys",SYS_CLK_MAX);
    }

// r_f_printf("---------------------------%lu %lu",clk_get("spi"),clk_get("sys"));
    if(SPI_CLK_MAX>clk_get("spi")){
        r_f_printf("---------------------------%lu",clk_get("spi"));
        clk_set("spi",SPI_CLK_MAX);
    }

    sysclk = clk_get("spi");
    // log_debug("spi clock source freq %lu", sysclk);
    if (sysclk < baud) {
        spi_w_reg_baud(spi_regs[id], 0);
        return -EINVAL;
    }
    spi_w_reg_baud(spi_regs[id], sysclk / baud - 1);
    return 0;
}

/*
 * @brief spi dma发送
 * @parm spi  spi句柄
 * @parm buf  发送缓冲区基地址
 * @parm len  期望发送长度
 * @return 实际发送长度,< 0表示失败
 */
int spi_dma_send(spi_dev spi, const void *buf, u32 len)
{
    u8 id = spi_get_info_id(spi);
    u32 clock = spi_get_info_clock(spi);
    int err = spi_set_baud(spi, clock);
    if (err ) {
        log_error("invalid spi baudrate");
        /* return 0; */
    }

    /* ASSERT((u32)buf % 4 == 0, "spi dma addr need 4-aligned"); */
    spi_dir_out(spi_regs[id]);
    spi_w_reg_dma_addr(spi_regs[id], (u32)buf);
    spi_w_reg_dma_cnt(spi_regs[id], len);
    asm("csync");
    if (__spi_wait_ok(spi, len)) {
        return -EFAULT;
    }
    return len;
}

/*
 * @brief spi 配置dma,不等待pnd,用于中断
 * @parm spi  spi句柄
 * @parm buf  缓冲区基地址
 * @parm len  期望长度
 * @parm rw  1 接收 / 0 发送
 * @return null
 */
void spi_dma_set_addr_for_isr(spi_dev spi, void *buf, u32 len, u8 rw)
{
    u8 id = spi_get_info_id(spi);
    u32 clock = spi_get_info_clock(spi);
    int err = spi_set_baud(spi, clock);
    if (err ) {
        log_error("invalid spi baudrate");
        /* return 0; */
    }

    /* ASSERT((u32)buf % 4 == 0, "spi dma addr need 4-aligned"); */
    rw ? spi_dir_in(spi_regs[id]) : spi_dir_out(spi_regs[id]);
    spi_w_reg_dma_addr(spi_regs[id], (u32)buf);
    spi_w_reg_dma_cnt(spi_regs[id], len);
}

Demo

1. 697N
  1. wireless_mic_sdk-v1.3.1_1t1_rx_spi移植成功程序.rar 2. AC692
  2. 【金山文档】 AC692x_SDK_release_V2.6.3_hsv_rgb
  3. https://kdocs.cn/l/cc1eZlrIJstW
  4. 【金山文档】 AC692x_SDK_release_V2.6.3_rgb
  5. https://kdocs.cn/l/coPpqzea4vlO 3. 695(3.1.0SDK)、696(1.7.0SDK) image 4. 701N 1. 141 SDK jl701n_soundbox_release_v1.4.1-spi-rgb.7z
    模块有3个buff分别为HSV、RGB、SPI,数据流向是HSV->RGB->SPI
    u_config.c配置文件
    u_rgb.c模块总入口
    u_rgb_drive.c SPI的数据转换与发送
    u_rgb_middleware.c中间层设置设置HSV/RGBbuff
    u_rgb_hsv.c HSV/RGB数据互转
    u_rgb_mode.c 模式扫描与切换的逻辑处理
    u_rgb_mode_fun.c 模式的实现

imageimage

image

    2. 120SDK

demo 下载
image

image

image 3. 可视化soundbox 100P02 DEMO
5. 700N 1. demo 700N自带独立模块推灯,不需要用SPI,demo在sdk里面的cpu\br36\ledc.c

#define RGB_LED_NUM    2//灯的数量
static u8 ledc_test_buf[RGB_LED_NUM * 3] __attribute__((aligned(4)));
void ledc_test(void)
{
    printf("*************  ledc test  **************\n");
    ledc_init(&ledc0_data);
    //第一个灯
    ledc_test_buf[0] = 0;//R
    ledc_test_buf[1] = 85;//G
    ledc_test_buf[2] = 170;//B
    //第二个灯
    ledc_test_buf[3] = 170;//R
    ledc_test_buf[4] = 85;//G
    ledc_test_buf[5] = 0;//B
    //2个灯的数据,重发5次,则亮灯数=(5+1)*2=12个
    u16 again = 5;
    while (1) {
        clr_wdt();
        ledc_send_rgbbuf(ledc0_data.index, ledc_test_buf, sizeof(ledc_test_buf), again);
        delay(150000);
        //第一个灯
        ledc_test_buf[0] ++;//R
        ledc_test_buf[1] ++;//G
        ledc_test_buf[2] ++;//B
        //第二个灯
        ledc_test_buf[3] ++;//R
        ledc_test_buf[4] ++;//G
        ledc_test_buf[5] ++;//B
    }
}
led_spi_700N.c
https://kdocs.cn/l/cczidSVkTGJC
#include "system/includes.h"
static const u8 SPI1_DO[2] = {
    IO_PORTC_05,//'A'  IO随便选,用的是映射
    IO_PORTC_05 //'B'
};
static const u8 SPI2_DO[2] = {
    IO_PORTB_07,//'A'
    IO_PORT_DM  //'B'
};
#define LED_SPI                 JL_SPI1
#define LED_SPI_PORT            'A'
#define LED_SPI_DAT_BAUD        2
#define LED_SPI_REST_BAUD       15
#define LED_NUM_MAX             2
#define LED_SPI_CLOCK_BASE        (clk_get("lsb") / 24000000)
static OS_SEM led_spi_sem;
static u32 spi_do = (u32)-1;
static u8 led_spi_busy = 0;
static u8 led_spi_sus = 0;
___interrupt
void led_spi_isr()
{
    LED_SPI->CON &= ~BIT(13);   //关闭中断
    LED_SPI->CON |=  BIT(14);   //清pnding
    os_sem_post(&led_spi_sem);
    led_spi_busy = 0;
}
void led_spi_init(void)
{
    if ((u32)LED_SPI == (u32)JL_SPI1) {
        spi_do = SPI1_DO[LED_SPI_PORT - 'A'];
        SFR(JL_IOMAP->CON1, 4, 1, LED_SPI_PORT - 'A');
        request_irq(IRQ_SPI1_IDX, 0, led_spi_isr, 0);
    } else {
        spi_do = SPI2_DO[LED_SPI_PORT - 'A'];
        SFR(JL_IOMAP->CON1, 16, 1, LED_SPI_PORT - 'A');
        request_irq(IRQ_SPI2_IDX, 0, led_spi_isr, 0);
    }
    gpio_set_fun_output_port(spi_do, FO_SPI1_DA0, 1, 1, LOW_POWER_FREE);//7000系列用的是Crossbar
    os_sem_create(&led_spi_sem, 1);
    LED_SPI->CON = 0x4021;
}
void led_rgb_to_24byte(u8 r, u8 g, u8 b, u8 *buf)
{
    u32 dat = ((g << 16) | (r << 8) | b);
    for (u8 i = 0; i < 24; i ++) {
        if (dat & BIT(23 - i)) {
            *(buf + i) = 0x7c;
        } else {
            *(buf + i) = 0x60;
        }
    }
}
void led_rest()
{
    u8 tmp_buf[16] = {0};
    LED_SPI->BAUD = (LED_SPI_REST_BAUD + 1) * LED_SPI_CLOCK_BASE - 1;
    LED_SPI->CON |= BIT(14);
    LED_SPI->ADR = (u32)tmp_buf;
    LED_SPI->CNT = 16;
    while (!(LED_SPI->CON & BIT(15)));
    LED_SPI->CON |= BIT(14);
}
void led_spi_send_rgbbuf(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
{
    if (!led_num) {
        return;
    }
    if (led_num > LED_NUM_MAX) {
        led_num = LED_NUM_MAX;
    }
    while (led_spi_sus) {
        os_time_dly(1);
    }
    led_spi_busy = 1;
    led_rest();
    LED_SPI->BAUD = (LED_SPI_DAT_BAUD + 1) * LED_SPI_CLOCK_BASE - 1;
    LED_SPI->CON |= BIT(14);
    LED_SPI->ADR = (u32)rgb_buf;
    LED_SPI->CNT = led_num * 24;
    while (!(LED_SPI->CON & BIT(15)));
    LED_SPI->CON |= BIT(14);
    led_spi_busy = 0;
}
void led_spi_send_rgbbuf_isr(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
{
    if (!led_num) {
        return;
    }
    if (led_num > LED_NUM_MAX) {
        led_num = LED_NUM_MAX;
    }
    while (led_spi_sus) {
        os_time_dly(1);
    }
    led_spi_busy = 1;
    os_sem_pend(&led_spi_sem, 0);
    led_rest();
    LED_SPI->BAUD = (LED_SPI_DAT_BAUD + 1) * LED_SPI_CLOCK_BASE - 1;
    LED_SPI->CON |= BIT(14);
    LED_SPI->ADR = (u32)rgb_buf;
    LED_SPI->CNT = led_num * 24;
    LED_SPI->CON |= BIT(13);//打开中断
}
u8 led_spi_suspend(void)
{
    if (led_spi_sus) {
        return 1;
    }
    if (led_spi_busy) {
        return 1;
    }
    LED_SPI->CON |=  BIT(14);
    LED_SPI->CON &= ~BIT(0);
    led_spi_sus = 1;
    return 0;
}
u8 led_spi_resume(void)
{
    if (!led_spi_sus) {
        return 0;
    }
    gpio_set_fun_output_port(spi_do, FO_SPI1_DA0, 1, 1, LOW_POWER_FREE);//7000系列用的是Crossbar
    LED_SPI->CON = 0x4021;
    led_spi_sus = 0;
    return 0;
}
static u8 spi_dat_buf[24 * LED_NUM_MAX] __attribute__((aligned(4)));
extern void wdt_clear();
//测试程序
void led_spi_test(void)
{
    printf("******************  led spi test  *******************\n");
    led_spi_init();
    u8 cnt = 0;
    u8 pulse = 0;
    while (1) {
        cnt ++;
        led_rgb_to_24byte(cnt, 255 - cnt, cnt, (u8 *)(&spi_dat_buf[0]));
        led_rgb_to_24byte(255 - cnt, cnt, 255 - cnt, (u8 *)(&spi_dat_buf[24]));
#if 1
        led_spi_send_rgbbuf(spi_dat_buf, 2);        //等待的方式,建议用在发的数据量小的场合
#else
        led_spi_send_rgbbuf_isr(spi_dat_buf, 2);    //中断的方式,建议用在发的数据量大的场合
#endif
        os_time_dly(2);
        wdt_clear();
    }
}
    2. 138SDK

led-spi-hsv-JL700N_earphone_release_V1.3.8.7z
6. 703N 1. 2.0.0-P01.04 703-suoundbox-2.0.0-P01.04-spi-rgb.7z

  1. LEDC 模块控制单线灯珠
    1. 模块代码:ledc_rgb_hsv.7z
      1. 适用范围 适用于所有带LEDC硬件模块的sdk
        image
  2. 硬件上支持2~3路(需要看用户手册)ledc
  3. 多个时间单位可选,兼容更多规格灯珠
typedef enum {
    ut_21ns=1,
    ut_42ns=2,
    ut_63ns=3,
    ut_125ns=6,
    ut_250ns=12,
    ut_500ns=24,
    ut_1us=48,
    ut_2us=96,
    ut_4us=192,
}t_unit_en;
  1. 通过配置0/1码值更方便适配不同规格灯珠
typedef  struct reg_platform_data {
    u32 index;           //控制器号
    u32 port;            //输出引脚
    u32 idle_level;      //当前帧的空闲电平,0:低电平, 1:高电平
    u32 out_inv;         //起始电平,0:高电平开始, 1:低电平开始
    u32 bit_inv;         //取数据时高低位镜像,0:不镜像,1:8位镜像,2:16位镜像,3:32位镜像
    t_unit_en   t_unit; //时间单位
    u32 t1h_cnt;         //1码的高电平时间 = t1h_cnt * t_unit;
    u32 t1l_cnt;         //1码的低电平时间 = t1l_cnt * t_unit;
    u32 t0h_cnt;         //0码的高电平时间 = t0h_cnt * t_unit;
    u32 t0l_cnt;         //0码的低电平时间 = t0l_cnt * t_unit;
    u32 t_rest_cnt;     //复位信号时间 = t_rest_cnt * t_unit;
    void (*cbfun)(void);//中断回调函数
}reg_data;
    2. 模块基础配置
LEDC_RGB_INFO info={
    .drive={
        #ifdef LEDC_0
        [LEDC_0]{.num/*灯的个数*/=1,.io={IO_PORTC_03/*io口*/,NO_CONFIG_PORT/*绑定io口*/},.cbfun=send_isr_0/*发完数据之后中断回调接口*/,.cnt=0/*重复发送数据次数 亮灯的个数=numb*(cnt+1)*/},
        #endif
        #ifdef LEDC_1
        [LEDC_1]{.num/*灯的个数*/=1,.io={IO_PORTA_02/*io口*/,NO_CONFIG_PORT/*绑定io口*/},.cbfun=send_isr_1/*发完数据之后中断回调接口*/,.cnt=1/*重复发送数据次数 亮灯的个数=numb*(cnt+1)*/},
        #endif
        #ifdef LEDC_2
        [LEDC_2]{.num/*灯的个数*/=1,.io={IO_PORTA_04/*io口*/,NO_CONFIG_PORT/*绑定io口*/},.cbfun=send_isr_2/*发完数据之后中断回调接口*/,.cnt=2/*重复发送数据次数 亮灯的个数=numb*(cnt+1)*/},
        #endif
    },
};
1. 初始化
    /*
    背景: 发送数据的时间远小于run color的时间间隔

    线程1
    1. 判断线程2是否完成发送数据
    2. 没有在发送数据
    3. 颜色变化
    4. 发送信号量同步状态
    5. 循环步骤1-4

    线程2
    1. 等待颜色变化处理完成
    2. 发送数据
    3. 循环步骤1-2
    */
    #ifdef LEDC_0
    create_rgb_task(&info.drive[LEDC_0],run_color_0/*改变颜色数据定时器回调接口*/,U_RGB_TASK_NAME_0);
    #endif
    #ifdef LEDC_1
    create_rgb_task(&info.drive[LEDC_1],run_color_1/*改变颜色数据定时器回调接口*/,U_RGB_TASK_NAME_1);
    #endif
    #ifdef LEDC_2
    create_rgb_task(&info.drive[LEDC_2],run_color_2/*改变颜色数据定时器回调接口*/,U_RGB_TASK_NAME_2);
    #endif
2. 数据的修改
static void run_color_2(const LEDC_DRIVE_INFO *drive){
    //避免在转换数据的时候修改源数据
    if(drive->send){
        return;
    }
    // r_printf("change color");

    for(int i=0;i<drive->num;i++){
        drive->hsv[i].h=(drive->hsv[i].h+1)%MAX_H;
        hsv2rgb(drive->hsv+i,drive->rgb+i);
    }

    os_sem_post(&drive->sem);
}
2. DEMO
    1.    703:

SKD1.0.0:703soundbox1.0.0SDK-LEDC-HSV-RGB.7z
2. 700: SDK1.3.8:ledc-rgb-hsv-JL700N_earphone_release_V1.3.8.7z
7. 692V263-SDK-繁体字库显示 需要用到ASCII.exe转码工具
imageimage 在上面获取码表后,填入需要显示的数组中:
imageimage download.bat需要添加 BIG5的编码
image

  1. 公版PWM_LED TWS呼吸灯同步呼吸功能,支持单IO和双IO推灯,支持单灯呼吸同步、双灯交替呼吸同步
    【金山文档】 AC897N_AD697N_earphone_release_V2.3.5_tws呼吸灯同步
    https://kdocs.cn/l/clgVi7uS3QvA

  2. LVGL字库 字库工具:LvglFontTool_V0.4.rar
    资料1:https://www.kdocs.cn/l/cp7abZRrK2u7 资料2:LVGL修改字库字模大小
    字库文字的添加:视频文件
    image

  3. 歌词显示器开发注意项 歌词显示器开发注意项.otl

FAQ

  1. 数码管显示会抖/闪屏问题
  • 提高扫屏中断的优先级(提到6),把扫屏代码放在ram中扫屏的代码必须在RAM,不然会出现死机,不屏蔽中断
#define TCFG_LED7_RUN_RAM                     1     //led7跑ram 不屏蔽中断(需要占据2k附近ram)
  • 【重点留意】:AC695 SDK irq_config.c没有上面宏定义包进去,导致中断优先级没有改为6 修改方法:
    SDK\apps\soundbox\board\br23\irq_config.c
    image
  1. LED7数码管出现有的暗有的亮的情况解决思路分享 首先在确保IO都配置为相同的强驱,配置的强驱电流大小要相同。
    造成亮暗不一致的原因:
    我们以7次扫描为一个循环状态,假如一循环中2脚只点亮一个管,那么这个时候是最亮的,如果点亮了四个管,这个时候是最暗的。
    image 解决方法:
    根据每个IO一个循环需要点亮的灯数,设置不同PWM的占空比,控制亮暗。

参考案例,以692为例:
【金山文档】 AC692x_SDK_release_V2.6.3_亮暗不一致
https://kdocs.cn/l/cfhjUZnCKdkh
imageimage 思路二: 确保每个数码管段的电流基本一致,出现亮暗不一致原因,排除硬件问题后,基本上与每次点亮的数码管段个数有关。
image 以AC6921A8为例,公版推数码管使用的是PA组和PC组口,普通输出能力是8mA,开强驱输出能力是24mA,公版默认会全部开强驱,一下情况下电流情况如下:(芯片输入电流能力会略大于输出电流能力)

每次推LED数共阳共阴
124mA24mA
212mA>12mA
38mA>8mA
46mA>6mA

由上表可以看出,公版配置可能会出现电流不一样情况,导致固定有的段会亮,有的段会灭。因此可以配置为共阴接法,默认全部关强驱,当IO为共阴极的情况下,打开强驱,增强IO输入电流能力(24mA),输出高的情况下,关闭强驱(8mA),这样的情况下每个段的电流都近似于8mA,能够有效解决亮暗不一致的问题。
修改方法:
image


/*----------------------------------------------------------------------------*/
/**@brief   LED清屏函数
   @param   x:显示横坐标
   @return  void
   @author  Change.tsai
   @note    void led7_clear(void)
*/
/*----------------------------------------------------------------------------*/
void led7_clear(void)
{

    //======C======

    LEDN_C_PORT_OUT &= ~(BIT(LEDN_S0_BIT) | BIT(LEDN_S1_BIT)  | BIT(LEDN_S3_BIT)  | BIT(LEDN_S5_BIT) | BIT(LEDN_S6_BIT));
    LEDN_C_PORT_DIR |= (BIT(LEDN_S0_BIT) | BIT(LEDN_S1_BIT)  | BIT(LEDN_S3_BIT)  | BIT(LEDN_S5_BIT) | BIT(LEDN_S6_BIT));
    LEDN_C_PORT_PU  &= ~(BIT(LEDN_S0_BIT) | BIT(LEDN_S1_BIT)  | BIT(LEDN_S3_BIT)  | BIT(LEDN_S5_BIT) | BIT(LEDN_S6_BIT));
    LEDN_C_PORT_PD  &= ~(BIT(LEDN_S0_BIT) | BIT(LEDN_S1_BIT)  | BIT(LEDN_S3_BIT)  | BIT(LEDN_S5_BIT) | BIT(LEDN_S6_BIT));
    LEDN_C_PORT_HD  &= ~(BIT(LEDN_S0_BIT) | BIT(LEDN_S1_BIT)  | BIT(LEDN_S3_BIT)  | BIT(LEDN_S5_BIT) | BIT(LEDN_S6_BIT) );
    //======A=====
    LEDN_A_PORT_OUT &= ~( BIT(LEDN_S2_BIT) |  BIT(LEDN_S4_BIT) );
    LEDN_A_PORT_DIR |= ( BIT(LEDN_S2_BIT) |  BIT(LEDN_S4_BIT)  );
    LEDN_A_PORT_PU  &= ~( BIT(LEDN_S2_BIT) |  BIT(LEDN_S4_BIT) );
    LEDN_A_PORT_PD  &= ~(BIT(LEDN_S2_BIT) |  BIT(LEDN_S4_BIT)  );
    LEDN_A_PORT_HD  &= ~( BIT(LEDN_S2_BIT) |  BIT(LEDN_S4_BIT)  );
}
/*----------------------------------------------------------------------------*/
/**@brief   LED扫描函数
   @param   void
   @return  void
   @author  Change.tsai
   @note    void led7_scan(void *param)
*/
/*----------------------------------------------------------------------------*/
void led7_scan(void *param)
{
    static u8 cnt;
    u8 seg;
    u8 user_seg;
    LED_drive7();

    seg = led7_var.bShowBuff1[cnt];
    user_seg = seg;

    // printf("user_seg[%d]==%d\n",cnt,user_seg);
    led7_clear();
    switch (cnt) {
    case 0:
        // LEDN_C_PORT_PU |=  BIT(LEDN_S0_BIT);
        LEDN_C_PORT_OUT &= ~BIT(LEDN_S0_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S0_BIT);
        LEDN_C_PORT_HD |= BIT(LEDN_S0_BIT);
        break;

    case 1:
        // LEDN_C_PORT_PU |=  BIT(LEDN_S1_BIT);
        LEDN_C_PORT_OUT &= ~BIT(LEDN_S1_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S1_BIT);
        LEDN_C_PORT_HD |= BIT(LEDN_S1_BIT);
        break;

    case 2:
        // LEDN_A_PORT_PU |=  BIT(LEDN_S2_BIT);
        LEDN_A_PORT_OUT &= ~ BIT(LEDN_S2_BIT);
        LEDN_A_PORT_DIR &= ~BIT(LEDN_S2_BIT);
        LEDN_A_PORT_HD |= BIT(LEDN_S2_BIT);
        break;

    case 3:
        // LEDN_C_PORT_PU |=  BIT(LEDN_S3_BIT);
        LEDN_C_PORT_OUT &= ~ BIT(LEDN_S3_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S3_BIT);
        LEDN_C_PORT_HD |= BIT(LEDN_S3_BIT);
        break;

    case 4:
        // LEDN_A_PORT_PU |=  BIT(LEDN_S4_BIT);
        LEDN_A_PORT_OUT &= ~ BIT(LEDN_S4_BIT);
        LEDN_A_PORT_DIR &= ~BIT(LEDN_S4_BIT);
        LEDN_A_PORT_HD |= BIT(LEDN_S4_BIT);
        break;

    case 5:
        // LEDN_C_PORT_PU |=  BIT(LEDN_S5_BIT);
        LEDN_C_PORT_OUT &= ~ BIT(LEDN_S5_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S5_BIT);
        LEDN_C_PORT_HD |= BIT(LEDN_S5_BIT);
        break;

    case 6:
        // LEDN_C_PORT_PU |=  BIT(LEDN_S6_BIT);
        LEDN_C_PORT_OUT &= ~ BIT(LEDN_S6_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S6_BIT);
        LEDN_C_PORT_HD |= BIT(LEDN_S6_BIT);
        break;
    default :
        break;
    }

    if (seg & BIT(0)) {
        
        // LEDN_C_PORT_PD |=  BIT(LEDN_S0_BIT);
        LEDN_C_PORT_OUT |= BIT(LEDN_S0_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S0_BIT);
    }

    if (seg & BIT(1)) {
        // LEDN_C_PORT_PD |=  BIT(LEDN_S1_BIT);
        LEDN_C_PORT_OUT |= BIT(LEDN_S1_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S1_BIT);
    }

    if (seg & BIT(2)) {
        // LEDN_A_PORT_PD |=  BIT(LEDN_S2_BIT);
        LEDN_A_PORT_OUT |= BIT(LEDN_S2_BIT);
        LEDN_A_PORT_DIR &= ~BIT(LEDN_S2_BIT);
    }

    if (seg & BIT(3)) {
        // LEDN_C_PORT_PD |=  BIT(LEDN_S3_BIT);
        LEDN_C_PORT_OUT|= BIT(LEDN_S3_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S3_BIT);
    }

    if (seg & BIT(4)) {
        // LEDN_A_PORT_PD |=  BIT(LEDN_S4_BIT);
        LEDN_A_PORT_OUT |= BIT(LEDN_S4_BIT);
        LEDN_A_PORT_DIR &= ~BIT(LEDN_S4_BIT);
    }

    if (seg & BIT(5)) {
        // LEDN_C_PORT_PD |=  BIT(LEDN_S5_BIT);
        LEDN_C_PORT_OUT |= BIT(LEDN_S5_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S5_BIT);
    }

    if (seg & BIT(6)) {
        // LEDN_C_PORT_PD |=  BIT(LEDN_S6_BIT);
        LEDN_C_PORT_OUT |= BIT(LEDN_S6_BIT);
        LEDN_C_PORT_DIR &= ~BIT(LEDN_S6_BIT);
    }

    cnt = (cnt >= 7) ? 0 : cnt + 1;
}
  1. AC695N 开启spi推屏 ui_task 会影响到dac L trim数值,导致DAC左声道播放会出现杂音("po声") 按照AC695X软件问题整理文档 第198点修改:
    AC695X软件问题整理.doc
  2. AC695N 使用内部框架推点阵屏需要高亮显示操作 控件高亮显示功能 ,点阵屏需要使用 int ui_invert_element_by_id(int id); 但是该接口只改变了显存的内容,并没有更新显存到屏幕
    需要新增接口
    image 在设置完高亮后,需要刷一遍屏幕
    image

本文档包含以下子页面

  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • UNICODE字库显示
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 16X96 LED阵列标准原理图V1.0
  • 12X72单色LED_V1.0
  • 16X96 RGB_LED阵列标准原理图V1.0
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C程序编译加key说明
  • AD101C强制升级工具烧录下载(ad100_uart_update_tools)使用说明补充
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
Prev
升级相关
Next
通话调试流程指南