HT66F018 -- HT1621 驱动程序

/******************************************************************************

  • @file IO.C (for HT66F018)
  • @author 徐永强
  • @version V1.0
  • @date 19-Nov-2015
  • @brief This file contains the main function for IO input/output example.
    *******************************************************************************/

//======================================================================
#include “HT66F018.h”

#define u8 unsigned char
#define u16 unsigned int
#define BIT(n) (1 << n)

#define HT162X_CS _pb0
#define HT162X_WR _pa4
#define HT162X_DAT1 _pb1
#define HT162X_DAT2 _pb2

#define KEY_PIN _pa5

#define TEST_MODE _pa6

#define Bias13Com4 0x52 //0b1000 0101 0010 1/3duty 4com
#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 RC256K 0X30 //0b1000 0011 0000 内部时钟
#define TONEON 0X12 //0b1000 0001 0010 打开声音输出
#define TONEOFF 0X10 //0b1000 0001 0000 关闭声音输出
#define WDTDis 0X0A //0b1000 0000 1010 禁止看门狗
#define TimerEn 0X0C //0b1000 0000 1100 使能时基输出

#define BUFFLEN 64 //显示缓冲区长度

u8 DisplayDataTabel[BUFFLEN];

unsigned char gc_Loop;//程序while循环使用

//====================================================================
void IO_Init()
{
//设定PB0,PB1,PB2,PA4, PA5,PA6,PA7,PB3 作为IO口
_acerl = 0x00;//设定相关IO口不作为ADC输入口,缺省是ADC输入口

//设定PA3,PB6,PB5作为IO口
_csel = 0;//设定比较器引脚作为IO口,缺省是比较器引脚
_cos = 1;

//IO 口上拉设定
_papu = 0xFF;
_pbpu = 0x7F;
_pcpu = 0x07;


//设定PA为输出口,缺省为输入口
_pac = 0x00;
//设定PB为输出口,缺省为输入口
_pbc = 0x00;
//设定PC为输出口,缺省为输入口
_pcc = 0x00;

}

const u8 LcdCmd[]=
{
6,
0xE3,
0x01,
0x02,
0x18,
0x29,
0x03,
};
//-----------------------------------------------------------------------------------------
//函数名称:DelayMS()
//功 能:延时子程序
//-----------------------------------------------------------------------------------------
void DelayMS(u16 iMs)
{
u16 i,j;
for(i=0;i<iMs;i++)
for(j=0;j<100;j++)
{
_clrwdt();
_nop();
}
}
//-----------------------------------------------------------------------------------------
//函数名称:Ht1621Wr_Data()
//功 能:写数据函数,cnt为传送数据位数,数据传送为低位在前
//-----------------------------------------------------------------------------------------
void Ht162XWr_Data(u8 Data,u8 cnt,u8 chipx)
{
u8 i;
for (i=0;i<cnt;i++)
{
HT162X_WR=0;
_nop();
_nop();
_nop();
_nop();
if((Data & 0x80)==0x80)
{
if(chipx)
{
HT162X_DAT2=1;
}else{
HT162X_DAT1=1;
}
}
else
{
if(chipx)
{
HT162X_DAT2=0;
}else{
HT162X_DAT1=0;
}
}
HT162X_WR=1;
_nop();
_nop();
_nop();
_nop();
Data<<=1;
}
}

//-----------------------------------------------------------------------------------------
//函数名称:void Ht1621WrCmd(uchar Cmd)
//功能描述: HT1621命令写入函数
//参数说明:Cmd为写入命令数据
//说 明:写入命令标识位100
//-----------------------------------------------------------------------------------------
void Ht162XWrCmd(u8 Cmd,u8 chipx)
{
HT162X_CS=0;
Ht162XWr_Data(0x80,3,chipx); //写入命令标志100
Ht162XWr_Data(Cmd,8,chipx); //写入命令数据
HT162X_WR=0;
HT162X_DAT1 = 0;
HT162X_DAT2 = 0;
_nop();
_nop();
_nop();
_nop();
HT162X_WR=1;
_nop();
_nop();
_nop();
_nop();
HT162X_CS=1;
}
/----------------------------------------------------------------------------/
/**@brief 发送数据
@param
index: 将DisplayDataTabel[index]的数据传送给屏,显示
@return
@note

/
/
----------------------------------------------------------------------------*/
void Ht162XWriteData(u8 index,u8 chipx)
{
u8 temp;
u8 adder;
adder = index;
adder <<= 2;
HT162X_CS=0;
Ht162XWr_Data(0xa0,3,chipx); //写入数据标志101
Ht162XWr_Data(adder,6,chipx); //register address A5-A0 SEG0
temp = DisplayDataTabel[index] << 4;//lcd buffer low addr
Ht162XWr_Data(temp,4,chipx); //data D3~D0
HT162X_CS=1;
}

