1 、前言
今日翻开电子器件箱,偶然发现以前邮购的HT1621驱动的6位液晶显示的段码屏,该屏只有三个信号线,当时用51单片机驱动显示正常,决定用申请的南京中科微的CSM32RV003开发板试试能否成功。
2、HT1621 驱动程序文件: HT1621.h
段码屏正面右侧共****6 个引脚,自上而下依次是: 1/CS 、 2/WR 、 3/Data 、 4/GND 、 5/VCC(+5V) 、 6/LED+( 背光正极 ) 。
实验电路:黑色的粗USB线引出****4 根线:绿线接 +5V ,白线接地。 6管数字段码屏用USB供电,一根绿线连5脚驱动供电,一根连6脚LED背光,一条白色线接4脚,另一条白色线接CSM32RV003 开发板的地,实现两块电路板的共地。 CSM32RV003****开发板的 PA0 (黑线)、 PA2 (白线)、 PA3 (灰线)分别与段码屏的 1/CS 、 2/WR 、 3/Data****相连。
HT1621驱动程序根据适合51单片机的驱动程序修改,采用HT1621****驱动的其它段码屏可以参考此程序修改。
//采用CSM32RV003单片机的6位数码管段码液晶屏驱动程序 HT1621.h
//该段码液晶屏地址从最右边一位开始,共12个地址,每个数字占2个地址
#include "headfile.h"
// - - 定义接口
#define HT1621_CS_PIN0 PIN0 // - - HT1621使能,引脚1
#define HT1621_WR_PIN2 PIN2 // - - HT1621时钟,引脚2
#define HT1621_DAT_PIN3 PIN3 // - - HT1621数据,引脚3
#define BIAS 0x52 //0b1000 0101 0010 1/3偏压 4公共口
#define SYSDIS 0X00 //0b1000 0000 0000 关振系统荡器和LCD偏压发生器
#define SYSEN 0X02 //0b1000 0000 0010 打开系统振荡器
#define LCDOFF 0X04 //0b1000 0000 0100 关LCD偏压
#define LCDON 0X06 //0b1000 0000 0110 打开LCD偏压
#define XTAL 0x28 //0b1000 0010 1000 外部接时钟
#define RC256 0X30 //0b1000 0011 0000 内部时钟
#define TONEON 0X12 //0b1000 0001 0010 打开声音输出
#define TONEOFF 0X10 //0b1000 0001 0000 关闭声音输出
#define WDTDIS 0X0A //0b1000 0000 1010 禁止看门狗
// - - 定义子程序函数
void Ht1621_Init(void); // - - 初始化 HT1621
void Ht1621Wr_Data(uint8_t Data,uint8_t cnt); // - - HT1621 写入数据函数
void Ht1621WrCmd(uint8_t Cmd); // - - HT1621 写入命令函数
void Ht1621WrOneData(uint8_t Addr,uint8_t Data); // - - HT1621 在指定地址写入数据函数
void Ht1621WrAllData(uint8_t Addr,uint8_t *p,uint8_t cnt); // - - HT1621 连续写入数据函数
uint8_t dat_buf(uint8_t dat); //数字转段码子函数
/********************************************************
函数名称:void Ht1621_Init(void)
功能描述: HT1621初始化
全局变量:无
参数说明:无
返回说明:无
版 本:1.0
说 明:初始化后,液晶屏所有字段均显示
********************************************************/
void Ht1621_Init(void)
{
GPIO_MODE_Init(GPIOA,HT1621_CS_PIN0,GPIO_MODE_OUTPUT); //GPIO 模式
GPIO_MODE_Init(GPIOA,HT1621_WR_PIN2,GPIO_MODE_OUTPUT); //GPIO 模式
GPIO_MODE_Init(GPIOA,HT1621_DAT_PIN3,GPIO_MODE_OUTPUT); //GPIO 模式
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_SET); //GPIO 输出
GPIO_Write(GPIOA,HT1621_WR_PIN2,GPIO_SET); //GPIO 输出
GPIO_Write(GPIOA,HT1621_DAT_PIN3,GPIO_SET); //GPIO 输出
Delay32M_ms(2500); // - - 延时使LCD工作电压稳定
Ht1621WrCmd(BIAS); //-- 1/3偏压 4公共口
Ht1621WrCmd(RC256); // - - 使用内部振荡器
Ht1621WrCmd(SYSDIS); // - - 关振系统荡器和LCD偏压发生器
Ht1621WrCmd(WDTDIS); // - - 禁止看门狗
Ht1621WrCmd(SYSEN); // - - 打开系统振荡器
Ht1621WrCmd(LCDON); // - - 打开声音输出
}
/******************************************************
函数名称:void Ht1621Wr_Data(INT8UData,INT8Ucnt)
功能描述: HT1621数据写入函数
全局变量:无
参数说明:Data为数据,cnt为数据位数
返回说明:无
说 明:写数据函数,cnt为传送数据位数,数据传送为低位在前
*******************************************************/
void Ht1621Wr_Data(uint8_t Data,uint8_t cnt)
{
uint8_t i;
for (i = 0;i < cnt;i++)
{
GPIO_Write(GPIOA,HT1621_WR_PIN2,GPIO_RESET); //
Delay32M_us(10);
if(Data&0x80)
GPIO_Write(GPIOA,HT1621_DAT_PIN3,GPIO_SET); //
else
GPIO_Write(GPIOA,HT1621_DAT_PIN3,GPIO_RESET);
Delay32M_us(10);
GPIO_Write(GPIOA,HT1621_WR_PIN2,GPIO_SET); //
Delay32M_us(10);
Data <<= 1;
}
}
/********************************************************
函数名称:void Ht1621WrCmd(INT8UCmd)
功能描述: HT1621命令写入函数
全局变量:无
参数说明:Cmd为写入命令数据
返回说明:无
说 明:写入命令标识位100
********************************************************/
void Ht1621WrCmd(uint8_t Cmd)
{
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_RESET); //
Delay32M_us(10);
Ht1621Wr_Data(0x80,4); // - - 写入命令标志100
Ht1621Wr_Data(Cmd,8); // - - 写入命令数据
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_SET); //
Delay32M_us(10);
}
/********************************************************
函数名称:void Ht1621WrOneData(INT8UAddr,INT8UData)
功能描述: HT1621在指定地址写入数据函数
全局变量:无
参数说明:Addr为写入初始地址,Data为写入数据
返回说明:无
说 明:因为HT1621的数据位4位,所以实际写入数据为参数的后4位
********************************************************/
void Ht1621WrOneData(uint8_t Addr,uint8_t Data)
{
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_RESET); //
Ht1621Wr_Data(0xa0,3); // - - 写入数据标志101
Ht1621Wr_Data(Addr << 2,6); // - - 写入地址数据
Ht1621Wr_Data(Data << 4,4); // - - 写入数据
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_SET); //
Delay32M_us(10);
}
/********************************************************
函数名称:void Ht1621WrAllData(uint8_t Addr,uint8_t*p,uint8_t cnt)
功能描述: HT1621连续写入方式函数
全局变量:无
参数说明:Addr为写入初始地址,*p为连续写入数据指针,
cnt为写入数据总数
返回说明:无
说 明:HT1621的数据位4位,此处每次数据为8位,写入数据
总数按8位计算
********************************************************/
void Ht1621WrAllData(uint8_t Addr,uint8_t *p,uint8_t cnt)
{
uint8_t i;
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_RESET); //
Ht1621Wr_Data(0xa0,3); // - - 写入数据标志101
Ht1621Wr_Data(Addr << 2,6); // - - 写入地址数据
for (i = 0;i < cnt;i++)
{
Ht1621Wr_Data(*p,8); // - - 写入数据
p++;
}
GPIO_Write(GPIOA,HT1621_CS_PIN0,GPIO_SET); //
Delay32M_us(10);
}
/********************************************************
函数名称:uint8_t dat_buf(uint8_t dat)
功能描述: 把1位数码管的数字的各个段码和转为16进制数
参数说明:dat要显示的数字
返回说明: dpgfe为高4位的和,dcba为低4位的和,返回二者进行或运算的结果
********************************************************/
uint8_t dat_buf(uint8_t dat)
{ //邮购的6位数码管液晶屏,经测试低地址的8对应该位数码管左侧的小数点
//可以再编写一个类似的点亮点的函数
//a=1,b=2,c=4,d=8,e=4,f=1,g=2
uint8_t temp,dp, g,f,e,d,c,b,a; //数码管的段 dp gfedcba
switch(dat)
{ //显示数字0~9时各段的值,最高位dp=0
case 0 : dp=0;g=0;f=1;e=4;d=8;c=4;b=2;a=1;break;
case 1 : dp=0;g=0;f=0;e=0;d=0;c=4;b=2;a=0;break;
case 2 : dp=0;g=2;f=0;e=4;d=8;c=0;b=2;a=1;break;
case 3 : dp=0;g=2;f=0;e=0;d=8;c=4;b=2;a=1;break;
case 4 : dp=0;g=2;f=1;e=0;d=0;c=4;b=2;a=0;break;
case 5 : dp=0;g=2;f=1;e=0;d=8;c=4;b=0;a=1;break;
case 6 : dp=0;g=2;f=1;e=4;d=8;c=4;b=0;a=1;break;
case 7 : dp=0;g=0;f=0;e=0;d=0;c=4;b=2;a=1;break;
case 8 : dp=0;g=2;f=1;e=4;d=8;c=4;b=2;a=1;break;
case 9 : dp=0;g=2;f=1;e=0;d=8;c=2;b=2;a=1;break;
default :break;
} //分别取高4位的段码和、低4位的段码和并转为BCD码
temp = (( g + f + e + d) << 4) | (c + b + a);
return temp; //返回每个数码管显示数字对应的段码的BCD码
}
2、主程序文件:main.c
#include "headfile.h"
#include "HT1621.h"
uint8_t Ht1621Tab[12];
uint8_t DateTime[ ]={56,45,10};
void display(void);
void display(void)
{
uint8_t h1,h2,m1,m2,s1,s2;
h1 = dat_buf(DateTime[2] / 10);
h2 = dat_buf(DateTime[2] % 10);
m1 = dat_buf(DateTime[1] / 10);
m2 = dat_buf(DateTime[1] % 10);
s1 = dat_buf(DateTime[0] / 10);
s2 = dat_buf(DateTime[0] % 10);
Ht1621WrOneData(0x0b,h1 >> 4 );
Ht1621WrOneData(0x0a,h1 & 0x0f );
Ht1621WrOneData(0x09,h2 >> 4 );
Ht1621WrOneData(0x08,h2 & 0x0f );
Ht1621WrOneData(0x07,m1 >> 4 );
Ht1621WrOneData(0x06,m1 & 0x0f );
Ht1621WrOneData(0x05,m2 >> 4 );
Ht1621WrOneData(0x04,m2 & 0x0f );
Ht1621WrOneData(0x03,s1 >> 4 );
Ht1621WrOneData(0x02,s1 & 0x0f );
Ht1621WrOneData(0x01,s2 >> 4 );
Ht1621WrOneData(0x00,s2 & 0x0f );
}
#define SFT ((SFT_TypeDef *)SFT_BASE)
#define SFT_BASE 0x30000360UL
volatile uint32_t NRST_EN;
#define LED_B_PA8 PIN8
#define LED_G_PA9 PIN9
#define LED_R_PA12 PIN12
#define KEY_PA3 PIN3
void Timer1_Update_IRQhandler(void) __attribute__((interrupt("SiFive-CLIC-preemptible")));
void Timer1_Update_IRQhandler(void)
{
Timer1_Update_Isr();
}
void Timer1_Update_Isr(void)
{
if(TIMER1->SR&0x1)
{
TIMER1->SR &= ~0x1;
GPIO_Toggle(GPIOA,LED_R_PA12 );
display( ) ;
}
}
int main(void)
{
typedef struct
{
volatile uint32_t EN;
volatile uint32_t NRST_EN;
}SFT_TypeDef;
SFT->NRST_EN=0;
GPIO_MODE_Init(GPIOA,LED_B_PA8,GPIO_MODE_OUTPUT);
GPIO_MODE_Init(GPIOA,LED_G_PA9 ,GPIO_MODE_OUTPUT);
GPIO_MODE_Init(GPIOA,LED_R_PA12,GPIO_MODE_OUTPUT);
GPIO_Write(GPIOA, LED_G_PA9,GPIO_RESET);
GPIO_Write(GPIOA, LED_B_PA8 ,GPIO_RESET);
GPIO_Write(GPIOA, LED_R_PA12,GPIO_RESET);
Delay32M_ms(2000);
GPIO_Write(GPIOA, LED_B_PA8 ,GPIO_SET);
GPIO_Write(GPIOA,LED_G_PA9,1);
GPIO_Write(GPIOA,LED_R_PA12,1);
GPIO_InType_Init( GPIOA, KEY_PA3,GPIO_MODE_INPUT);
GPIO_PULL_Init(GPIOA, KEY_PA3, GPIO_PULLDOWN);
GPIO_MODE_Init(GPIOA, PIN12,GPIO_MODE_OUTPUT);
GPIO_Write(GPIOA, PIN12,GPIO_SET);
Ht1621_Init( );
Ht1621WrAllData(0,Ht1621Tab ,12);
for (uint8_t i = 0;i < 12;i+=2)
{
Ht1621WrOneData(0x0+i,1 );
Delay32M_ms(500);
Ht1621WrOneData(0x0+i,3 );
Delay32M_ms(500);
Ht1621WrOneData(0x0+i,7 );
Delay32M_ms(500);
Ht1621WrOneData(0x0+i,15 );
Delay32M_ms(500);
Ht1621WrOneData(0x01+i,1 );
Delay32M_ms(500);
Ht1621WrOneData(0x01+i,3 );
Delay32M_ms(500);
Ht1621WrOneData(0x01+i,7 );
Delay32M_ms(500);
Ht1621WrOneData(0x01+i,15 );
Delay32M_ms(500);
}
Ht1621WrAllData(0,Ht1621Tab ,12);
CLIC_Init();
SysClock_Test_Init();
Timer1_UpCounting_Mode_Init( );
Interrupt_Level(TIMER1_updata_int_ID,INT_LEVEL0);
Interrupt_Enable(TIMER1_updata_int_ID);
SYS_Interrupt_Enable( );
while(1);
return 0;
}
*附件:MCS003_timer1.rar