打印

GD32控制TM1621B显示段码液晶教程

[复制链接]
15191|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bearfw|  楼主 | 2024-8-16 21:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#技术资源# #申请原创#
一、 硬件连接电路
        根据TM1621B的手册来看,硬件搭接电路很简单,只需要将CS,RD,WR,DATA分别连接MCU的引脚就行,MCU使用的是GD32F103RCT6,这里将电路图给出


(但是我在这里有个疑问,官方的手册上写的是VLCD必须比VDD,但是在实际测的时候,两个引脚的电压差不多,并没有很大的差别,不知道有没有懂得大神解释一下。)

二、液晶显示的数据原理
       这里我先贴上我的液晶显示的厂家文件

       在这里说明一下如何进行选择点亮自己想要的数据,可以看见这里有COM4,COM3,COM2,COM1这个其实是数据位,那么地址位其实就是seg,seg是按照十进制进行传输的
       就比如,(--,X3,X2,X1)这一列,首先你要先选种这个地址,再进行传输,而(--,X3,X2,X1)对应的是 1 引脚的意思,那么要进行显示的时候,就可以用这样的表示-> (0x01,0x7),相当于制冷,负号,制热都给你点亮,其他的以此类推是一样的。
       这里还可以举一个例子,比如第一个数字要表示0,他的数据位是(1D,1E,1G,1F)和(--,1C,1B,1A)那他们对应的地址即引脚是什么?对,是3脚和4脚所以可以表示为(0X03,0X0D),(0X04,0X07)。
       这里提一嘴,地址是从高位写入,数据位是从低位写入。
       这样就可以完成一个灯的点亮。

三、代码
LCD.c
#include        "gd32f10x.h"
#include         "LCD.h"
#include        "delay.h"
void LCD_GPIO_Config(void)
{               

                rcu_periph_clock_enable(RCU_GPIOB);//初始化GPIOB时钟
                rcu_periph_clock_enable(RCU_GPIOD);//初始化GPIOD时钟
                rcu_periph_clock_enable(RCU_GPIOC);//初始化GPIOD时钟
                rcu_periph_clock_enable(RCU_GPIOA);//初始化GPIOD时钟
                gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);//CS控制引脚
                gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);//RD控制引脚
                gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);//WR控制引脚
                gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);//DATA控制引脚
       
                //先默认高电平
                gpio_bit_set(GPIOD,GPIO_PIN_2);
                gpio_bit_set(GPIOA,GPIO_PIN_8);
                gpio_bit_set(GPIOC,GPIO_PIN_9);
                gpio_bit_set(GPIOB,GPIO_PIN_5);
}
/********************从高位写入数据*************************/
void Write_Data_H(uint8_t Data, uint8_t Cnt)        //Data的高cnt位写入TM1621,高位在前
{
        uint8_t i;
        for(i=0; i<Cnt; i++)
        {
                WR_OUT(0);//输出低电平
                if(Data&0x80)                                        //从最高位发送
                {
                        DATA_OUT(1);
                }
                else
                {
                        DATA_OUT(0);
                }
                        delay_1us(2);
                        WR_OUT(1);
                        Data<<=1;
                        delay_1us(2);
        }
        WR_OUT(0);
        DATA_OUT(0);
}

/********************从低位写入数据*************************/
void Write_Data_L(uint8_t Data,uint8_t Cnt)        //Data 的低cnt位写入TM1621,低位在前
{
uint8_t i;
for(i=0;i<Cnt;i++)
{
   WR_OUT(0);
   if(Data&0x01)                                //从低位发送
         {
                 DATA_OUT(1);
         }
   else
         {
    DATA_OUT(0);
         }                 
                delay_1us(2);
                WR_OUT(1);
                Data>>=1;
         delay_1us(2);
        }
WR_OUT(0);
DATA_OUT(0);
}