/----------------------------------------------------------------------------/
/@brief 更新显示,将DisplayDataTabel的数据更新到屏幕上
@param none
@return none
@note
DisplayDataTabel的低四位对应4个com,最高位为1就更新,否则不更新
/
/
----------------------------------------------------------------------------/
void LCDUpdate_Display(void)
{
u8 i;
for(i=0;i<BUFFLEN/2;i++)
{
if((DisplayDataTabel[i]&BIT(7))BIT(7))
{//已经写入的数据不需要再进行写入
Ht162XWriteData(i,0);
DisplayDataTabel[i] &= ~BIT(7);
}
}
for(;i<BUFFLEN;i++)
{
if((DisplayDataTabel[i]&BIT(7))BIT(7))
{//已经写入的数据不需要再进行写入
Ht162XWriteData(i,1);
DisplayDataTabel[i] &= ~BIT(7);
}
}
}
/
----------------------------------------------------------------------------*/
/
@brief 全显或者清除所有显示
@param flag:1 全显 flag:0 清除
@return
@note
/
/
----------------------------------------------------------------------------*/
void LCDDispAllAndClear(u8 flag)
{
u8 i;
for(i=0;i<BUFFLEN;i++)
{
DisplayDataTabel[i] = BIT(7);
if(flag)
{
DisplayDataTabel[i] = 0x8f;
}
}
}
//==========================================================================
void LCDDispComNumber(u8 tc_Num)
{
volatile u8 i,tempvalue,tempvalue1;

switch(tc_Num)
{
	case 0:
	   	tempvalue = 0x81;
	   	tempvalue1 = 0x80;
	   	break;
	case 1:
	   	tempvalue = 0x82;
	   	tempvalue1 = 0x80;
	   	break;
	case 2:
	   	tempvalue = 0x84;
	   	tempvalue1 = 0x80;
	   	break;
	case 3:
	   	tempvalue = 0x88;
	   	tempvalue1 = 0x80;
	   	break;
	case 4:
	   	tempvalue = 0x80;
	   	tempvalue1 = 0x81;
	   	break;
	case 5:
	   	tempvalue = 0x80;
	   	tempvalue1 = 0x82;
	   	break;
	case 6:
	   	tempvalue = 0x80;
	   	tempvalue1 = 0x84;
	   	break;
	case 7:
	   	tempvalue = 0x80;
	   	tempvalue1 = 0x88;
	   	break;
}

for(i=0;i<BUFFLEN;i=i+2)
{
	DisplayDataTabel[i] = tempvalue;
	DisplayDataTabel[i+1] = tempvalue1;
}

}

void LCDDispCom(u8 flg) //flg=0显偶数,flg=1显奇数
{
u8 i,tempvalue;

if(flg==0)
{    	
	tempvalue = 0x8A;	
}
else
{      
    tempvalue = 0x85;		
}

for(i=0;i<BUFFLEN;i++)
{
  DisplayDataTabel[i] = tempvalue;				
}

}

void LCDDispSegNumber(u8 tc_SegNumber)
{
DisplayDataTabel[tc_SegNumber] =0x8f;
}

void LCDDispSeg(u8 odd) //odd=0显示偶数的SEG,odd=1显示奇数的SEG,
{
u8 i;

for(i=odd;i<BUFFLEN;i=i+2)
{
  DisplayDataTabel[i] =0x8f;
}

}

void LCD_INITIAL()
{
u8 i;
HT162X_CS=1;
HT162X_WR=1;
HT162X_DAT1=1;
HT162X_DAT2=1;

HT162X_CS=0;
Ht162XWr_Data(0x90,4,0);          //写入命令标志1001
Ht162XWr_Data(0X10,8,0);          //写入命令数据irqen

Ht162XWr_Data(0x90,4,1);          //写入命令标志1001
Ht162XWr_Data(0X10,8,1);          //写入命令数据irqen
HT162X_CS=1;	
	
for(i = 1; i <= LcdCmd[0]; i++)
{
	Ht162XWrCmd(LcdCmd[i],0);//chip1
	Ht162XWrCmd(LcdCmd[i],1);//chip2
}
DelayMS(100);

}
//-----------------------------------------------------------------------------------------
//函数名称:DelayMS()
//功 能:延时子程序
//-----------------------------------------------------------------------------------------
void KeyDelayMS(u16 iMs)
{
u16 i;
u8 j;
for(i=0;i<iMs;i++)
for(j=0;j<250;j++)
{
_clrwdt();
_nop();
while(!KEY_PIN)
{
_clrwdt();
}
}
}
//=====================================================================================
void LCD_Send_Data(u8 index,u8 chipx,u8 tcData)
{
u8 adder;
adder = index;
adder <<= 2;
HT162X_CS=0;
Ht162XWr_Data(0xa0,3,chipx); //写入数据标志101
Ht162XWr_Data(adder,6,chipx); //register address A5-A0 SEG0
Ht162XWr_Data(tcData,4,chipx); //data D3~D0
HT162X_CS=1;
}
//=====================================================================================
const u8 gc_NumData[][2]=
{
{0x50,0xF0},//数字0
{0x50,0x00},//数字1
{0x30,0xD0},//数字2
{0x70,0x90},//数字3
{0x70,0x20},//数字4
{0x60,0xB0},//数字5
{0x60,0xF0},//数字6
{0x50,0x10},//数字7
{0x70,0xF0},//数字8
{0x70,0xB0},//数字9
};

