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