| #技术资源# #申请原创# 一、 硬件连接电路
 根据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
 
 LCD.H#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偏压
 
}
 void WriteOneData_8(uint8_t Addr, uint8_t Data)#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_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位。
 
 这个在不同厂家的显示屏的时候就可以很灵活的使用。
 
 四、实物展示
 
   新手一名,如果有理解错误的地方大家多多包含并指出,感谢
 
 |