const u8 gc_DigAddr[][3]=
{
{6,7,1},//第1个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{4,5,1},//第2个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{2,3,1},//第3个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{0,1,1},//第4个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{16,17,1},//第5个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{14,15,1},//第6个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{12,13,1},//第7个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{10,11,1},//第8个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{7,8,0},//第9个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{5,6,0},//第10个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{3,4,0},//第11个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
{1,2,0},//第12个8断码所在的seg位置(两字节) 和 位于那个芯片(一字节)
};

void LCD_Disp_DigNum(u8 tcAdr,u8 tcNum)
{
if(tcAdr)
{
tcAdr = tcAdr-1;
}
LCD_Send_Data(gc_DigAddr[tcAdr][0],gc_DigAddr[tcAdr][2],gc_NumData[tcNum][0]);
LCD_Send_Data(gc_DigAddr[tcAdr][1],gc_DigAddr[tcAdr][2],gc_NumData[tcNum][1]);
}

//=====================================================================================
void main()
{
u8 tcAdr;
u8 tcNum;

_wdtc = 0xA8;//关闭看门狗,缺省是开的,如果不清看门狗会引起复位

IO_Init();	

LCD_INITIAL();
LCDDispAllAndClear(0);//全清除,把RAM全部填0
LCDUpdate_Display();

for(tcNum=0;tcNum<10;tcNum++)
{
	for(tcAdr=1;tcAdr<13;tcAdr++)
	{
		LCD_Disp_DigNum(tcAdr,tcNum);  
	}
	_nop();
}

while(1);

if(TEST_MODE)//判断是快速测试模式,还是精细测试模式
{

  while(1)
  {
    _clrwdt(); 

      LCD_INITIAL();
      LCDDispAllAndClear(1);//全显示,把RAM全部填1
      LCDUpdate_Display();
      KeyDelayMS(500);//按键按住,可以暂停显示

      LCD_INITIAL();
      LCDDispAllAndClear(0);//全清除,把RAM全部填0
      LCDUpdate_Display();
      KeyDelayMS(500);//按键按住,可以暂停显示
      
      LCD_INITIAL();          
      LCDDispAllAndClear(0); //全清除,把RAM全部填0
      LCDDispCom(0);//显示COM0,2,4,6,...  
      LCDUpdate_Display();          
      KeyDelayMS(500); //按键按住,可以暂停显示
      
      LCD_INITIAL();
      LCDDispAllAndClear(0); 
      LCDDispCom(1);//显示COM1,3,5,7,...  
      LCDUpdate_Display();
      KeyDelayMS(500); //按键按住,可以暂停显示
      
      LCD_INITIAL();
      LCDDispAllAndClear(0); 
      LCDDispSeg(0);//显示SEG0,2,4,6,...  
      LCDUpdate_Display();
      KeyDelayMS(500); //按键按住,可以暂停显示
      
      LCD_INITIAL();         
      LCDDispAllAndClear(0); 
      LCDDispSeg(1);//显示SEG1,3,5,7,...  
      LCDUpdate_Display();
      KeyDelayMS(500);  //按键按住,可以暂停显示       
  	
  }
}else{
 	while(1)
    {
      _clrwdt(); 		
      
      LCD_INITIAL();
      LCDDispAllAndClear(1);//全显示,把RAM全部填1
      LCDUpdate_Display();
      KeyDelayMS(500);//按键按住,可以暂停显示

      LCD_INITIAL();
      LCDDispAllAndClear(0);//全清除,把RAM全部填0
      LCDUpdate_Display();
      KeyDelayMS(500);//按键按住,可以暂停显示
      
      for(tcNum=0;tcNum<8;tcNum++)
      {//每次显示一个com
          LCD_INITIAL();          
          LCDDispAllAndClear(0); //全清除,把RAM全部填0
          LCDDispComNumber(tcNum);//显示COMi
          LCDUpdate_Display();          
          KeyDelayMS(500); //按键按住,可以暂停显示
      }
      
      for(tcNum=0;tcNum<BUFFLEN;tcNum++)
      {//每次显示一个seg
          LCD_INITIAL();          
          LCDDispAllAndClear(0); //全清除,把RAM全部填0
          LCDDispSegNumber(tcNum);//显示Segi
          LCDUpdate_Display();          
          KeyDelayMS(500); //按键按住,可以暂停显示
      }
    }
}

}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值