/********************写入控制命令*************************/
void WriteCmd(uint8_t Cmd)
{
CS_OUT(0);
delay_1us(2);
Write_Data_H(0x80,4);     //写入命令标志100
Write_Data_H(Cmd,8);      //写入命令数据
CS_OUT(1);
delay_1us(2);
}
/*********指定地址写入数据,实际写入8位************/
void WriteOneData_8(uint8_t Addr, uint8_t Data)
{
CS_OUT(0);
Write_Data_H(0xa0,3);     //写入数据标志101
Write_Data_H(Addr<<2,6);  //写入地址数据
Write_Data_L(Data,8);     //写入数据
CS_OUT(1);
delay_1us(2);
}
/*********指定地址写入数据,实际写入后4位************/
void WriteOneData_4(uint8_t Addr, uint8_t Data)
{
CS_OUT(0);
Write_Data_H(0xa0,3);     //写入数据标志101
Write_Data_H(Addr<<2,6);  //写入地址数据
Write_Data_L(Data,4);     //写入数据
CS_OUT(1);
delay_1us(2);
}
/*********连续写入方式,每次数据为8位,写入数据************/
void WriteAllData(uint8_t Addr,uint8_t *p,uint8_t cnt)
{
uint8_t i;
CS_OUT(0);
Write_Data_H(0xa0,3);      //写入数据标志101
Write_Data_H(Addr<<2,6);   //写入地址数据
for(i=0;i<cnt;i++)            //写入数据
{
   Write_Data_L(*p,8);            
   p++;
}
CS_OUT(1);
delay_1us(2);
}
/*******************TM1621初始化**********************/
void TM1621_init(void)
{
CS_OUT(1);
WR_OUT(1);
DATA_OUT(1);
delay_1us(5);
delay_1ms(1);                       
WriteCmd(BIAS1_3);                 //1/3偏压 4公共口
WriteCmd(RC_256K);                         //内部RC振荡
WriteCmd(SYS_DIS);                 //关系统振荡器和LCD偏压发生器
WriteCmd(WDT_DIS);                 //禁止看门狗
WriteCmd(SYS_EN);                 //打开系统振荡器
WriteCmd(LCD_ON);                 //开LCD偏压

}
  LCD.H
#include "gd32f10x.h"

/*
                当/CS为高电平读写TM1621B的数据和命令无效,串行接口电路复位;
                当/CS为低电平和作为输入时,读写TM1621B的数据和命令有效
*/
#define CS_OUT(a)        if(a) gpio_bit_set(GPIOD,GPIO_PIN_2); else        gpio_bit_reset(GPIOD,GPIO_PIN_2);

/*
                在/RD信号的下降沿,TM1621B内存的数据被读到DATA 线上,
                主控制器可以在下一个上升沿时锁存这些数据
*/
#define RD_OUT(a) if(a)        gpio_bit_set(GPIOA,GPIO_PIN_8); else        gpio_bit_reset(GPIOA,GPIO_PIN_8);

/*
                在/WR信号的上升沿,DATA 线上的数据写到TM1621B
*/
#define WR_OUT(a) if(a) gpio_bit_set(GPIOC,GPIO_PIN_9); else gpio_bit_reset(GPIOC,GPIO_PIN_9);

/*
                外接上拉电阻的串行数据逻辑输入/输出
*/
#define DATA_OUT(a) if(a)        gpio_bit_set(GPIOB,GPIO_PIN_5); else        gpio_bit_reset(GPIOB,GPIO_PIN_5);

