M-Arch(番外14)GD32L233评测-驱动段码LCD

前言

之前粗看GD32L233的资料,支持SLCD驱动,高兴的买了一块裸屏;

结果后来细看,发现CCT6不支持,裸屏不能浪费了,又买了一块天微的TM1621D驱动,自己折腾了一块SLCD板,板子其实比较简单,打板如下:

63506bbe5a5c9a942e706e5c9091cb3e.png
SLCD板

其中:

信号管脚RC参数中的R参数以及VLCD的分压电阻可直接参考手册。

如何测试裸屏

裸屏是交流信号驱动,直接用DC是不行的,得用交流测试。

用一段线缠绕在交流线上面,就可以测试了。

fc39d9e6ab73f5739a656eb0acc67cdb.png
SLCD裸屏测试
c882d3de31a2af27f3473bd7cd19a072.gif
测试结果

段码液晶的原理

cbccb11700060f68f4fe38e0b34e2037.png
SLCD参数

其中最关键的驱动条件参数,一般而言:

  • duty = 1/com的数量

  • bias = 1/(sqrt(duty)+1)

766684daa65b769e387f743c7d72dd4b.png
SLCD COM和SEG

SLCD按duty的周期执行扫描模式,所以简单的理解:

  • SEG = 地址

  • COM = 数据


假如我们需要显示第一位的数字为2,那么对应的【8】,其中:标号2,标号3,标号4,标号6,标号7会亮。

参考SEG图,我们知道:

  • SEG 9对应的是标号1,标号2,标号3,标号4共4段。

  • SEG 10对应的是标号5,标号6,标号7共3段(电池图标我们不用)。

要想把标号2,标号3,标号4,标号6,标号7点亮,那么:

  • SEG 9:COM0(标号4),COM1(标号3),COM2(标号2)为1。

  • SEG 10:COM2(标号3),COM3(标号2)为1。

就是下表:


COM0COM1COM2COM3
SEG91110
SEG100011

也就是往这两个地址写入0xE和0x3就能显示数字2。

懂了啵?!

驱动代码

一堆寄存器配置,参见芯片手册。

偷个懒,一把贴出来了。

【说明】SLCD切换的时序很短,延时直接用计数--就好。

//#define SLCD_USING_SPI

#if defined(SPI1_FOR_SLCD)

/* SPI1:PB13-SCK-SPI_SCK PB14-CE-SPI_MISO PB15-DATA-SPI_MOSI */

#define CURRENT_SPI     SPI1
#define CURRENT_SPI_RCU RCU_SPI1

#define SLCD_RCU         RCU_GPIOB
#define SLCD_GPIO        GPIOB
#define SLCD_WR_CLK_PIN  GPIO_PIN_13
#define SLCD_CS_PIN      GPIO_PIN_14
#define SLCD_DATA_PIN    GPIO_PIN_15

#ifdef SLCD_USING_SPI
#else

#define READ_MODE   gpio_init_input_mode(RTC_RCU, SLCD_GPIO, RTC_DATA_PIN);
#define WRITE_MODE  gpio_init_output_mode(RTC_RCU, SLCD_GPIO, RTC_DATA_PIN, GPIO_OSPEED_50MHZ, 0);

#define CS_HIGH     gpio_bit_set(SLCD_GPIO, SLCD_CS_PIN);
#define CS_LOW      gpio_bit_reset(SLCD_GPIO, SLCD_CS_PIN);
#define WR_CLK_HIGH gpio_bit_set(SLCD_GPIO, SLCD_WR_CLK_PIN);
#define WR_CLK_LOW  gpio_bit_reset(SLCD_GPIO, SLCD_WR_CLK_PIN);
#define DATA_HIGH   gpio_bit_set(SLCD_GPIO, SLCD_DATA_PIN);
#define DATA_LOW    gpio_bit_reset(SLCD_GPIO, SLCD_DATA_PIN);
#define DATA        gpio_input_bit_get(SLCD_GPIO, SLCD_DATA_PIN)

#endif

// SLCD命令码
#define  CTRL_CMD   0x80  //写控制命令 
#define  DATA_CMD   0xA0  //写数据命令 

#define LCD_ON     0x06  //打开LCD 1000 0000 011x 
#define LCD_OFF    0x04  //关闭LCD 1000 0000 010x 
#define SYS_EN     0x02  //系统振荡器开 1000 0000 001x
#define RC_OSC     0x30  //内部RC振荡器(上电默认256K) 1000 0011 0XXX
#define COM_BIAS   0x52  //4COM,1/3bias 1000 010 10X1X

#define SLCD_OFF        send_cmd_slcd(LCD_OFF)
#define SLCD_ON         send_cmd_slcd(LCD_ON)
#define SLCD_SYS_EN     send_cmd_slcd(SYS_EN)
#define SLCD_RC_OSC     send_cmd_slcd(RC_OSC)
#define SLCD_COM_BIAS   send_cmd_slcd(COM_BIAS)

