1.15. Segment Code LCD
本芯片内置一个断码屏驱动器,最大支持4*27 或 6*25的LCD断码屏 支持1/2、1/3、1/4bias; 支持电压灵活调节; 支持跳秒信号映射到任意的seg口; 可使用RTC晶振32KHz或内部LRC作为模块时钟; 详细的示例代码请参考SDK “cpu/demo/segment_code_lcd_demo.c”。
Note
使用RTC晶振32KHz为模块时钟时,才支持跳秒设置
晶振需要初始化RTC后才能使用(占用PA7 PA8)
1.15.1. 断码屏驱动使用流程
Note
LCD IO复用其他功能时,LCD的COM口需要保持高阻状态
LCD IO驱动过程中,会翻转,因此其他功能复用需要考虑协议相互干扰
1.15.1.1. LCD IO不复用
配置使用到的LCD COM和SEG IO高阻输入,且DIE=0 DIEH=0;
配置LCD显示像素点寄存器;
配置LCD模式配置;
LCD配置成连续推屏模式;
开启LCD使能位;
写入软件KIST START BIT(KST);
LCD模块开始工作,接管IO;
1.15.1.2. LCD IO复用切换
LCD配置成断续推屏模式;
等待LCD当前帧结束pending或者中断;
关闭LCD模块使能位;
LCD模块停止工作,COM IO保持高阻输入;
SEG IO可释放,复用做其他功能;
其他功能完成后,恢复SEG IO为高阻输入,继续推屏;
开启LCD模块使能位;
写入软件KIST START BIT(KST);
LCD模块开始工作,接管IO,下一步到(2)
1.15.1.3. LCD IO不复用切换
LCD配置成断续推屏模式
等待LCD当前帧结束pending或者中断
关闭LCD模块使能位
LCD模块停止工作,COM IO保持高阻输入
SEG IO可释放,复用做其他功能
其他功能完成后,恢复SEG IO为高阻输入
LCD配置成连续推屏模式
开启LCD模块使能位
写入软件KIST START BIT(KST)
LCD模块开始工作,接管IO
1.15.2. 断码屏驱动基本接口
1.15.2.1. segment_code_lcd_init
lcd断码屏驱动初始化接口,支持配置时钟,电压,充电模式,跳秒等,先初始化之后才能调用其他api
原型:
struct segment_code_lcd_platform_data {
enum lcd_clk clk; //时钟配置
enum lcdcp_pmup_vol chgpump_vol;//charge pump电压配置
enum lcdcp_ldob_vol ldob_vol; //ldob电压配置
enum lcd_vol vlcd; //电压分压设置
enum lcd_bias bias; //偏压设置
enum lcd_chgmode chgmode; //充电模式设置
u8 chgduty; //强充时间设置,当chgmode==LCD_CHGMODE_MANY_CYCLE时有效
enum lcd_com_index dot_com; //跳秒脚对应的com口(使用OSL_CLK时钟时才有效)
enum lcd_seg_index dot_seg; //跳秒脚对应的seg口(使用OSL_CLK时钟时才有效)
u8 lcd_com_en; //设置使用的com的IO, bit0~bit5 对应 com0~com5
u32 lcd_seg_en; //设置使用的seg的IO, bit0~bit26 对应 seg0~seg26
u8 ctu_en; //1:连续模式(CPU控制) 0:断续模式(ie=1)
void (*isr_cb)(void); //断续模式时,中断回调函数
};
void segment_code_lcd_init(const struct segment_code_lcd_platform_data *lcd_dat);
- 参数:
lcd_dat
初始化配置传参
返回值
无
1.15.2.2. segment_code_lcd_deinit
关闭LCD断码屏模块,与segment_code_lcd_init相对
原型:
void segment_code_lcd_deinit(void);
- 参数:
参数
无
返回值
无
1.15.2.3. segment_code_lcd_set_ctu_en
设置LCD驱动为连续模式还是断续模式,中途改变LCD驱动方式时可调用
原型:
void segment_code_lcd_set_ctu_en(u8 ctu_en);
- 参数:
ctu_en
0:断续模式 1:连续模式(CPU控制)
返回值
无
1.15.2.4. segment_code_lcd_set_dot_en
设置跳秒使能/禁能,跳秒显示切换时调用
原型:
void segment_code_lcd_set_dot_en(u8 dot_en);
- 参数:
dot_en
0:跳秒禁能 1:跳秒使能
返回值
无
1.15.2.5. segment_code_lcd_start
启动LCD模块,当使用断续推屏模式时,复用功能完成后,调用该接口重新启动推屏
原型:
void segment_code_lcd_start(void);
- 参数:
传参
无
返回值
无
1.15.2.6. segment_code_lcd_fill_point
需要填充一个点或者清除一个点时调用,该接口不会更新到硬件寄存器
原型:
void segment_code_lcd_fill_point(u8 icon, u8 isfill);
- 参数:
icon
点的位置, 高5位表示seg口,低3bit表示com口
isfill
0:清除 1:填充
返回值
无
1.15.2.7. segment_code_lcd_fill_number
填充一个数字,需要填充数字时调用,该接口不会更新到硬件寄存器
原型:
void segment_code_lcd_fill_number(const u8 ptr[], u8 num);
- 参数:
ptr[]
需要显示数字的7段LCD对应的点位置的数组
num
需要填充的数字,num > 11时清除显示
返回值
无
1.15.2.8. segment_code_lcd_fill_char
填充一个英文字符,需要填充英文字符时调用,该接口不会更新到硬件寄存器
原型:
void segment_code_lcd_fill_char(const u8 ptr[], u8 cc);
- 参数:
ptr[]
需要显示英文字符的7段LCD对应的点位置的数组
cc
需要填充的英文字符, ‘a’~’z’ 或 ‘A’~’Z’
返回值
无
1.15.2.9. segment_code_lcd_disp_clear
清屏,需要清屏时调用,该接口不会更新到硬件寄存器
原型:
void segment_code_lcd_disp_clear(void);
- 参数:
传参
无
返回值
无
1.15.2.10. segment_code_lcd_disp_all
全显,需要全显时调用,该接口不会更新到硬件寄存器
原型:
void segment_code_lcd_disp_all(void);
- 参数:
传参
无
返回值
无
1.15.2.11. segment_code_lcd_disp_update
更新显示缓存,需要把缓存更新到寄存器时调用
原型:
void segment_code_lcd_disp_update(void);
- 参数:
传参
无
返回值
无
1.15.3. HADC使用示例代码
#define NUM_SYS_HUN_A (LCD_POINT(0, 9))
#define NUM_SYS_HUN_B (LCD_POINT(0, 8))
#define NUM_SYS_HUN_C (LCD_POINT(2, 8))
#define NUM_SYS_HUN_D (LCD_POINT(2, 9))
#define NUM_SYS_HUN_E (LCD_POINT(1, 9))
#define NUM_SYS_HUN_F (LCD_POINT(INVALID_COM, 0))
#define NUM_SYS_HUN_G (LCD_POINT(1, 8))
#define NUM_SYS_TEN_A (LCD_POINT(0, 6))
#define NUM_SYS_TEN_B (LCD_POINT(1, 5))
#define NUM_SYS_TEN_C (LCD_POINT(2, 5))
#define NUM_SYS_TEN_D (LCD_POINT(2, 6))
#define NUM_SYS_TEN_E (LCD_POINT(2, 7))
#define NUM_SYS_TEN_F (LCD_POINT(1, 7))
#define NUM_SYS_TEN_G (LCD_POINT(1, 6))
#define NUM_SYS_ONE_A (LCD_POINT(0, 3))
#define NUM_SYS_ONE_B (LCD_POINT(1, 2))
#define NUM_SYS_ONE_C (LCD_POINT(2, 2))
#define NUM_SYS_ONE_D (LCD_POINT(2, 3))
#define NUM_SYS_ONE_E (LCD_POINT(2, 4))
#define NUM_SYS_ONE_F (LCD_POINT(1, 4))
#define NUM_SYS_ONE_G (LCD_POINT(1, 3))
#define NUM_DIA_HUN_A (LCD_POINT(3, 9))
#define NUM_DIA_HUN_B (LCD_POINT(3, 8))
#define NUM_DIA_HUN_C (LCD_POINT(5, 8))
#define NUM_DIA_HUN_D (LCD_POINT(5, 9))
#define NUM_DIA_HUN_E (LCD_POINT(4, 9))
#define NUM_DIA_HUN_F (LCD_POINT(INVALID_COM, 0))
#define NUM_DIA_HUN_G (LCD_POINT(4, 8))
#define NUM_DIA_TEN_A (LCD_POINT(3, 6))
#define NUM_DIA_TEN_B (LCD_POINT(3, 5))
#define NUM_DIA_TEN_C (LCD_POINT(4, 5))
#define NUM_DIA_TEN_D (LCD_POINT(5, 6))
#define NUM_DIA_TEN_E (LCD_POINT(4, 7))
#define NUM_DIA_TEN_F (LCD_POINT(3, 7))
#define NUM_DIA_TEN_G (LCD_POINT(4, 6))
#define NUM_DIA_ONE_A (LCD_POINT(3, 3))
#define NUM_DIA_ONE_B (LCD_POINT(3, 2))
#define NUM_DIA_ONE_C (LCD_POINT(4, 2))
#define NUM_DIA_ONE_D (LCD_POINT(5, 3))
#define NUM_DIA_ONE_E (LCD_POINT(4, 4))
#define NUM_DIA_ONE_F (LCD_POINT(3, 4))
#define NUM_DIA_ONE_G (LCD_POINT(4, 3))
static const u8 NUM_SYS_HUN[7] = {NUM_SYS_HUN_A, NUM_SYS_HUN_B, NUM_SYS_HUN_C, NUM_SYS_HUN_D, NUM_SYS_HUN_E, NUM_SYS_HUN_F, NUM_SYS_HUN_G};
static const u8 NUM_SYS_TEN[7] = {NUM_SYS_TEN_A, NUM_SYS_TEN_B, NUM_SYS_TEN_C, NUM_SYS_TEN_D, NUM_SYS_TEN_E, NUM_SYS_TEN_F, NUM_SYS_TEN_G};
static const u8 NUM_SYS_ONE[7] = {NUM_SYS_ONE_A, NUM_SYS_ONE_B, NUM_SYS_ONE_C, NUM_SYS_ONE_D, NUM_SYS_ONE_E, NUM_SYS_ONE_F, NUM_SYS_ONE_G};
static const u8 NUM_DIA_HUN[7] = {NUM_DIA_HUN_A, NUM_DIA_HUN_B, NUM_DIA_HUN_C, NUM_DIA_HUN_D, NUM_DIA_HUN_E, NUM_DIA_HUN_F, NUM_DIA_HUN_G};
static const u8 NUM_DIA_TEN[7] = {NUM_DIA_TEN_A, NUM_DIA_TEN_B, NUM_DIA_TEN_C, NUM_DIA_TEN_D, NUM_DIA_TEN_E, NUM_DIA_TEN_F, NUM_DIA_TEN_G};
static const u8 NUM_DIA_ONE[7] = {NUM_DIA_ONE_A, NUM_DIA_ONE_B, NUM_DIA_ONE_C, NUM_DIA_ONE_D, NUM_DIA_ONE_E, NUM_DIA_ONE_F, NUM_DIA_ONE_G};
const struct segment_code_lcd_platform_data lcd_test_data = {
.clk = LCD_CLK_SEL_WCLK,
.chgpump_vol = LCDCP_PUMPVOL_SEL_3P8V,
.ldob_vol = LCDCP_LDOB_SEL_3P3V,
.vlcd = LCD_VOL_SEL_1P000XLCDCP,
.bias = LCD_BIAS_1DIV3,
.chgmode = LCD_CHGMODE_STRONG,
.chgduty = 0,
.dot_com = LCD_COM0,
.dot_seg = LCD_SEG18,
.lcd_com_en = 0x3F, //6com
.lcd_seg_en = 0x7FFFFC, //21seg
.ctu_en = 1, //0:断续推屏(en ie) 1:连续推屏
.isr_cb = NULL,
};
void segment_code_lcd_test(void)
{
segment_code_lcd_init(&lcd_test_data);
segment_code_lcd_disp_all();
segment_code_lcd_disp_update();
mdelay(500);
segment_code_lcd_disp_clear();
segment_code_lcd_fill_number(NUM_SYS_HUN, 1);
segment_code_lcd_fill_number(NUM_SYS_TEN, 2);
segment_code_lcd_fill_number(NUM_SYS_ONE, 3);
segment_code_lcd_fill_number(NUM_DIA_HUN, 1);
segment_code_lcd_fill_number(NUM_DIA_TEN, 5);
segment_code_lcd_fill_number(NUM_DIA_ONE, 7);
segment_code_lcd_disp_update();
while (1) {
wdt_clear();
}
}