#define SYS_DIS                                         0X00        //关闭系统振荡器和LCD 偏压发生器
#define SYS_EN                                                 0X02        //打开系统振荡器
#define LCD_OFF                                                0X04        //关闭LCD 偏压发生器
#define LCD_ON                                                0X06        //打开LCD 偏压发生器
#define TIMER_DIS                                 0X08        //时基输出失效
#define WDT_DIS                                         0X0A        //WDT溢出标志输出失效
#define TIMER_EN                                        0X0C        //时基输出使能
#define WDT_EN                                                0X0E        //WDT 溢出标志输出有效
#define TONE_OFF                                         0X10        //关闭声音输出
#define TONE_ON                                                 0X12        //打开声音输出
#define CLR_TIMER                                        0X18        //时基发生器清零
#define CLR_WDT                                                0X1C        //清除WDT 状态
#define XTAL_32K                                        0X28        //系统时钟源晶振
#define RC_256K                                                0X30        //系统时钟源片内RC振荡器
#define EXT_256K                                        0X38        //系统时钟源外部时钟源
#define BIAS1_2                                         0X50        //1/2的偏压四个公共口
#define        BIAS1_3                                                0X52        //1/3的偏压4个公共口
#define TONE_4K                                                0X80        //声音频率4KHz
#define TONE_2K                                                0XC0        //声音频率2KHz
#define IRQ_DIS                                                0X20        //使/IRQ 输出失效
#define IRQ_EN                                                0X30        //使/IRQ 输出有效
#define F1                                                                0X40        //时基时钟输出1Hz,WDT计时标志产生时间:4S
#define F2                                                                0X42        //时基时钟输出2Hz,WDT计时标志产生时间:2S
#define F4                                                                0X44        //时基时钟输出4Hz,WDT计时标志产生时间:1S
#define F8                                                                0X46        //时基时钟输出8Hz,WDT计时标志产生时间:1/2S
#define F16                                                                0X48        //时基时钟输出16Hz,WDT计时标志产生时间:1/4S
#define F32                                                                0X4A        //时基时钟输出32Hz,WDT计时标志产生时间:1/8S
#define F64                                                                0X4C        //时基时钟输出64Hz,WDT计时标志产生时间:1/16S
#define F128                                                        0X4E        //时基时钟输出128Hz,WDT计时标志产生时间:1/32S
#define TOPT                                                        0XC0        //测试模式
#define TNORMAL                                                0XC6        //普通模式



void LCD_GPIO_Config(void);
void Write_Data_H(uint8_t Data, uint8_t Cnt);
void Write_Data_L(uint8_t Data,uint8_t Cnt);
void WriteCmd(uint8_t Cmd);
void WriteOneData_8(uint8_t Addr, uint8_t Data);
void WriteAllData(uint8_t Addr,uint8_t *p,uint8_t cnt);
void TM1621_init(void);
void WriteOneData_4(uint8_t Addr, uint8_t Data);

void WriteOneData_8(uint8_t Addr, uint8_t Data)
        void WriteOneData_4(uint8_t Addr, uint8_t Data)
        这里主要说一下这两个函数,
        第一个函数void WriteOneData_8(uint8_t Addr, uint8_t Data)
        在你写入地址的时候,他会将后一位地址也写入,数据也会多读4位
        如WriteOneData_8(0x03,0x77);就相当于他一次性写入了(0x03,0x07)和(0x04,0x07);的意思

        第二个函数void WriteOneData_4(uint8_t Addr, uint8_t Data)
        在你写入一个地址就对一个数据,如WriteOneData_4(0x03,0x77);
        就会变成(0x03,0x07);不会顺延地址,也不会写入高4位。

        这个在不同厂家的显示屏的时候就可以很灵活的使用。

四、实物展示

新手一名,如果有理解错误的地方大家多多包含并指出,感谢

使用特权

评论回复
评论
21小跑堂 2024-9-12 14:31 回复TA
感谢大佬分享,21家的原创奖励需文章字数至少800,您可以继续填充内容哦~ 
沙发
王派oo| | 2024-9-30 13:31 | 只看该作者
如果VLCD电压过低,液晶显示可能会出现异常或不稳定的情况。

使用特权

评论回复
板凳
而服务器人| | 2024-9-30 13:40 | 只看该作者
关于VLCD和VDD的电压关系,TM1621B的手册建议VLCD应高于VDD,这是为了确保液晶显示能够正常工作。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

15

帖子

0

粉丝