|
/********************************************************************************
;* 標(biāo)題: TOPAV-2008單片機(jī)開發(fā)系統(tǒng)演示程序 *
;* 硬件: TOPAV-2008 *
;* 文件: MA016.C *
;* 日期: 2007-5-1 *
;* 版本: 1.0 *
;* 作者: 單片機(jī)音響技術(shù)網(wǎng) - zhangshaobin *
;********************************************************************************
;* 描述: *
;* PT6312VFD屏演示(頻譜花式,HELLO字符顯示,按鍵掃描) *
;* *
;********************************************************************************
;* 跳線設(shè)置: *
;* 矩陣鍵盤上方跳線組(短接STB,CLK,DATA) *
;* 安裝好6312VFD模塊(注意絲印對應(yīng)且全部腳插入)VFD為真空玻璃注意愛護(hù) *
;* 特別注意保護(hù)VFD屏左邊真空抽氣孔(小凸起部分不可破裂 *
;********************************************************************************
;* 【版權(quán)】 Copyright(C)單片機(jī)音響技術(shù)網(wǎng)All Rights Reserved *
;* 【聲明】 此程序僅用于學(xué)習(xí)與參考,引用請注明版權(quán)和作者信息! *
;*******************************************************************************/
//來,一起玩轉(zhuǎn)VFD屏及PT6312驅(qū)動
#include "reg51.h"
typedef bit BIT;
typedef unsigned char BYTE;
typedef unsigned int WORD;
sbit PT6312_STB = P2^3;
sbit PT6312_CLK = P2^4;
sbit PT6312_DATA = P2^5;
BYTE DISP_ARRAY[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
//BYTE code DISP_CHAR1[] = {4,192,55,118,91,58}; //TUNER
BYTE code DISP_CHAR1[] = {1,62,91,19,19,119}; //HELLO
//BYTE code DISP_CHAR1[] = {4,0,125,127,93,247}; //98.50
BYTE code DISP_KEY01[] = {0,0,119,119,119,36};
BYTE code DISP_KEY02[] = {0,0,119,119,119,107};
BYTE code DISP_KEY03[] = {0,0,119,119,119,109};
BYTE code DISP_KEY04[] = {0,0,119,119,119,60};
BYTE code DISP_KEY05[] = {0,0,119,119,119,93};
BYTE code DISP_KEY06[] = {0,0,119,119,119,95};
BYTE code DISP_KEY07[] = {0,0,119,119,119,100};
BYTE code DISP_KEY08[] = {0,0,119,119,119,127};
BYTE code DISP_KEY09[] = {0,0,119,119,119,125};
BYTE code DISP_KEY10[] = {0,0,119,119,36,119};
BYTE code DISP_KEY11[] = {0,0,119,119,36,36};
BYTE code DISP_KEY12[] = {0,0,119,119,36,107};
BIT NEW_KEY_FLAG=0;
BIT OLD_KEY_FLAG=0;
BYTE bKEY;
BYTE oldKEY;
BYTE code DISP_FREQ1[] = {1,3,7,15,31,63,127,255}; //頻譜上升
BYTE code DISP_FREQ2[] = {1,2,4,8,16,32,64,128}; //頻譜下降
BYTE code DISP_FREQ3[] = {128,192,224,240,248,252,254,255}; //頻譜中間跳動
BYTE SEC_TIME;
BYTE DISC_RUN_TIME;
BYTE FREQ_TIME;
BYTE FREQ_SEC_TIME;
BYTE FREQ_ST_TIME;
BYTE FREQ_RANGE[4]; //手動設(shè)置的頻譜,沒有音頻取樣,假頻譜... :)
BYTE KEY_BUF[3];
#define VFD_DISP_MODE 0x02 // 設(shè)置段位為 6d/16s
#define VFD_DIM_QUANTITY 0x8f //占空比14/16,顯示為開
#define VFD_DATWR_MODE 0x40 //正常寫入后地址加1
#define VFD_ADDSET_COMD 0xC0 //PT6312片內(nèi)RAM從OOH~15H,6段使用00H~0BH共12BYTE每段16BIT兩個RAM
#define VFD_SPH 0x00
#define MS20H 0xb1 //定時(shí)器0初值
#define MS20L 0xe0 //12M 20MS;45536=B1E0H 65536-45536=20000US=20MS
void Write_A_ByteTo_VFD(BYTE); //一些函數(shù)聲明,如果帶行參變量,編譯器會忽略
void Init_vfd();
void Light_all_Write();
void Write_GID6(BYTE *);
BYTE RD_A_Bytefrom_VFD();
void KEY_Scan_Save();
BYTE Get_KEYVAL();
void KEY_Process();
void disp_Chag_disc();
void Write_GID4(BYTE *,BYTE *);
void freqrange_to_disp();
void disp_Chag_freq(); //以上函數(shù)做了申明,主程序可以寫在最前面
void main()
{
TMOD = 0x11; //TMOD = 0x01,定時(shí)器0方式設(shè)置
IE = 0X82; //開總中斷允許,開定時(shí)器0允許
Init_vfd(); //DISP_ARRAY數(shù)組初始化全部為0所以顯示無內(nèi)容,只是設(shè)置了段位,允許VFD顯示
TH0 = MS20H; //定時(shí)器初值設(shè)定
TL0 = MS20L;
TR0 = 1; //開定時(shí)器0
Write_GID6(&DISP_CHAR1); //顯示HELLO
while(1)
{
disp_Chag_freq(); //調(diào)用頻譜條變化
disp_Chag_disc(); //調(diào)用DVD轉(zhuǎn)盤旋轉(zhuǎn)
KEY_Process(); //按鍵按下顯示按鍵值
Light_all_Write(); //PT6312數(shù)據(jù)更新
}
}
/*************************************************************************************************/
void Init_vfd() //PT6312初始化
{
PT6312_STB = 1;
PT6312_STB = 0;
Write_A_ByteTo_VFD(VFD_DISP_MODE); //0x02 6d/16s根據(jù)顯示VFD的段位設(shè)置
PT6312_STB = 1;
PT6312_STB = 0;
Write_A_ByteTo_VFD(0x8f); //占空比14/16,顯示為開
PT6312_STB = 1;
Light_all_Write(); //寫入所有數(shù)據(jù)到PT6312
}
void Write_A_ByteTo_VFD(BYTE vfd_data) //寫一個字節(jié)數(shù)據(jù)到PT6312
{
BYTE wr_temp;
PT6312_CLK = 1;
for(wr_temp = 0;wr_temp < 8;wr_temp++)
{
PT6312_CLK = 0;
if (vfd_data & 0x01)
PT6312_DATA = 1;
else
PT6312_DATA = 0;
vfd_data >>= 1;
PT6312_CLK = 1;
}
}
void KEY_Process(void)
{
KEY_Scan_Save();
bKEY = Get_KEYVAL();
oldKEY = bKEY;
if ((bKEY == oldKEY) && (FREQ_SEC_TIME == 0))
Write_GID6(&DISP_CHAR1);
switch(bKEY)
{
case 1:
Write_GID6(&DISP_KEY01);
break;
case 2:
Write_GID6(&DISP_KEY02);
break;
case 3:
Write_GID6(&DISP_KEY03);
break;
case 4:
Write_GID6(&DISP_KEY04);
break;
case 5:
Write_GID6(&DISP_KEY05);
break;
case 6:
Write_GID6(&DISP_KEY06);
break;
case 7:
Write_GID6(&DISP_KEY07);
break;
case 8:
Write_GID6(&DISP_KEY08);
break;
case 9:
Write_GID6(&DISP_KEY09);
break;
case 10:
Write_GID6(&DISP_KEY10);
break;
case 11:
Write_GID6(&DISP_KEY11);
break;
case 12:
Write_GID6(&DISP_KEY12);
break;
// default:
// Write_GID6(&DISP_CHAR1);
// break;
}
}
BYTE Get_KEYVAL(void)
{
BYTE keyval;
if (KEY_BUF[0])
{
while (KEY_BUF[0]) //按鍵在KEY_BUF[0],如: 0001 0000,keyval == 5
{
keyval++;
KEY_BUF[0] >>= 1;
};
};
if (KEY_BUF[1])
{
keyval = 8;
while (KEY_BUF[1]) //按鍵在KEY_BUF[1],如: 0001 0000,keyval == 13
{
keyval++;
KEY_BUF[1] >>= 1;
};
};
if (KEY_BUF[2])
{
keyval = 16;
while (KEY_BUF[2]) //按鍵在KEY_BUF[2],如: 0000 1000,keyval == 20
{
keyval++;
KEY_BUF[2] >>= 1;
};
};
return(keyval);
}
void KEY_Scan_Save(void)
{
BYTE keybuf_number;
PT6312_STB = 0;
Write_A_ByteTo_VFD(0x76);
for (keybuf_number = 0 ;keybuf_number < 3;keybuf_number++)
{
KEY_BUF[keybuf_number] = RD_A_Bytefrom_VFD() ;
}
PT6312_STB = 1;
}
BYTE RD_A_Bytefrom_VFD(void)
{
BIT rd_temp_flag;
BYTE key_data;
BYTE rd_temp,rd_temp_keydata;
PT6312_CLK = 1;
PT6312_DATA = 1;
key_data = 0;
for(rd_temp = 0;rd_temp < 8;rd_temp++)
{
PT6312_CLK = 0;
rd_temp_flag = PT6312_DATA;
if (rd_temp_flag)
{
rd_temp_keydata = 0x80;
rd_temp_keydata >>= (7-rd_temp);
key_data |= rd_temp_keydata;
}
PT6312_CLK = 1;
}
return(key_data);
}
void Light_all_Write(void) //顯示數(shù)據(jù)暫存數(shù)組的所有要顯示的內(nèi)容寫入到PT6312
{
BYTE fill_temp;
PT6312_STB = 1;
PT6312_STB = 0;
Write_A_ByteTo_VFD(0x40); //數(shù)據(jù)寫入到PT6312后其內(nèi)部地址自動+1
PT6312_STB = 1;
for (fill_temp=0;fill_temp<12;fill_temp++)
{
PT6312_STB = 0;
Write_A_ByteTo_VFD(0xC0+(11-fill_temp));
Write_A_ByteTo_VFD(DISP_ARRAY[fill_temp]); //暫存顯示數(shù)據(jù)的數(shù)組和PT6312內(nèi)部地址一一對應(yīng)
PT6312_STB = 1;
}
}
/*************************************************************************************************/
void Write_GID6(BYTE *charp)
{
BYTE char_temp;
for( char_temp = 2;char_temp < 8;char_temp++) //DISP_ARRAY數(shù)組DISP_ARRAY[2]~DISP_ARRAY[7]主顯示內(nèi)容更新
{
DISP_ARRAY[char_temp] = *charp;
charp++; //指針++指象實(shí)參數(shù)組下一個元素
}
}
/*************************************************************************************************/
void disp_Chag_disc() //DISC圖標(biāo)動畫
{
DISP_ARRAY[0] = 0x50; //點(diǎn)亮其他一些圖標(biāo)"ALL","播放"
switch(DISC_RUN_TIME)
{
case 0:
{
DISP_ARRAY[1] = 0x5f; //01011111 //圖標(biāo)可以單獨(dú)給個位變量來"與"&
break;
}
case 1:
{
DISP_ARRAY[1] = 0x6f;
break;
}
case 2:
{
DISP_ARRAY[1] = 0x77;
break;
}
case 3:
{
DISP_ARRAY[1] = 0x7b;
break;
}
case 4:
{
DISP_ARRAY[1] = 0x7d;
break;
}
case 5:
{
DISP_ARRAY[1] = 0x7e;
break;
}
}
}
/*************************************************************************************************/
void freqrange_to_disp() //顯示頻譜
{
switch(FREQ_TIME) //模擬的一些頻譜幅度,后續(xù)根據(jù)這個幅度取DISP_FREQ1~3數(shù)組的值
//如果有動態(tài)的音頻取樣只需要取樣值變化再取顯示點(diǎn)亮的格數(shù)值
{
case 0:
{
FREQ_RANGE[0] = 2;
FREQ_RANGE[1] = 4;
FREQ_RANGE[2] = 1;
FREQ_RANGE[3] = 1;
break;
}
case 1:
{
FREQ_RANGE[0] = 1;
FREQ_RANGE[1] = 6;
FREQ_RANGE[2] = 1;
FREQ_RANGE[3] = 2;
break;
}
case 2:
{
FREQ_RANGE[0] = 4;
FREQ_RANGE[1] = 7;
FREQ_RANGE[2] = 3;
FREQ_RANGE[3] = 4;
break;
}
case 3:
{
FREQ_RANGE[0] = 3;
FREQ_RANGE[1] = 4;
FREQ_RANGE[2] = 5;
FREQ_RANGE[3] = 2;
break;
}
case 4:
{
FREQ_RANGE[0] = 6;
FREQ_RANGE[1] = 5;
FREQ_RANGE[2] = 7;
FREQ_RANGE[3] = 5;
break;
}
case 5:
{
FREQ_RANGE[0] = 6;
FREQ_RANGE[1] = 1;
FREQ_RANGE[2] = 3;
FREQ_RANGE[3] = 1;
break;
}
case 6:
{
FREQ_RANGE[0] = 3;
FREQ_RANGE[1] = 2;
FREQ_RANGE[2] = 1;
FREQ_RANGE[3] = 2;
break;
}
case 7:
{
FREQ_RANGE[0] = 7;
FREQ_RANGE[1] = 6;
FREQ_RANGE[2] = 4;
FREQ_RANGE[3] = 3;
break;
}
case 8:
{
FREQ_RANGE[0] = 2;
FREQ_RANGE[1] = 4;
FREQ_RANGE[2] = 5;
FREQ_RANGE[3] = 1;
break;
}
case 9: //十種變化
{
FREQ_RANGE[0] = 5;
FREQ_RANGE[1] = 7;
FREQ_RANGE[2] = 6;
FREQ_RANGE[3] = 7;
break;
}
}
}
void disp_Chag_freq()
{
freqrange_to_disp();
switch(FREQ_ST_TIME)
{
case 0:
{
Write_GID4(&DISP_FREQ1,&FREQ_RANGE);
break;
}
case 1:
{
Write_GID4(&DISP_FREQ2,&FREQ_RANGE);
break;
}
case 2:
{
Write_GID4(&DISP_FREQ3,&FREQ_RANGE);
break;
}
default:
Write_GID4(&DISP_FREQ1,&FREQ_RANGE);
}
}
void Write_GID4(BYTE *freqp,BYTE *freqrp) //兩個指針的應(yīng)用
{
BYTE freq_temp;
for( freq_temp = 8;freq_temp < 12;freq_temp++)
{
DISP_ARRAY[freq_temp] = freqp[*freqrp];
freqrp++;
}
}
/*************************************************************************************************/
void TR0_Service(void) interrupt 1 using 2 //TR0的定時(shí)中斷函數(shù),此函數(shù)應(yīng)簡單。使用寄存器組2
{
TH0 = MS20H; //重點(diǎn)掌握此定時(shí)方式可任意定時(shí)
TL0 = MS20L;
if(!SEC_TIME) //基準(zhǔn)時(shí)間5X20MS = 100ms
{
DISC_RUN_TIME++;
if( DISC_RUN_TIME == 6) //DVD轉(zhuǎn)盤旋轉(zhuǎn)一圈需要6種狀態(tài)改變,DISC_RUN_TIME變化就改變一下狀態(tài)
DISC_RUN_TIME = 0;
SEC_TIME = 5;
if(!FREQ_TIME)
{
FREQ_TIME = 10; //根據(jù)FREQ_TIME值可更新10種頻譜幅度每100MS變化一次
if(!FREQ_SEC_TIME)
{
FREQ_SEC_TIME = 15; //15s //15s基準(zhǔn)
if(!FREQ_ST_TIME) //FREQ_ST_TIME賦值則可根據(jù)FREQ_ST_TIME值每15S調(diào)用更新
{
FREQ_ST_TIME = 3; //三種主顯示內(nèi)容和頻譜模式,他們復(fù)用每判斷
}
else
{
FREQ_ST_TIME--;
}
}
else
{
FREQ_SEC_TIME--;
}
}
else
{
FREQ_TIME--;
}
}
else
{
SEC_TIME--;
}
}
/*end code 2009/1/7 How to program C!*/ |
-
-
vfd6311.pdf
2024-3-29 11:52 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
24.64 KB, 下載次數(shù): 2, 下載積分: 黑幣 -5
-
-
vfd6312.pdf
2024-3-29 11:52 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
24.35 KB, 下載次數(shù): 2, 下載積分: 黑幣 -5
|