📄 main.c
字号:
//-----------------------------------------------------------------
// 名称: 微芯VLS5573显示屏驱动测试
//-----------------------------------------------------------------
// 说明: 本例运行时,按下K1按键可分别在VLS5573LCD屏上完成模数转换,温度显示,
// 时钟运行三种演示效果.在演示时钟运行时,K2,K3按键可用于时钟调节.
// 本例用MCC18编译.
//
//-----------------------------------------------------------------
#include "p18f8490.h"
#include "LCD_8490.h"
#include <delays.h>
#define INT8U unsigned char
#define INT16U unsigned int
#pragma config OSC = INTIO67
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOREN = OFF
#pragma config WDT = OFF
#pragma config DEBUG = ON
#pragma config XINST = OFF
//-----------------------------------------------------------------
// 本例相关函数声明
//-----------------------------------------------------------------
void LCD_CONFIG(void);
void DisplayOn(void);
void DisplayOff(void);
void BarGraph(INT8U);
void CirGraph(INT8U);
void S1Num(INT8U);
void S2Num(INT8U);
void S3Num(INT8U);
void S4Num(INT8U);
void S5Num(INT8U);
void S6Num(INT8U);
void S7Num(INT8U);
void S8Num(INT8U);
void Voltmeter(void);
void Volt_Display(INT8U dat);
void BatteryIndic(INT8U i);
void Thermometer(void);
void Temp_Display_C(INT16U dat);
void Temp_Display_F(INT16U dat);
void TempIndic(INT8U i);
void RTC_Display(void);
void InterruptHandlerHigh(void);
//-----------------------------------------------------------------
// 相关符号等定义
//-----------------------------------------------------------------
//10以上的十六进制数位定义(A-F)及本例其他所用字符定义(H,L,P)
#define A 10
#define B 11
#define C 12
#define D 13
#define E 14
#define F 15
#define H 17
#define L 21
#define P 25
//无显示
#define NoDisp 0xFF
#define K1 PORTBbits.RB5 //模式选择键(F1~F3)
#define K2 PORTBbits.RB6 //按键K2调节HR
#define K3 PORTBbits.RB7 //按键K3调节MIN
//-----------------------------------------------------------------
// 变量声明
//-----------------------------------------------------------------
//AN0,AN1两路模拟电压
INT16U an0_voltage, an1_voltage, Reading;
//条形图条数
INT8U BGCNT;
//演示功能代号
volatile INT8U DemoCode = 0;
//秒,分,时
volatile INT8U SEC, MIN, HR;
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
void main()
{
OSCCON = 0B01000000; //1MHZ
OSCTUNE = 0B01100000;
BGCNT = 0; //条形图当前显示的竖条数(bar graph count)
LCD_CONFIG(); //配置LCD模块使用内部升压电路
TRISBbits.TRISB5 = 1; //K1按键输入
TRISBbits.TRISB6 = 1; //K2按键输入
TRISBbits.TRISB7 = 1; //K3按键输入
DisplayOn(); //全屏开演示
Delay10KTCYx(10); //延时
DisplayOff(); //全屏关演示
MCHPON; //显示微芯标志
S1Num(H);S2Num(E);S3Num(L);//显示"HELLO"(字母O用数字0代替)
S4Num(L);S5Num(0);
//外部中断控制
INTCONbits.RBIE = 1; //使RB端口中断
INTCONbits.GIE = 1; //开全局中断
INTCONbits.PEIE = 1; //使能所有未屏蔽的外部中断
Sleep(); //低功耗模式
DisplayOff(); //显示屏关闭
//定时器TMR1初始化
TMR1H = 0x80;
T1CONbits.T1RUN = 1; //设备时钟取自TIMER1振荡器
T1CONbits.T1CKPS1 = 0; //T1CKPS1:0=00,1:1预分频
T1CONbits.T1CKPS0 = 0;
T1CONbits.T1OSCEN = 1; //使能TIMER1振荡器
T1CONbits.T1SYNC = 1; //不同步外部时钟输入
T1CONbits.TMR1CS = 1; //选择外部时钟源(32K),RC0/T1OSO/T13CKI
T1CONbits.TMR1ON = 1; //使能TIMER1
PIE1bits.TMR1IE = 0; //暂时禁止TIMER1中断
ADCON1 = 0x0D; //RA0-RA2设为模拟输入
while(1)
{
//F1按键演示-----------------------------------------------
if (DemoCode == 1)
{
}
//F2按键演示-----------------------------------------------
if (DemoCode == 2)
{
}
//F3按键演示-----------------------------------------------
if (DemoCode == 3)
{
}
}
}
//-----------------------------------------------------------------
// LCD配置寄存器设置
//-----------------------------------------------------------------
void LCD_CONFIG(void)
{
//波形类型选择位(0:A类,1:B类)
LCDPSbits.WFT = 0;
//偏压模式选择位(本例LMUX1:0为11,BIASMD为0则为1/3偏压模式)
LCDPSbits.BIASMD = 0;
//选择帧时钟预分频0100->1:5
LCDPSbits.LP3 = 0;
LCDPSbits.LP2 = 1;
LCDPSbits.LP1 = 0;
LCDPSbits.LP0 = 0;
//设置LCDSEx寄存器,使相应的引脚(SEGx)作为数码管段驱动
LCDSE0 = 0xFF; LCDSE1 = 0xFF;
LCDSE2 = 0xFF; LCDSE3 = 0xFF;
LCDSE4 = 0xFF; LCDSE5 = 0xFF;
//通过LCDCON寄存器配置LCD模块
//CS1:0为时钟源选择位,11表示:INTRC(31.25 kHz)/32
LCDCONbits.CS1 = 1;
LCDCONbits.CS0 = 1;
//LMUX1:0设为11,将PORTE4-PORTE6设为COM1-COM3,占空比:1/4
LCDCONbits.LMUX1 = 1;
LCDCONbits.LMUX0 = 1;
//使能LCD模块
LCDCONbits.LCDEN = 1;
}
//-----------------------------------------------------------------
// 高优选级中断向量
//-----------------------------------------------------------------
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh()
{
_asm
goto InterruptHandlerHigh //跳转到中断例程
_endasm
}
//-----------------------------------------------------------------
// 高优选级中断例程
//-----------------------------------------------------------------
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh(void)
{
//定时器TMR1溢出中断
if (PIR1bits.TMR1IF == 1)
{ PIR1bits.TMR1IF = 0;
//处理秒,分,时递增及进位操作
if (++SEC > 59)
{ SEC = 0;
if (++MIN > 59) { MIN = 0; if (++HR > 23 ) HR = 0; }
}
TMR1H = 0x80;
}
//模数转换中断
if (PIR1bits.ADIF == 1)
{ PIR1bits.ADIF = 0;
if (DemoCode == 1) { an0_voltage =((INT16U)(ADRESH) << 8) + ADRESL;}
if (DemoCode == 2) { an1_voltage =((INT16U)(ADRESH) << 8) + ADRESL;}
}
//INT中断(按键K1/K2/K3触发)
if (INTCONbits.RBIF == 1)
{ //K1控制演示功能号在1~3之间循环
if (K1 == 0 && ++DemoCode > 3 ) DemoCode = 1;
//K2,K3调节时/分
if (K2 == 0 && HR < 23) HR++;
if (K3 == 0 && MIN < 59) MIN++;
INTCONbits.RBIF = 0;
}
}
//-----------------------------------------------------------------
// 温度计程序
//-----------------------------------------------------------------
void Thermometer(void)
{
Temp_Display_C(2 *(Reading - 392)); //摄氏温度显示
Temp_Display_F(36 *(Reading - 303)); //华氏温度显示
}
//-----------------------------------------------------------------
// 摄氏温度显示
// (显示在下行数字6,7,8位,加小数点,开摄氏度标志,并显示温度指示器)
//-----------------------------------------------------------------
void Temp_Display_C(INT16U dat)
{
S6Num(dat / 100);
S7Num(dat / 10 % 10);
S8Num(dat % 10);
DP2ON; X25ON;
TempIndic(dat / 100);
}
//-----------------------------------------------------------------
// 华氏温度显示(显示在上行数字2,3,4,5位,加小数点,开华氏度标志)
//-----------------------------------------------------------------
void Temp_Display_F(INT16U dat)
{
S2Num(dat / 1000);
S3Num(dat / 100 % 10);
S4Num(dat % 100 / 10);
S5Num(dat % 10);
DP1ON; X26ON;
}
//-----------------------------------------------------------------
// 电压表显示
//-----------------------------------------------------------------
void Voltmeter(void)
{
//电压值显示0.0V~5.0V (VR调到顶端时本例为1022,此处用+1调整误差)
Volt_Display( (an0_voltage + 1) * 50 / 1023);
//刷新条形图显示(0-20条)
BarGraph( (an0_voltage + 1) * 20 / 1023);
//电量指示器显示(3段电量指示)
BatteryIndic((an0_voltage + 1) * 3 / 1023);
}
//-----------------------------------------------------------------
// 电压值显示
//-----------------------------------------------------------------
void Volt_Display(INT8U d)
{
//在上行第4,5两位显示电压,并加小数点
S4Num(d / 10); S5Num(d % 10); DP1ON;
}
//-----------------------------------------------------------------
// 温度指示器指示
//-----------------------------------------------------------------
void TempIndic(INT8U i)
{
S5ON; //固定显示温度指示器外框
//内部高度显示(3段,S6/S7/S8)
if (i >= 5) { S6ON; S7ON; S8ON;} //三段显示
else if (i >= 2) { S6OFF; S7ON; S8ON;} //两段显示
else if (i >= 1) { S6OFF; S7OFF; S8ON;} //一段显示
}
//-----------------------------------------------------------------
// 电量指示器显示
//-----------------------------------------------------------------
void BatteryIndic(INT8U i)
{
S9ON; //固定显示电量指示器外框
if (i >= 3) { S10ON; S12ON; S11ON; } //三段显示
if (i == 2) { S10OFF; S12ON; S11ON; } //两段显示
if (i == 1) { S10OFF; S12OFF; S11ON;} //一段显示
}
//-----------------------------------------------------------------
// 实时时钟显示
//-----------------------------------------------------------------
void RTC_Display(void)
{
//小时显示,后面加冒号显示
S1Num(HR / 10); S2Num(HR % 10); COLON;
//分钟显示
S3Num(MIN / 10); S4Num(MIN % 10);
//秒显示
S6Num(SEC / 10); S7Num(SEC % 10);
//环形图显示(用于模拟秒循环)
CirGraph(SEC % 10);
}
//-----------------------------------------------------------------
// 环形进程图显示
//-----------------------------------------------------------------
void CirGraph(INT8U Count)
{
CGOFF; //先清除环形图显示
//根据Count值决定显示扇形范围,为0时仅显示环形的圆心点
switch(Count)
{
case 9: X28ON; case 8: X29ON; case 7: X30ON;
case 6: X31ON; case 5: X32ON; case 4: X33ON;
case 3: X34ON; case 2: X35ON; case 1: X36ON;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -