📄 vfd.c
字号:
#include "REG931.H"
#include "memory.h"
#include "system.h"
#include "key.h"
#include "uart.h"
#include "iic.h"
#include "vfd.h"
//SPI
uchar code vfdgid[][3]={
{0x1,0x00,0x00}, // grid1
{0x2,0x00,0x00}, // grid2
{0x4,0x00,0x00}, // grid3
{0x8,0x00,0x00}, // grid4
{0x10,0x00,0x00}, // grid5
{0x20,0x00,0x00}, // grid6
{0x40,0x00,0x00}, // grid7
{0x80,0x00,0x00}, // grid8
{0x0,0x01,0x00}, // grid9
{0x0,0x02,0x00}, // grid10
{0x0,0x04,0x00}, // grid11
{0x0,0x08,0x00}, // grid12
{0x0,0x10,0x00}, // grid13
{0x0,0x20,0x00}, // grid14
{0x0,0x40,0x00}, // grid15
{0x0,0x80,0x00}, // grid16
{0x0,0x00,0x01}, // grid17
{0x0,0x00,0x02}, // grid18
///////////////////////////////////////////////
{0x01,0x00,0x00}, // grid19
};
//----------------------------------
//功能:SPI接口初始化(初始化为主机)
//----------------------------------
void SPI_Init()
{
ESPI=1; // enable SPI interrupt;
SPCTL=0xfd; //SSIG=1,SPIEN=1,DROD=0,MSTR=1,CPOL=1,CPHA=1,SPR1=0,SPR0=1;
SPSTAT=0xC0; //清除SPSTAT中的标志位
}
// % : 8.3 16.6 25 33.3 41.6 50 58.3 66.6 75 83.3 91.6 100
// seg: 1 2 3 4 5 6 7 8 9 10 11 12
// Input: percent=0 ~ 100
void DisplayColumn(uchar point){
uchar SegNum=0;
if(Mode !=SYS_IDLE)
return;
VFD.BakupBuff[0] &= 0xcc; // clear b5,b4,b1,b0
VFD.BakupBuff[1] = 0x0;
if(!point){
PerModulus=0; return;
}
else if(point<8){ goto GET_MOD;}
else if(point<16){ SegNum=0x10; goto PER_8; }
else if(point<24){ SegNum=0x20; goto PER_17;}
else if(point<32){ SegNum=0x30; goto PER_25;}
else if(point<40){ SegNum=0x40; goto PER_33;}
else if(point<48){ SegNum=0x50; goto PER_42;}
else if(point<56){ SegNum=0x60; goto PER_50;}
else if(point<64){ SegNum=0x70; goto PER_58;}
else if(point<72){ SegNum=0x80; goto PER_67;}
else if(point<80){ SegNum=0x90; goto PER_75;}
else if(point<88){ SegNum=0xa0; goto PER_83;}
else if(point<100){SegNum=0xb0; goto PER_92;} // more than 92 percent
else Percent=100;
VFD.BakupBuff[0] |= 0x01;
PER_92: VFD.BakupBuff[0] |= 0x02;
PER_83: VFD.BakupBuff[0] |= 0x10;
PER_75: VFD.BakupBuff[0] |= 0x20;
PER_67: VFD.BakupBuff[1] |= 0x01;
PER_58: VFD.BakupBuff[1] |= 0x02;
PER_50: VFD.BakupBuff[1] |= 0x04;
PER_42: VFD.BakupBuff[1] |= 0x08;
PER_33: VFD.BakupBuff[1] |= 0x10;
PER_25: VFD.BakupBuff[1] |= 0x20;
PER_17: VFD.BakupBuff[1] |= 0x40;
PER_8: VFD.BakupBuff[1] |= 0x80;
VFD.FrontBuff[0] = VFD.BakupBuff[0];
VFD.FrontBuff[1] = VFD.BakupBuff[1];
GET_MOD:
PerModulus = point%8;
PerModulus |= SegNum;
}
//SPI, send 5 bytes (1 Grid, 1 frame)typically 110us, max is 120 us, but from Timer1 to SPI interrupt, typically time 25us
// so update 1 Grid typically time 110+25=136us
void SPI_ISR (void) interrupt 9
{
// static uchar data cNum=1;
uchar posit;
SPSTAT=0xc0;
if(!bGrid){ // already send one frame data (18*2=36 byte)
cNum++;
// Delayus(50);
BLANK=1;
return;
}
do{ // send 5 byte data (5 * 8=40 bits)
posit=cNum%5;
if(posit<3){
#if 0
if(cNum==2) SPDAT = vfdgid[cNum/5][posit]|(Seg_AEC?0x80:0);
else if(cNum==22) SPDAT = vfdgid[cNum/5][posit]|(Seg_W?0x80:0);
else if(cNum==47) SPDAT = vfdgid[cNum/5][posit]|(Seg_DI1?0x80:0);
else SPDAT = vfdgid[cNum/5][posit];
#else
if(cNum==2) SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x01)?0x80:0); // refresh AEC segment
else if(cNum==22) SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x02)?0x80:0); // refresh W segment
else if(cNum==47) SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x04)?0x80:0); // refresh DI_S14 segment
else SPDAT = vfdgid[cNum/5][posit];
#endif
}
else{
SPDAT=VFD.FrontBuff[(cNum/5)*2+ posit-3];
}
while(SPSTAT&0x80==0) ; // wait for SPIF=1
SPSTAT=0xC0; //清除SPSTAT中的标志位
Delayus(1); // about 1 us
}
while(++cNum%5);
if(cNum >= 90){
cNum=0;
}
LATCH=1;
bGrid=0;
// BLANK=1;
}
void VFD_Fresh(void)
{
BLANK=0;
FrameNum %= 18;
switch(FrameNum){
case 0: cNum=1; break;
// case 1: cNum=6; break;
case 2: cNum=11; break;
// case 3: cNum=16; break;
case 4: cNum=21; break;
// case 5: cNum=26; break;
case 6: cNum=31; break;
// case 7: cNum=36; break;
case 8: cNum=41; break;
// case 9: cNum=46; break;
case 10: cNum=51; break;
// case 11: cNum=56; break;
case 12: cNum=61; break;
// case 13: cNum=66; break;
case 14: cNum=71; break;
// case 15: cNum=76; break;
case 16: cNum=81; break;
// case 17: cNum=86; break;
}
LATCH=1;
bGrid=1;
LATCH=0;
Delayus(1);
SPDAT=vfdgid[FrameNum][0]; // start SPI interrupt
FrameNum++;
}
// exicute time typically 72us , min 26us, max 80us
// value =FFFF-us*F(MHz)/2
void timer1 (void) interrupt 3 //using 1 /* Int Vector at 000BH, Reg Bank 1 */
{
TR1= 0;
// max is 12.5ms/18Grid = 694us
// 0x0800=9.9ms; 0xf610==690us ; 0xf6A3=650us; 0xfa00=252us; 0xf500=448us;
// TH1= 0xf6; TL1= 0xa3; /* set timer period 650us */
TH1= 0xf6; TL1= 0x10; /* set timer period 690us */
TR1= 1;
VFD_Fresh( );
}
#define TEST_END_DELAY_TIME BUF_SIZE+128
// use system Counter32ms counted the step
void VFDTestSelf(void){
#define TimeTick Counter32ms
static uchar n=0;
if(bSelfTest){
n=0;
bSelfTest=0;
}
if(n>=BUF_SIZE)
n++; // delay time
if(TimeTick%SelfTestUnit)
return;
if(n<BUF_SIZE){
VFD.FrontBuff[n] <<=1;
VFD.FrontBuff[n] |=0x1;
if(VFD.FrontBuff[n]==0xff)
n++;
}
if(n>=TEST_END_DELAY_TIME){
for(n=0;n<BUF_SIZE;n++)
VFD.FrontBuff[n]=0;
VFD.FrontBuff[36]=0x1;
// TimeTick=0;
Mode=SYS_IDLE;
DisplayColumn(Percent); // recover BRM
}
}
// RTC interrupt is used to display level percent (BRM)
void InitRTC(void){
// start Real Time Clock. // RTC frequency is 7.373 MHz;
RTCCON=0x0; // disenable rtc,
RTCH=0x0e;RTCL=0x10;
// IEN0 |=0x40; // enable RTC interrupt
EWDRT =1; // enable RTC interrupt
RTCCON |=0x63; // enable rtc interrupt,
}
void SetBRMFlashBit(uchar tim, uchar mod, uchar cnst){
if(tim < mod) VFD.FrontBuff[0] |= cnst;
else VFD.FrontBuff[0] &= ~cnst;
}
// RTC is used to display VFD level percent (BRM)
// this interrupt source share of watch dog timer
void RTC_Isr(void) interrupt 10
{
uchar seg, ucMod;
static idata ModTimer;
if(RTCCON &0x80) {
RTCCON &= 0x7f;
// 0x0e20=62.5ms; 0x0709=31.3ms; 0x0384=15.6ms; 0x0240=10ms; 0x01c2=7.8ms
RTCH=0x02;RTCL=0x40;
RTCCON |=0x63; // enable rtc interrupt
}
ModTimer++;
ModTimer %= 8;
seg = PerModulus>>4;
ucMod= PerModulus&0x0f;
if(!ucMod)
return;
if( seg<8){
if(ModTimer < ucMod) VFD.FrontBuff[1] |= 0x80>>seg; // on
else VFD.FrontBuff[1] &= ~(0x80>>seg); // off
}
else{
switch(seg){
case 0x08:
SetBRMFlashBit(ModTimer, ucMod, 0x20);
// if(ModTimer < ucMod) VFD.FrontBuff[0] |= 0x20; // on
// else VFD.FrontBuff[0] &= ~0x20 ;
break;
case 0x09:
SetBRMFlashBit(ModTimer, ucMod, 0x10);
break;
case 0x0a:
SetBRMFlashBit(ModTimer, ucMod, 0x02);
break;
case 0x0b:
SetBRMFlashBit(ModTimer, ucMod, 0x01);
break;
}
}
}
void SendData2TxBuff(uchar cmd, uchar *Pt){
uchar CheckSum,Lenth;
CheckSum=TxDBuff[0]=cmd; // [0]
switch(cmd){
case TXD_RESEND_CMD: // Len=4;
case SYS_RST_FLAG_CMD: // Len=4;
TxDBuff[1]=0; // [1]
TxDBuff[2]=0; // [2]
Lenth=3;
break;
case TXD_KEY_EVENT_CMD: // Len=4;
case TXD_SOFTWARE_VER_CMD: // Len=4;
TxDBuff[1]=1; CheckSum += 1; // [1]
TxDBuff[2]=*Pt; CheckSum += TxDBuff[2]; // [2]
Lenth=3;
break;
}
TxDBuff[Lenth]=CheckSum;
if(bUartFuncSelectEn) // uart
StartUartData(Lenth+1);
else // i2c
StartI2CData(Lenth+1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -