首頁 > 評測 > 使用MM32L0130 SLCD驅動LCD顯示

使用MM32L0130 SLCD驅動LCD顯示

  
  • 作者:
  • 來源:
  • [導讀]
  • 本帖最后由 MM靈靈靈 于 2022-10-26 09:20 編輯 使用MM32L0130 SLCD驅動LCD顯示 靈動股份推出的MM32L0130系列MCU具有片上SLCD液晶顯示控制器,SLCD 驅動器是用于單色無源液晶顯示器(SLCD)的數字驅動器,具

本帖最后由 MM靈靈靈 于 2022-10-26 09:20 編輯

使用MM32L0130 SLCD驅動LCD顯示


靈動股份推出的MM32L0130系列MCU具有片上SLCD液晶顯示控制器,SLCD 驅動器是用于單色無源液晶顯示器(SLCD)的數字驅動器,具有多達 8 個公共端和多達 63 個分段端, SLCD 引腳最多為 64 個,因此最多可驅動 240(60x4)或 448(56x8)個段碼。驅動段碼的最終數量由產品規(guī)格書中設備引腳的數目決定。

一. SLCD介紹

1.1 SLCD功能框圖
SLCD 驅動模塊包括以下幾個基本的子模塊,如下圖所示。

  • 顯示數據寄存器
  • SLCD 輸出驅動引腳
  • 時鐘產生單元,包括時鐘預分頻器、幀時鐘分頻器、電荷泵時鐘分頻器和閃爍時鐘分頻器
  • 閃爍控制器
  • 內置升壓電荷泵和偏置電壓生成單元
  • 時序控制和波形發(fā)生器

 


1.2 SLCD主要特征
  • 示幀率靈活控制
  • 兼容 APB 接口
  • 支持靜態(tài)、 1/2、 1/3、 1/4、 1/6 和 1/8 占空比
  • 支持 1/2、 1/3 和 1/4 偏置電壓設置
  • 為了存儲顯示數據,內置了 16*32bit 顯示數據寄存器
  • 通過軟件來調整 SLCD 輸出電壓,來調節(jié)對比度
  • 外圍電路簡單,不需要模擬器件支持
      1)內嵌電容升壓器來得到比電源電壓更高而且不受其影響的 SLCD 驅動電壓。升壓器產生的 SLCD驅動電壓范圍可調,可以匹配支持 3V 或者 5V 的 LCD 屏幕
      2)SLCD 驅動電源可以通過軟件來選擇內部電源或外部電源。
      3)可以選擇使用內嵌電容分壓器對 SLCD 驅動電壓進行分壓,得到驅動電壓的中間值(VLCDrail1,VLCDrail2, VLCDrail3, VLCDrail4)
  • 兩種調整顯示對比度的方法
      1)當采用內部升壓器來提供 VLCD 電源時,可以通過軟件調節(jié) VLCD 輸出電壓
      2)其它情況下可以在每幀顯示之間插入死區(qū)時間
  • 支持以下低功耗模式:低功耗運行模式,睡眠模式,低功耗睡眠模式,停止模式,深度停止模式,待機模式;在不需要顯示的時候,可以完全關閉 SLCD 驅動以達到降低功耗的目的
  • 支持相位反轉模式,降低功耗和 EMI
  • 每一幀顯示開始的時候,通過中斷信號與軟件同步,更新顯示數據
  • 閃爍功能
      1)可以從所有段碼中任意選擇 1 到 8 個段碼閃爍顯示,也可以閃爍顯示全部段碼
      2)在靜態(tài)、 1/2、 1/3、 1/4 占空比模式下可以閃爍顯示任意段碼
      3)軟件選擇閃爍頻率,支持閃爍頻率 0.5Hz, 1Hz, 2Hz 或 4Hz
  • 靈活的引腳復用功能,可以配置任意 LCD 驅動引腳成為 COM 或者 SEG 功能;SLCD 的驅動引腳在沒有被配置成 SLCD 功能的時候,可以作為 GPIO 引腳來使用
  • SLCD 驅動電平(VLCDrail1, VLCDrail2, VLCDrail3, VLCDrail4)的去耦合功能
  • 支持低功耗驅動波形
  • 支持 DMA 傳輸
  • 支持中斷

二. 功能概述

2.1 顯示數據寄存器
為了存儲顯示數據, SLCD 驅動模塊內置了 16 個 32 比特顯示數據寄存器。顯示數據寄存器中的比特位與 LCD 顯示屏上的段碼一一對應, 如果要點亮 LCD 顯示屏上的某個段碼, 則需要把顯示數據寄存器中的相對應的比特寫為‘1’;反之如果要熄滅某個段碼, 則需要把對應的比特寫為‘0’, 如下圖所示。


在 static, 1/2, 1/3 和1/4 duty模式下,顯示數據寄存器被劃分為主顯示數據寄存器片區(qū)(SLCD_DR[7:0])和輔助顯示數據寄存器片區(qū)( SLCD_DR[15:8]);在 1/6 和 1/8 duty 模式下,顯示數據寄存器(SLCD_DR[15:0])全部作為主顯示數據寄存器片區(qū)使用,沒有輔助顯示數據寄存器片區(qū)的分劃。顯示數據寄存器的具體結構和詳細的片區(qū)劃分情況見下圖:


2.2 主/輔助顯示數據寄存器
在 static,1/2,1/3和1/4 duty 模式下,可以通過 SLCD 幀控制寄存器(SLCD_FCR)中的DRSEL比特選擇控制將主顯示數據寄存器片區(qū)(SLCD_DR[7:0])或者輔助顯示數據寄存器片區(qū)(SLCD_DR[15:8])的數據顯示到 LCD 屏幕上,如果DRSEL為‘0’, 顯示主顯示數據寄存器片區(qū)的數據;如果 DRSEL 為‘1’,顯示輔助顯示數據寄存器片區(qū)的數據。SLCD 狀態(tài)寄存器(SLCD_SR)中的 DRSS 比特可以指示出顯示數據當前使用的顯示數據寄存器片區(qū), 如果當前使用的是主顯示數據寄存器片區(qū)的數據, 則 DRSS 比特為‘0’;如果當前使用的是輔助顯示數據寄存器片區(qū)的數據,則 DRSS 比特為‘1’。將 SLCD 幀控制寄存器(SLCD_FCR)中的 DRLC 比特置‘1’可以清除主顯示數據寄存器片區(qū)的數據;將 DRHC 比特置‘1’可以清除輔助顯示數據寄存器片區(qū)的數據。

2.3 COM 和 SEG 引腳配置
SLCD 模塊提供公共端(COM)引腳和段(SEG)引腳的驅動。

2.4 SLCD 引腳配置
SLCD 的 SEG 和 COM 引腳是同通用功能 I/O 復用的。在不作為 SLCD 引腳使用時,這些引腳可以配置成通用功能 I/O 引腳。具體配置請參考通用功能 I/O 章節(jié)。

2.5 COM 和 SEG 引腳重映射
當作為 SLCD 引腳使用時,每一個 SLCD 引腳都可以被重映射為 COM 或者 SEG 引腳,以簡化電路板上的布局布線。SLCD 模塊支持從 L0 到 L63 最多 64 個 SLCD 引腳(SLCD 引腳的最終數量由產品規(guī)格書中設備引腳的數目決定),每一個引腳可以通過相應的 SLCD_CFGR0 和 SLCD_CFGR1 寄存器來配置,重映射其作為 COM 或者 SEG 功能。

2.6 時鐘產生
時鐘產生模塊為波形發(fā)生模塊和電荷泵模塊提供各自所需的時鐘,其結構如下:


三. 實驗

3.1 硬件設計
本次實驗使用MM32L0130片上SLCD驅動LCD液晶屏顯示。硬件使用靈動股份設計的EVB-L0136開發(fā)板,板載LCD接口可以適配GDC0689液晶屏,GDC0689具有半透和反射兩種模式,6位8字、6點視角、寬溫,適用于工業(yè)設備等產品。GDC0689液晶屏全顯效果圖如下:


EVB-L0136開發(fā)板LCD模塊原理圖如下:



3.2 程序設計
例程主要用到GDC0689液晶屏的數碼管部分進行計數顯示,以最右邊的數碼管作為小數部分,其余數碼管作為整數部分,從最低位開始累加計數,滿十就向前一位進1。

靈動股份設計了MM32F0130 SLCD相關的庫函數以及API函數,容易理解和使用,代碼較多,這里不再進行贅述,僅對部分主要程序進行分析。

3.21 SLCD測試函數
void slcd_test(void)
{
    slcd_init();
    while(1) {
        LCD_DisplayDataUpdate();
        DELAY_Ms(100);
    }
}

3.22 SLCD初始化函數
void slcd_init()函數主要代碼:

使能PWR、BKP時鐘
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_BKP, ENABLE);

使能SLCD時鐘,軟件復位SLCD
    RCC_SLCD_ClockCmd(SLCD, ENABLE);
    SLCD_DeInit();

SLCD的時鐘源選擇LSI,配置LSI時鐘頻率為40KHZ。
    RCC_LSICLKConfig(RCC_LSICLKSource_40KHz);
    RCC_LSICmd(ENABLE);
    RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSI);

LSI作為SLCD時鐘源,對應時鐘預分頻系數為4,分頻系數為16
    else if(slcd_clk_source_freq <= LSI_VALUE) {
        pre_value = SLCD_Prescaler_4;
        div_value = SLCD_Divider_16;
    }

初始化SLCD結構體,配置1/4偏置、1/3占空比,VDD作為SLCD電源使能
slcd_struct.SLCD_Divider = div_value;
    slcd_struct.SLCD_Duty = SLCD_Duty_1_4;
    slcd_struct.SLCD_Bias = SLCD_Bias_1_3;
    slcd_struct.SLCD_VoltageSource = SLCD_VoltSrcCapCharggDownVdd;
    SLCD_Init(&slcd_struct);

