⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 单片机c语言程序设计100例--基于PIC+PROTEUS
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------
// 名称: 微芯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 + -