#define DISP_0      0xD7
#define DISP_1      0x06
#define DISP_2      0xE3
#define DISP_3      0xA7
#define DISP_4      0x36
#define DISP_5      0xB5
#define DISP_6      0xF5
#define DISP_7      0x07
#define DISP_8      0xF7
#define DISP_9      0xB7
#define DISP_A      0x77
#define DISP_B      0xF7
#define DISP_b      0xF4
#define DISP_C      0xD1
#define DISP_D      0xD7
#define DISP_c      0xE0
#define DISP_d      0xE6
#define DISP_E      0xF1
#define DISP_F      0x71
#define DISP_H      0x76
#define DISP_h      0x74
#define DISP_L      0xD0
#define DISP_n      0x64
#define DISP_N      0x57
#define DISP_o      0xE4
#define DISP_P      0x73
#define DISP_r      0x60
#define DISP_t      0xF0
#define DISP_U      0xD6
#define DISP__      0x20
#define DISP_EMPTY  0x00

void spi5_init(){}

#ifdef SLCD_USING_SPI

void spi1_init()
{
}

#else

void spi1_init() {
    gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_WR_CLK_PIN,  GPIO_OSPEED_2MHZ, 0);
    gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_CS_PIN,  GPIO_OSPEED_2MHZ, 0);
    gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_DATA_PIN,  GPIO_OSPEED_50MHZ, 0);
}

static void slcd_delay(int count) {
 while (count) {
  count--;
 }
}

void send_bit_slcd(uint8_t sdat, uint8_t cnt)
{
    //data 的高cnt位写入,高位在前 
 uint8_t i; 
 for(i = 0; i < cnt; i++) 
 { 
  WR_CLK_LOW;
  slcd_delay(20);
  if(sdat&0x80)
  {
   DATA_HIGH; 
  }
  else 
  {
   DATA_LOW; 
  }
  slcd_delay(20);
  WR_CLK_HIGH;
  slcd_delay(20);
  sdat<<=1; 
 } 
 slcd_delay(20);
}

void send_cmd_slcd(uint8_t command)
{
    //发送指令 
 CS_LOW; 
 send_bit_slcd(CTRL_CMD, 4);     //写入标志码b100
 send_bit_slcd(command, 8);   //没有最高位为1的命令,直接将command的最高位写0
 CS_HIGH;
} 

void write_slcd(uint8_t addr, uint8_t sdat) 
{ 
 addr<<=2;
 CS_LOW;
 send_bit_slcd(DATA_CMD, 3);     //写入标志码b101
 send_bit_slcd(addr, 6);     //写入addr 的高6位 
 send_bit_slcd(sdat, 8);     //写入data 的8位
 CS_HIGH; 
}


void slcd_user_init(void)
{
    SLCD_OFF;
    SLCD_SYS_EN;
 SLCD_RC_OSC;    
 SLCD_COM_BIAS;
    SLCD_ON;
    slcd_display_data(DISP_0,DISP_0,DISP_0,DISP_0,DISP_0,DISP_0);delay_ms(600);
    slcd_display_data(DISP_1,DISP_1,DISP_1,DISP_1,DISP_1,DISP_1);delay_ms(600);
    slcd_display_data(DISP_2,DISP_2,DISP_2,DISP_2,DISP_2,DISP_2);delay_ms(600);
    slcd_display_data(DISP_3,DISP_3,DISP_3,DISP_3,DISP_3,DISP_3);delay_ms(600);
    slcd_display_data(DISP_4,DISP_4,DISP_4,DISP_4,DISP_4,DISP_4);delay_ms(600);
    slcd_display_data(DISP_5,DISP_5,DISP_5,DISP_5,DISP_5,DISP_5);delay_ms(600);
    slcd_display_data(DISP_6,DISP_6,DISP_6,DISP_6,DISP_6,DISP_6);delay_ms(600);
    slcd_display_data(DISP_7,DISP_7,DISP_7,DISP_7,DISP_7,DISP_7);delay_ms(600);
    slcd_display_data(DISP_8,DISP_8,DISP_8,DISP_8,DISP_8,DISP_8);delay_ms(600);
    slcd_display_data(DISP_9,DISP_9,DISP_9,DISP_9,DISP_9,DISP_9);delay_ms(600);
    slcd_display_data(DISP__,DISP__,DISP__,DISP__,DISP__,DISP__);delay_ms(600);
    slcd_display_data(DISP_H,DISP_E,DISP_L,DISP_L,DISP_0,DISP_EMPTY);
}

void slcd_display_data(uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6)
{
    uint8_t addr = 9;
    write_slcd(addr, data1);
    addr += 2;
    write_slcd(addr, data2);
    addr += 2;
    write_slcd(addr, data3);
    addr += 2;
    write_slcd(addr, data4);
    addr += 2;
    write_slcd(addr, data5);
    addr += 2;
    write_slcd(addr, data6);
    addr += 2;
}

视频

ae07862852b53e2f14f13cf3664ce9c9.gif 729cc5b805d66cc603dbb175ae86b22e.gif 1a0b08187775a86a3fe79947b554327c.png aced5effc7fd9f76de37ebbeb5b152da.gif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值