/*
CS16312作为主控芯片的 VFD 显示屏驱动程序
Coder : Farman
Version : 2018-01-07
*/
#include <STC89C5xRC.H>
#include "Delay.h"
sbit CS16312_SDA = P2^0; // SPI 数据线
sbit CS16312_SCLK = P2^1; // SPI 串行时钟
sbit CS16312_STB = P2^2; // 片选信号,0-不选 1-选中。
#define CS16312_SDA_HIGH 1
#define CS16312_SCLK_HIGH 1
#define CS16312_STB_HIGH 1
//--------------------------------------------------------
void CS16312_delay()
{
nop_();
//Delay1ms();
}
//----------------------------------------------------------
void CS16312_enable()
{
CS16312_STB = !CS16312_STB_HIGH;
CS16312_delay();
}
void CS16312_disable()
{
CS16312_STB = CS16312_STB_HIGH;
CS16312_delay();
}
void CS16312_write_byte(unsigned char byte_to_write)
{
unsigned char mask = 0x01;
unsigned char n;
for(n=0; n<8; n++)
{
CS16312_SCLK =!CS16312_SCLK_HIGH;
CS16312_delay();
CS16312_SDA = (mask & byte_to_write) ? 1 : 0; CS16312_delay();
CS16312_SCLK = CS16312_SCLK_HIGH;
CS16312_delay();
mask += mask;
}
return;
}
void CS16312_write_command_byte(unsigned char command_byte)
{
CS16312_enable();
CS16312_write_byte(command_byte);
CS16312_disable();
}
//----------------------------------------------------------
// digits_could_display : 8 - 16
// 命令前必须有一次 STB 有效,
// 命令后必须有一次 STB 释放。
void CS16312_command1(unsigned char digits_could_display)
{
CS16312_write_command_byte(digits_could_display - 4);
}
// 命令前必须有一次 STB 有效,
// 命令后必须有一次 STB 释放。
void CS16312_command2(bit enable_inc_addr_after_write)
{
unsigned char command = 0x40;
command += enable_inc_addr_after_write ? 0x00 : 0x04;
CS16312_write_command_byte(command);
}
// addr : 0x00 - 0x15
// 该命令后面要紧跟写入显示RAM的数据,且该命令与数据之间不允许有 STB 释放操作
// 数据与数据之间也不允许有 STB 释放。
//
// 所以,在该命令前要 调用一次 CS16312_enable()
// 所有的显示RAM传输结束后,调用一次 CS16312_disable().
void CS16312_command3(unsigned char RAM_addr_to_write)
{
CS16312_write_byte(0xC0 + RAM_addr_to_write);
}
// 命令前必须有一次 STB 有效,
// 命令后必须有一次 STB 释放。
// bright : 0 - 7
void CS16312_command4(bit enable_display, unsigned char bright)
{
CS16312_write_command_byte((enable_display ? 0x88 : 0x80) + bright);
}
//----------------------------------------------------------
void CS16312_write_display_RAM(unsigned char addr, unsigned char display_data_byte)
{
CS16312_enable();
CS16312_command3(addr);
CS16312_write_byte(display_data_byte);
CS16312_disable();
}
void CS16312_fill_display(unsigned char pattern)
{
unsigned char m;
CS16312_command2(1);
CS16312_enable();
CS16312_command3(0);
for(m=0x00; m<0x16; m++)
{
CS16312_write_byte(pattern);
}
CS16312_disable();
}
//----------------------------------------------------------
code unsigned char CS16312_8seg_digit[] =
{
0x77, 0x24, 0x6B, 0x6D, 0x3C, 0x5D, 0x5F, 0x64, 0x7F, 0x7D
};
// pos 0-6 digit:0-9
// 因为倒数第2个数字的段码与其他的不同,需要单独处理。此处未处理。
// 在 CS1632_show_byte_as_BCD 中进行了处理
void CS16312_show_8seg_digit(unsigned char pos, unsigned char digit, bit with_dot)
{
if(pos == 2 || pos == 4)
{
CS16312_write_display_RAM(6-pos, CS16312_8seg_digit[digit] + (with_dot ? 0x80 : 0x00));
}
else
{
CS16312_write_display_RAM(6-pos, CS16312_8seg_digit[digit]);
}
}
code unsigned char CS16312_special_digit[] =
{
0x77, 0x24, 0x6B, 0x6D, 0x3C, 0x5D, 0x5F, 0x64, 0x7F, 0x7D
};
// pos 0-3 BCD:0x00-0x99
void CS1632_show_byte_as_BCD(unsigned char pos, unsigned char bcd, bit with_dot)
{
if(pos == 0)
{
CS16312_show_8seg_digit(0, bcd&0x0F, 0);
}
else if(pos == 3)
{
// 写右边起第2个数字
CS16312_write_display_RAM(1, CS16312_special_digit[bcd>>4]>>1);
// 写右边起第1个数字
CS16312_write_display_RAM(0, (CS16312_special_digit[bcd>>4] & 0x01) ?
(CS16312_8seg_digit[bcd&0x0F] | 0x80) : (CS16312_8seg_digit[bcd&0x0F] | 0x00));
}
else
{
CS16312_show_8seg_digit(2*pos-1, bcd>>4, with_dot);
CS16312_show_8seg_digit(2*pos, bcd&0x0F, with_dot);
}
}
void CS16312_show_disk(unsigned int pattern)
{
CS16312_write_display_RAM(8, pattern>>8);
CS16312_write_display_RAM(9, pattern>>8);
}
//----------------------------------------------------------
void CS16312_init()
{
CS16312_disable();
CS16312_SCLK = 0;
CS16312_SDA = 1;
Delay200ms();
CS16312_command1(5);
CS16312_command2(1);
CS16312_fill_display(0xFF);
CS16312_command4(1, 3);
}
//----------------------------------------------------------
void CS16312_main()
{
unsigned char m, n, seg;
CS16312_init();
CS16312_fill_display(0xFF); Delay200ms();
CS16312_fill_display(0x00); Delay200ms();
CS16312_fill_display(0xFF); Delay200ms();
CS16312_fill_display(0x00); Delay200ms();
CS16312_fill_display(0xFF); Delay200ms();
CS16312_fill_display(0x00); Delay200ms();
while(0)
{
CS16312_show_disk(0x5555); Delay200ms();
CS16312_show_disk(0xAAAA); Delay200ms();
}
while(1)
{
seg = 0x01;
for(m=0; m<10; m++)
{
CS1632_show_byte_as_BCD(0, m*0x11, 1);
CS1632_show_byte_as_BCD(1, m*0x11, 1);
CS1632_show_byte_as_BCD(2, m*0x11, 1);
CS1632_show_byte_as_BCD(3, m*0x11, 1);
Delay1s();
}
Delay1s();
}
}