SLCD pin對應的GPIO配置為SEG或COM,并使能
    SLCD_IO_Config(&(SEGorCOM[0]));
    //must call after SLCD_init

配合SLCD COM索引寄存器
    SLCD_COM_IndexInit(&(SCLD_COM_Index[0]));

配置電荷泵時鐘分頻為1024
    SLCD_ChargePumpClockDivConfig(SLCD_ChargePumpClock_Div1024);

正常驅動波形
    SLCD_LowPowerDriveCmd(DISABLE);

配置無死區(qū)插入,當在兩幀之間插入死區(qū)時,SEG和COM信號電壓為零
    SLCD_DeadTimeConfig(SLCD_DeadTime_0);

清除顯示數據寄存器
    LCD_Clear();

關閉SLCD閃爍模式,閃爍時鐘分頻系數為512
    SLCD_BlinkConfig(SLCD_BlinkMode_Off, SLCD_BlinkFrequency_Div512);

配置SLCD閃爍索引
    SLCD_BLINK_IndexInit(SCLD_BLINK_Index);

3.23 LCD更新顯示數據函數
LCD_DisplayDataUpdate()函數主要代碼:   
    Number1 = (Number1 + 1) % 1000000;

    if(Number1 < 10) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, ' ', 0);
        LCD_DisplayNumber1(3, ' ', 0);
        LCD_DisplayNumber1(4, '0', 1);
        LCD_DisplayNumber1(5, '0' + Number1, 0);
    }
    else if(Number1 < 100) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, ' ', 0);
        LCD_DisplayNumber1(3, ' ', 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1 ) % 10), 0);
    }
    ......(省略余下代碼)

其中LCD顯示函數 void LCD_DisplayNumber1(u8 Index, char ch, u8 Point)用于配置數碼管顯示,函數的3個形參含義如下:
  • Index表示選中的數碼管索引,對應6個數碼管,可選值為0,1,2,3,4,5
  • ch表示要顯示的數字,為char類型
  • Point表示該數碼管是否顯示Dp字段,顯示則為1,否則為0

舉例:代碼中LCD_DisplayNumber1(5, '0' + Number1, 0)表示選中第5個數碼管(最右),顯示內容是Number的值,不顯示Dp字段。

3.24 LCD顯示函數
LCD_DisplayNumber1()函數主要代碼:
void LCD_DisplayNumber1(u8 Index, char ch, u8 Point)
{
    u8 i;
    char TAB[6][8][4] =  {   // (1)
        {"5A ", "5B ", "5C ", "5D ", "5E ", "5F ", "5G ", "DP5"},
        {"6A ", "6B ", "6C ", "6D ", "6E ", "6F ", "6G ", "DP6"},
        {"7A ", "7B ", "7C ", "7D ", "7E ", "7F ", "7G ", "DP7"},
        {"8A ", "8B ", "8C ", "8D ", "8E ", "8F ", "8G ", "DP8"},
        {"9A ", "9B ", "9C ", "9D ", "9E ", "9F ", "9G ", "DP9"},
        {"10A", "10B", "10C", "10D", "10E", "10F", "10G", "   "},
    };

    u8 COMn = 0xFF, SEGn = 0xFF;

    u8 Code = LCD_SearchCode(ch);   // (2)

    if(Code != 0xFF) {
        for(i = 0; i < 7; i++) {
            LCD_SearchName(TAB[Index], &COMn, &SEGn);   // (3)

            if((COMn != 0xFF) && (SEGn != 0xFF)) {
                LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], (Code >> i) & 0x01);   // (4)
            }
        }

        LCD_SearchName(TAB[Index][7], &COMn, &SEGn); // (5)

        if((COMn != 0xFF) && (SEGn != 0xFF)) {
            LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], Point);   // (6)
        }
    }
}

  • 定義三維字符數組TAB[6][8][4],其中[6]對應6位“8”字,[8]對應“8”字的8段(含DP段),[4]表示元素的長度,對應各段的名稱。
  • 形參ch表示要顯示的數字,為char類型,LCD_SearchCode(char ch)函數用來遍歷LCD_CODE_Table[38],如果傳入的參數ch和LCD_CODE_Table.ch相等,則返回LCD_CODE_Table.Data,即該數字對應的段選信號。
  • LCD_SearchName(TAB[Index], &COMn, &SEGn)函數遍歷所有COM口(4)和SEG口(22),如果TAB[Index]和LCD_NAME_Table[j]相等,則獲取COMn和SEGn的值,然后返回。
  • 獲取COMn對應的顯示數據寄存器索引,根據段選信號,給顯示數據寄存器賦值。
  • 獲取Dp段對應的COMn和SEGn的值,然后返回。
  • 獲取COMn對應的顯示數據寄存器索引,根據Dp段選信號,給顯示數據寄存器賦值。
  • 本文系21ic原創(chuàng),未經許可禁止轉載!

網友評論