- typedef struct
- {
- char ch;
- uint8_t Data;
- } SLCD_Code_TypeDef;
- const SLCD_Code_TypeDef SLCD_CodeTable[38] =
- {
- { ' ', 0x00 },
- { '0', 0x3F },
- { '1', 0x06 },
- { '2', 0x5B },
- { '3', 0x4F },
- { '4', 0x66 },
- { '5', 0x6D },
- { '6', 0x7D },
- { '7', 0x07 },
- { '8', 0x7F },
- { '9', 0x6F },
- { 'A', 0x77 },
- { 'b', 0x7C },
- { 'c', 0x58 },
- { 'C', 0x39 },
- { 'd', 0x5E },
- { 'E', 0x79 },
- { 'F', 0x71 },
- { 'g', 0x6F },
- { 'H', 0x76 },
- { 'h', 0x74 },
- { 'i', 0x04 },
- { 'I', 0x30 },
- { 'J', 0x1E },
- { 'l', 0x30 },
- { 'L', 0x38 },
- { 'n', 0x54 },
- { 'o', 0x5C },
- { 'O', 0x3F },
- { 'P', 0x73 },
- { 'q', 0x67 },
- { 'r', 0x50 },
- { 'S', 0x6D },
- { 't', 0x78 },
- { 'u', 0x1C },
- { 'U', 0x3E },
- { 'y', 0x6E },
- { '-', 0x40 },
- };
这些显示字符和段位显示的对应关系都是固定,如果你还需要其它的定制某一段位的显示,是可以自行进行修改添加的,但需要注意数组的大小定义和使用到该数组时个遍历的个数,也需要同步修改一致。
5.2.MM32L0130系列MCU引脚与LCD功能引脚的对应关系,我们可以通过芯片的数据手册来获悉,在数据手册4.2引脚定义表中,Name列是MCU引脚名称,LCD Function列是LCD功能引脚下标;通过这个表格的整理,最大LCD Function是L63,但在L0~L63之间有不存在的项,所以为了我们定义数组的完整,我们在程序设计时,将不存在的Lx下标都定义在一个没有LCD功能的PH0引脚上,这么定义只是为了数组的完整和顺序性。
- typedef struct
- {
- GPIO_TypeDef *GPIOn;
- uint16_t PINn;
- uint32_t Line;
- } SLCD_Line_TypeDef;
- const SLCD_Line_TypeDef SLCD_LineTable[] =
- {
- { GPIOC, GPIO_Pin_13, SLCD_L0 },
- { GPIOD, GPIO_Pin_7, SLCD_L1 },
- { GPIOB, GPIO_Pin_9, SLCD_L2 },
- { GPIOB, GPIO_Pin_8, SLCD_L3 },
- { GPIOC, GPIO_Pin_12, SLCD_L4 },
- { GPIOC, GPIO_Pin_11, SLCD_L5 },
- { GPIOC, GPIO_Pin_10, SLCD_L6 },
- { GPIOA, GPIO_Pin_15, SLCD_L7 },
- { GPIOD, GPIO_Pin_3, SLCD_L8 },
- { GPIOD, GPIO_Pin_2, SLCD_L9 },
- { GPIOA, GPIO_Pin_12, SLCD_L10 },
- { GPIOA, GPIO_Pin_11, SLCD_L11 },
- { GPIOA, GPIO_Pin_10, SLCD_L12 },
- { GPIOA, GPIO_Pin_9, SLCD_L13 },
- { GPIOA, GPIO_Pin_8, SLCD_L14 },
- { GPIOC, GPIO_Pin_9, SLCD_L15 },
- { GPIOC, GPIO_Pin_8, SLCD_L16 },
- { GPIOC, GPIO_Pin_7, SLCD_L17 },
- { GPIOC, GPIO_Pin_6, SLCD_L18 },
- { GPIOB, GPIO_Pin_15, SLCD_L19 },
- { GPIOB, GPIO_Pin_14, SLCD_L20 },
- { GPIOB, GPIO_Pin_13, SLCD_L21 },
- { GPIOB, GPIO_Pin_12, SLCD_L22 },
- { GPIOB, GPIO_Pin_11, SLCD_L23 },
- { GPIOB, GPIO_Pin_10, SLCD_L24 },
- { GPIOB, GPIO_Pin_2, SLCD_L25 },
- { GPIOB, GPIO_Pin_1, SLCD_L26 },
- { GPIOB, GPIO_Pin_0, SLCD_L27 },
- { GPIOC, GPIO_Pin_5, SLCD_L28 },
- { GPIOC, GPIO_Pin_4, SLCD_L29 },
- { GPIOA, GPIO_Pin_7, SLCD_L30 },
- { GPIOA, GPIO_Pin_6, SLCD_L31 },
- { GPIOA, GPIO_Pin_5, SLCD_L32 },
- { GPIOA, GPIO_Pin_4, SLCD_L33 },
- { GPIOD, GPIO_Pin_5, SLCD_L34 },
- { GPIOD, GPIO_Pin_4, SLCD_L35 },
- { GPIOA, GPIO_Pin_3, SLCD_L36 },
- { GPIOA, GPIO_Pin_2, SLCD_L37 },
- { GPIOA, GPIO_Pin_1, SLCD_L38 },
- { GPIOA, GPIO_Pin_0, SLCD_L39 },
- { GPIOC, GPIO_Pin_3, SLCD_L40 },
- { GPIOC, GPIO_Pin_2, SLCD_L41 },
- { GPIOC, GPIO_Pin_1, SLCD_L42 },
- { GPIOC, GPIO_Pin_0, SLCD_L43 },
- { GPIOH, GPIO_Pin_0, SLCD_L44 },
- { GPIOH, GPIO_Pin_0, SLCD_L45 },
- { GPIOH, GPIO_Pin_0, SLCD_L46 },
- { GPIOH, GPIO_Pin_0, SLCD_L47 },
- { GPIOH, GPIO_Pin_0, SLCD_L48 },
- { GPIOH, GPIO_Pin_0, SLCD_L49 },
- { GPIOH, GPIO_Pin_0, SLCD_L50 },
- { GPIOH, GPIO_Pin_0, SLCD_L51 },
- { GPIOH, GPIO_Pin_0, SLCD_L52 },
- { GPIOH, GPIO_Pin_0, SLCD_L53 },
- { GPIOH, GPIO_Pin_0, SLCD_L54 },
- { GPIOH, GPIO_Pin_0, SLCD_L55 },
- { GPIOH, GPIO_Pin_0, SLCD_L56 },
- { GPIOH, GPIO_Pin_0, SLCD_L57 },
- { GPIOD, GPIO_Pin_6, SLCD_L58 },
- { GPIOB, GPIO_Pin_3, SLCD_L59 },
- { GPIOB, GPIO_Pin_4, SLCD_L60 },
- { GPIOB, GPIO_Pin_5, SLCD_L61 },
- { GPIOB, GPIO_Pin_6, SLCD_L62 },
- { GPIOB, GPIO_Pin_7, SLCD_L63 },
- };
如上定义的结构体中,GPIOn是端口号,PINn是引脚,Line是LCD Function的下标号;如上定义的结构体数组是依据MM32L0160系列MCU引脚定义表进行列举的,属于固定内容,无需修改,也不能够修改,切记!!!定义此结构体、数组是为了在后面程序中可以通过查表的方式来配置的MCU引脚功能,不需要再通过数据手册一个个翻查对应关系了。
5.3.段码LCD显示屏真值表数组定义,这个可以直接参照段码LCD显示屏真值表的段码名,在后面显示的时候通过真值表中的段码名可以直接进行查询,既方便又直观,快速的定位到当前段码名对应真值表当中的哪个COM和SEG:
- const char SLCD_NAME_Table[SLCD_COM_NUMBER][SLCD_SEG_NUMBER][4] =
- {
- { "1D ", "DP1", "2D ", "DP2", "3D ", "DP3", "4D ", "C1 ", "C2 ", "W5 ", "L1 ", "5F ", "5A ", "6F ", "6A ", "7F ", "7A ", "S4 ", "S5 ", "8F ", "8A ", "9F ", "9A ", "10F", "10A" },
- { "1E ", "1C ", "2E ", "2C ", "3E ", "3C ", "4E ", "4C ", "C3 ", "W4 ", "L2 ", "5G ", "5B ", "6G ", "6B ", "7G ", "7B ", "S3 ", "S6 ", "8G ", "8B ", "9G ", "9B ", "10G", "10B" },
- { "1G ", "1B ", "2G ", "2B ", "3G ", "3B ", "4G ", "4B ", "T1 ", "W3 ", "L3 ", "5E ", "5C ", "6E ", "6C ", "7E ", "7C ", "S2 ", "S7 ", "8E ", "8C ", "9E ", "9C ", "10E", "10C" },
- { "1F ", "1A ", "2F ", "2A ", "3F ", "3A ", "4F ", "4A ", "W1 ", "W2 ", "L4 ", "5D ", "DP5", "6D ", "DP6", "7D ", "DP7", "S1 ", "S8 ", "8D ", "DP8", "9D ", "DP9", "10D", "S9 " },
- };
5.4.段码LCD显示屏硬件连接映射表,这也是最关键的一步;我们通过定义如下结构体,来说明MCU引脚对应的LCD功能,MCU引脚是作为SEG功能使用,还是作为COM功能使用,在结构体中GPIOn是端口号,PINn是引脚,Line是LCD Function的下标号,LineGroup是分组,Mode是引脚配置;其中Line和LineGroup在定义结构体数组时,初始值都是0,后面程序设计中会自动根据5.2小节的功能进行自动匹配,定义LineGroup是因为在操作寄存器时有区分,所以后面程序中将L0~L31划分为LineGroup1,将L31~L63划分到LineGroup2,以此来操作不同的显示缓存;最后Mode就是用来区分是MCU是作SEG功能使用的,还是作为COM功能使用的了:
- typedef struct
- {
- GPIO_TypeDef *GPIOn;
- uint16_t PINn;
- uint32_t Line;
- uint8_t LineGroup;
- uint8_t Mode;
- } SLCD_IO_TypeDef;
- SLCD_IO_TypeDef SLCD_SCH[SLCD_PIN_NUMBER] =
- {
- { GPIOB, GPIO_Pin_8, 0, 0, SLCD_IOConfigSEG }, /* PB8 : SLCD_D0 */
- { GPIOA, GPIO_Pin_15, 0, 0, SLCD_IOConfigSEG }, /* PA15 : SLCD_D1 */
- { GPIOC, GPIO_Pin_10, 0, 0, SLCD_IOConfigSEG }, /* PC10 : SLCD_D2 */
- { GPIOC, GPIO_Pin_11, 0, 0, SLCD_IOConfigSEG }, /* PC11 : SLCD_D3 */
- { GPIOC, GPIO_Pin_12, 0, 0, SLCD_IOConfigSEG }, /* PC12 : SLCD_D4 */
- { GPIOD, GPIO_Pin_6, 0, 0, SLCD_IOConfigSEG }, /* PD6 : SLCD_D5 */
- { GPIOB, GPIO_Pin_1, 0, 0, SLCD_IOConfigSEG }, /* PB1 : SLCD_D6 */
- { GPIOB, GPIO_Pin_0, 0, 0, SLCD_IOConfigSEG }, /* PB0 : SLCD_D7 */
- { GPIOA, GPIO_Pin_7, 0, 0, SLCD_IOConfigSEG }, /* PA7 : SLCD_D8 */
- { GPIOA, GPIO_Pin_6, 0, 0, SLCD_IOConfigSEG }, /* PA6 : SLCD_D9 */
- { GPIOD, GPIO_Pin_5, 0, 0, SLCD_IOConfigSEG }, /* PD5 : SLCD_D10 */
- { GPIOD, GPIO_Pin_3, 0, 0, SLCD_IOConfigSEG }, /* PD3 : SLCD_D11 */
- { GPIOD, GPIO_Pin_2, 0, 0, SLCD_IOConfigSEG }, /* PD2 : SLCD_D12 */
- { GPIOA, GPIO_Pin_12, 0, 0, SLCD_IOConfigSEG }, /* PA12 : SLCD_D13 */
- { GPIOA, GPIO_Pin_11, 0, 0, SLCD_IOConfigSEG }, /* PA11 : SLCD_D14 */
- { GPIOC, GPIO_Pin_9, 0, 0, SLCD_IOConfigSEG }, /* PC9 : SLCD_D15 */
- { GPIOC, GPIO_Pin_8, 0, 0, SLCD_IOConfigSEG }, /* PC8 : SLCD_D16 */
- { GPIOC, GPIO_Pin_7, 0, 0, SLCD_IOConfigSEG }, /* PC7 : SLCD_D17 */
- { GPIOC, GPIO_Pin_6, 0, 0, SLCD_IOConfigSEG }, /* PC6 : SLCD_D18 */
- { GPIOB, GPIO_Pin_14, 0, 0, SLCD_IOConfigSEG }, /* PB14 : SLCD_D19 */
- { GPIOB, GPIO_Pin_15, 0, 0, SLCD_IOConfigSEG }, /* PB15 : SLCD_D20 */
- { GPIOB, GPIO_Pin_12, 0, 0, SLCD_IOConfigSEG }, /* PB12 : SLCD_D21 */
- { GPIOB, GPIO_Pin_13, 0, 0, SLCD_IOConfigSEG }, /* PB13 : SLCD_D22 */
- { GPIOC, GPIO_Pin_5, 0, 0, SLCD_IOConfigSEG }, /* PC5 : SLCD_D23 */
- { GPIOC, GPIO_Pin_4, 0, 0, SLCD_IOConfigSEG }, /* PC4 : SLCD_D24 */
- { GPIOD, GPIO_Pin_4, 0, 0, SLCD_IOConfigCOM }, /* PD4 : SLCD_COM0 */
- { GPIOC, GPIO_Pin_3, 0, 0, SLCD_IOConfigCOM }, /* PC3 : SLCD_COM1 */
- { GPIOC, GPIO_Pin_13, 0, 0, SLCD_IOConfigCOM }, /* PC13 : SLCD_COM2 */
- { GPIOD, GPIO_Pin_7, 0, 0, SLCD_IOConfigCOM }, /* PD7 : SLCD_COM3 */
- };
如上的结构体数组,需要根据硬件原理图设计中的MCU引脚和LCD引脚的实际连接来定义,并且需要按照顺序依次来定义,参照LCD_SEG0、LCD_SEG1、LCD_SEG2……LCD_SEGn、LCD_COM0、LCD_COM1……LCD_COMm这样的顺序编写。
5.5.底层函数实现,这些都是固定的,不需要客户修改,如下所示:
- void SLCD_Clear(uint8_t Mode)
- {
- uint8_t i = 0;
- if (0 != Mode)
- {
- for (i = 0; i < 16; i++)
- {
- SLCD->DR[i] = 0xFFFFFFFF;
- }
- }
- else
- {
- for (i = 0; i < 16; i++)
- {
- SLCD->DR[i] = 0x00000000;
- }
- }
- }
- void SLCD_WriteBit(uint8_t COMn, uint32_t SEGn, uint32_t Group, uint8_t State)
- {
- uint8_t Index = COMn * 2 + Group;
- if (State)
- {
- SLCD->DR[Index] |= SEGn;
- }
- else
- {
- SLCD->DR[Index] &= ~SEGn;
- }
- }
- uint8_t SLCD_SearchCode(char ch)
- {
- uint8_t i = 0;
- for (i = 0; i < 38; i++)
- {
- if (ch == SLCD_CodeTable[i].ch)
- {
- return (SLCD_CodeTable[i].Data);
- }
- }
- return (0xFF);
- }
- void SLCD_SearchName(char *str, uint8_t *COMn, uint8_t *SEGn)
- {
- uint8_t i = 0, j = 0;
- for (i = 0; i < SLCD_COM_NUMBER; i++)
- {
- for (j = 0; j < SLCD_SEG_NUMBER; j++)
- {
- if (strcmp(str, SLCD_NAME_Table[i][j]) == 0)
- {
- *COMn = i;
- *SEGn = j;
- return;
- }
- }
- }
- *COMn = 0xFF;
- *SEGn = 0xFF;
- }
void SLCD_Clear(uint8_t Mode)函数是清除所有LCD段位的显示,通过Mode来控制是全显示,还是全不显示
void SLCD_WriteBit(uint8_t COMn, uint32_t SEGn, uint32_t Group, uint8_t State)函数是操作显示RAM的某一位,通过COM、SEG和Group确定操作SLCD显示RAM的位置,通过State来控制显示还是不显示
uint8_t SLCD_SearchCode(char ch)函数是通过显示字符ch查找与之对应的段码数值
void SLCD_SearchName(char *str, uint8_t *COMn, uint8_t *SEGn)函数是通过真值表段名查找对应的COM和SEG下标
通过上述这些函数就可以组合实现具体的显示应用啦!
5.6.SLCD的配置,需要开启使用到GPIO的时钟、SLCD的时钟,当然对于输入到SLCD的时钟源是可以选择的,可以根据需求进行配置,另外就是LCD功能的配置了,具体参考哪下几个函数:
void SLCD_Configure(void)函数是SLCD的总配置入口,如下所示:
- void SLCD_Configure(void)
- {
- SLCD_InitTypeDef SLCD_InitStructure;
- uint32_t SLCD_ClockFreq = 0;
- uint32_t SLCD_Prescaler = SLCD_Prescaler_16;
- uint32_t SLCD_Divider = SLCD_Divider_16;
- uint8_t SLCD_ClockSource = 0;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
- PWR_BackupAccessCmd(ENABLE);
- switch (SLCD_ClockSource)
- {
- case 0: /* LSI */
- RCC_LSICmd(ENABLE);
- RCC_LSICLKConfig(RCC_LSICLKSource_40KHz);
- while (RESET == RCC_GetFlagStatus(RCC_FLAG_LSIRDY))
- {
- __NOP();
- }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE);
- SLCD_DeInit();
- RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSI);
- break;
- case 1: /* LSE */
- RCC_LSEConfig(RCC_LSE_ON);
- while (RESET == RCC_GetFlagStatus(RCC_FLAG_LSERDY))
- {
- __NOP();
- }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE);
- SLCD_DeInit();
- RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSE);
- break;
- case 2: /* HSI(1MHz)/DIV1 -> 1MHz */
- RCC_HSIConfig(RCC_HSI_1M);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE);
- SLCD_DeInit();
- RCC_SLCDCLKConfig(RCC_SLCDCLKSource_HSI_Div1);
- break;
- case 3: /* HSI(8MHz)/DIV8 -> 1MHz */
- RCC_HSIConfig(RCC_HSI_8M);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE);
- SLCD_DeInit();
- RCC_SLCDCLKConfig(RCC_SLCDCLKSource_HSI_Div8);
- break;
- default:
- break;
- }
- SLCD_ClockFreq = RCC_GetSlcdClockFreq();
- printf("\r\nSLCD_ClockFreq : %dHz\r\n", SLCD_ClockFreq);
- if (SLCD_ClockFreq == 0)
- {
- return;
- }
- else if (SLCD_ClockFreq == 32768UL)
- {
- SLCD_Prescaler = SLCD_Prescaler_2;
- SLCD_Divider = SLCD_Divider_16;
- }
- else if (SLCD_ClockFreq == 40000UL)
- {
- SLCD_Prescaler = SLCD_Prescaler_2;
- SLCD_Divider = SLCD_Divider_20;
- }
- else if (SLCD_ClockFreq == 1000000UL)
- {
- SLCD_Prescaler = SLCD_Prescaler_64;
- SLCD_Divider = SLCD_Divider_16;
- }
- SLCD_StructInit(&SLCD_InitStructure);
- SLCD_InitStructure.SLCD_Prescaler = SLCD_Prescaler;
- SLCD_InitStructure.SLCD_Divider = SLCD_Divider;
- SLCD_InitStructure.SLCD_Duty = SLCD_Duty_1_4;
- SLCD_InitStructure.SLCD_Bias = SLCD_Bias_1_3;
- SLCD_InitStructure.SLCD_VoltageSource = SLCD_VoltSrcCapCharggDownVdd;
- SLCD_Init(&SLCD_InitStructure);
- SLCD_ConfigureSEGoCOM();
- SLCD_ConfigureCOMnIDX();
- SLCD_ChargePumpClockDivConfig(SLCD_ChargePumpClock_Div1024);
- SLCD_LowPowerDriveCmd(DISABLE);
- SLCD_DeadTimeConfig(SLCD_DeadTime_0);
- SLCD_Cmd(ENABLE);
- SLCD_Clear(1);
- PLATFORM_DelayMS(1000);
- SLCD_Clear(0);
- SLCD_ConfigureBlinkEN();
- }
void SLCD_ConfigureSEGoCOM(void)函数是用来配置MCU引脚是作LCD功能使用的
void SLCD_ConfigureCOMnIDX(void)函数是用来配置MCU引脚作为COM功能使用的
- void SLCD_ConfigureSEGoCOM(void)
- {
- uint8_t i = 0, j = 0;
- uint8_t SLCD_IOConfigTable[MAX_SLCD_PIN_NUMBER];
- memset(SLCD_IOConfigTable, SLCD_IOConfigNone, MAX_SLCD_PIN_NUMBER);
- for (i = 0; i < MAX_SLCD_PIN_NUMBER; i++)
- {
- for (j = 0; j < SLCD_PIN_NUMBER; j++)
- {
- if ((SLCD_LineTable[i].GPIOn == SLCD_SCH[j].GPIOn) && (SLCD_LineTable[i].PINn == SLCD_SCH[j].PINn))
- {
- SLCD_IOConfigTable[i] = SLCD_SCH[j].Mode;
- SLCD_SCH[j].Line = SLCD_LineTable[i].Line;
- if (i > 31)
- {
- SLCD_SCH[j].LineGroup = 1;
- }
- else
- {
- SLCD_SCH[j].LineGroup = 0;
- }
- }
- }
- }
- SLCD_IO_Config(SLCD_IOConfigTable);
- }
- void SLCD_ConfigureCOMnIDX(void)
- {
- uint8_t i = 0, j = 0, k = 0;
- uint8_t SCLD_COM_IndexTable[COM_INDEX_MAX];
- for (i = 0; i < COM_INDEX_MAX; i++)
- {
- SCLD_COM_IndexTable[i] = 50 + i;
- }
- i = 0;
- for (j = 0; j < SLCD_PIN_NUMBER; j++)
- {
- if (SLCD_IOConfigCOM == SLCD_SCH[j].Mode)
- {
- for (k = 0; k < MAX_SLCD_PIN_NUMBER; k++)
- {
- if ((SLCD_LineTable[k].GPIOn == SLCD_SCH[j].GPIOn) && (SLCD_LineTable[k].PINn == SLCD_SCH[j].PINn))
- {
- SCLD_COM_IndexTable[i++] = k;
- }
- }
- }
- }
- SLCD_COM_IndexInit(SCLD_COM_IndexTable);
- }
这2个函数都是固定的,不需要客户修改!!
- void SLCD_ConfigureBlinkEN(void)
- {
- uint8_t SCLD_BLINK_IndexTable[COM_INDEX_MAX * BLINK_INDEX_STEP] =
- {
- 1, 0, 0, /* BLINK_Index0 is Enable, BLINK_Index0 point to COM0 and SEG0 */
- 1, 1, 1, /* BLINK_Index1 is Enable, BLINK_Index1 point to COM1 and SEG1 */
- 1, 2, 2, /* BLINK_Index2 is Enable, BLINK_Index2 point to COM2 and SEG2 */
- 1, 3, 3, /* BLINK_Index3 is Enable, BLINK_Index3 point to COM3 and SEG3 */
- 1, 4, 4, /* BLINK_Index4 is Enable, BLINK_Index4 point to COM4 and SEG4 */
- 1, 5, 5, /* BLINK_Index5 is Enable, BLINK_Index5 point to COM5 and SEG5 */
- 1, 6, 6, /* BLINK_Index6 is Enable, BLINK_Index6 point to COM6 and SEG6 */
- 1, 7, 7, /* BLINK_Index7 is Enable, BLINK_Index7 point to COM7 and SEG7 */
- };
- SLCD_BlinkConfig(SLCD_BlinkMode_Off, SLCD_BlinkFrequency_Div512);
- SLCD_BLINK_IndexInit(SCLD_BLINK_IndexTable);
- }
void SLCD_ConfigureBlinkEN(void)函数是用来配置硬件闪烁功能的,这个函数可以根据应用需示进行修改,如上所示,最多也只能配置8个段位进行闪烁,如果多余8个段位,就需要使用软件来实现闪烁功能了。
5.7.在进行上述的配置之后,我们就可以来编写应用显示功能函数了,我们拿例程中的SLCD_DisplayNumber1函数来说明:
- void SLCD_DisplayNumber1(uint8_t Index, char ch, uint8_t Point)
- {
- char TAB[4][8][4] =
- {
- { "1A ", "1B ", "1C ", "1D ", "1E ", "1F ", "1G ", "DP1" },
- { "2A ", "2B ", "2C ", "2D ", "2E ", "2F ", "2G ", "DP2" },
- { "3A ", "3B ", "3C ", "3D ", "3E ", "3F ", "3G ", "DP3" },
- { "4A ", "4B ", "4C ", "4D ", "4E ", "4F ", "4G ", " " },
- };
- uint8_t COMn = 0xFF, SEGn = 0xFF;
- uint8_t Code = SLCD_SearchCode(ch);
- uint8_t i = 0;
- if (Code != 0xFF)
- {
- for (i = 0; i < 7; i++)
- {
- SLCD_SearchName(TAB[Index][i], &COMn, &SEGn);
- if ((COMn != 0xFF) && (SEGn != 0xFF))
- {
- SLCD_WriteBit(COMn, SLCD_SCH[SEGn].Line, SLCD_SCH[SEGn].LineGroup, (Code >> i) & 0x01);
- }
- }
- SLCD_SearchName(TAB[Index][7], &COMn, &SEGn);
- if ((COMn != 0xFF) && (SEGn != 0xFF))
- {
- SLCD_WriteBit(COMn, SLCD_SCH[SEGn].Line, SLCD_SCH[SEGn].LineGroup, Point);
- }
- }
- }
我们先通过段码LCD显示屏的真值表,构建显示组,就比如我要4个小数字区域(左上角)第一个数字的位置显示字符,首先就需要定义第一个数字位置是由哪几个段位组成的,然后在代码中定义出来;然后通过SLCD_SearchCode函数获取要显示字符对应段码值,然后将这个段码值依次写入到组成这个显示区域的各个段位中,每一个段位对应的COM和SEG则是通过SLCD_SearchName函数来获取的,最后调用SLCD_WriteBit将状态写入到显示RAM中去。
我们再拿SLCD_DisplayTool函数为例:
- void SLCD_DisplayTool(void)
- {
- static uint8_t State = 0;
- char TAB[4] = "T1 ";
- uint8_t COMn = 0xFF, SEGn = 0xFF;
- SLCD_SearchName(TAB, &COMn, &SEGn);
- if ((COMn != 0xFF) && (SEGn != 0xFF))
- {
- SLCD_WriteBit(COMn, SLCD_SCH[SEGn].Line, SLCD_SCH[SEGn].LineGroup, State);
- }
- State = (State + 1) % 2;
- }
它是一个独立的段位,我们只需要通过SLCD_SearchName函数查找真值表对应的COM和SEG,然后通过SLCD_WriteBit将状态写入到显示RAM中去,即可操作这个图标的显示状态。
5.8.官方示例程序显示效果
6.基于SLCD例程设计框架,移植产品LCD,实现显示功能
我们准备了另外一块段码LCD显示屏,真值表和显示段位如下所示:
我们通过杜绑线将LCD与EVB-L0130开发板连接起来,分配如下所示:
6.1.依据段码LCD显示屏,修改如下宏定义,他们分别指示了段码LCD显示屏有几个COM口,几个SEG口:
- #define SLCD_COM_NUMBER (4)
- #define SLCD_SEG_NUMBER (8)
6.2.根据段码LCD显示屏的真值表,修改SLCD_NAME_Table数组内容:
- const char SLCD_NAME_Table[SLCD_COM_NUMBER][SLCD_SEG_NUMBER][3] =
- {
- { "1F", "1A", "2F", "2A", "3F", "3A", "4F", "4A" },
- { "1G", "1B", "2G", "2B", "3G", "3B", "4G", "4B" },
- { "1E", "1C", "2E", "2C", "3E", "3C", "4E", "4C" },
- { "P1", "1D", "P2", "2D", "P3", "3D", "P4", "4D" },
- };
6.3.根据段码LCD显示屏与MCU引脚的分配,修改SLCD_SCH数组内容:
- SLCD_IO_TypeDef SLCD_SCH[SLCD_PIN_NUMBER] =
- {
- { GPIOC, GPIO_Pin_4, 0, 0, SLCD_IOConfigSEG }, /* PC4 : LCD_SEG1 */
- { GPIOC, GPIO_Pin_5, 0, 0, SLCD_IOConfigSEG }, /* PC5 : LCD_SEG2 */
- { GPIOC, GPIO_Pin_6, 0, 0, SLCD_IOConfigSEG }, /* PC6 : LCD_SEG3 */
- { GPIOC, GPIO_Pin_7, 0, 0, SLCD_IOConfigSEG }, /* PC7 : LCD_SEG4 */
- { GPIOB, GPIO_Pin_12, 0, 0, SLCD_IOConfigSEG }, /* PB12 : LCD_SEG5 */
- { GPIOB, GPIO_Pin_13, 0, 0, SLCD_IOConfigSEG }, /* PB13 : LCD_SEG6 */
- { GPIOB, GPIO_Pin_14, 0, 0, SLCD_IOConfigSEG }, /* PB14 : LCD_SEG7 */
- { GPIOB, GPIO_Pin_15, 0, 0, SLCD_IOConfigSEG }, /* PB15 : LCD_SEG8 */
- { GPIOC, GPIO_Pin_3, 0, 0, SLCD_IOConfigCOM }, /* PC3 : LCD_COM1 */
- { GPIOC, GPIO_Pin_13, 0, 0, SLCD_IOConfigCOM }, /* PC13 : LCD_COM2 */
- { GPIOD, GPIO_Pin_4, 0, 0, SLCD_IOConfigCOM }, /* PD4 : LCD_COM3 */
- { GPIOD, GPIO_Pin_7, 0, 0, SLCD_IOConfigCOM }, /* PD7 : LCD_COM4 */
- };
6.4.根据段码LCD显示屏的功能,重构应用显示函数:
- void SLCD_DisplayNumber1(uint8_t Index, char ch, uint8_t Point)
- {
- char TAB[4][8][3] =
- {
- { "1A", "1B", "1C", "1D", "1E", "1F", "1G", "P1" },
- { "2A", "2B", "2C", "2D", "2E", "2F", "2G", "P2" },
- { "3A", "3B", "3C", "3D", "3E", "3F", "3G", "P3" },
- { "4A", "4B", "4C", "4D", "4E", "4F", "4G", "P4" },
- };
- uint8_t COMn = 0xFF, SEGn = 0xFF;
- uint8_t Code = SLCD_SearchCode(ch);
- uint8_t i = 0;
- if (Code != 0xFF)
- {
- for (i = 0; i < 7; i++)
- {
- SLCD_SearchName(TAB[Index][i], &COMn, &SEGn);
- if ((COMn != 0xFF) && (SEGn != 0xFF))
- {
- SLCD_WriteBit(COMn, SLCD_SCH[SEGn].Line, SLCD_SCH[SEGn].LineGroup, (Code >> i) & 0x01);
- }
- }
- SLCD_SearchName(TAB[Index][7], &COMn, &SEGn);
- if ((COMn != 0xFF) && (SEGn != 0xFF))
- {
- SLCD_WriteBit(COMn, SLCD_SCH[SEGn].Line, SLCD_SCH[SEGn].LineGroup, Point);
- }
- }
- }
6.5.移植后的显示效果
7.附件程序
LibSamples_MM32L0130_V0.9.3_SLCD.zip
(5.42 MB, 下载次数: 25)