/* Main.c file generated by New Project wizard
*
* Created: 周二 4月 10 2018
* Processor: PIC18F452
* Compiler: MPLAB C18
*/
#include <p18f452.h>
#define RW PORTBbits.RB5
#define RS PORTBbits.RB6
#define EN PORTBbits.RB7
#define P0 PORTD
#define ADGO ADCON0bits.GO
void tmr(void);
void KeyInterrupt1 (void); //中斷服務函數
void KeyInterrupt2 (void); //中斷服務函數
void KeyInterrupt3 (void); //中斷服務函數
void lcd_show(void);
void lcd_show1(void);
void lcd_show2(void);
void lcd_show3(void);
void lcd_show4(void);
void lcd_show5(void);
void lcd_show6(void);
unsigned int AD_Trs(void);
unsigned int AD_Trs1(void);
unsigned int AD_Trs2(void);
//int j=0;
//int time=0;
//int timem=0;
int intermode=0;
unsigned int lednum=0;
int max=4000,max1=3900,max2=3800,max3=3700;
int min=1000,min1=900,min2=800,min3=1000;
unsigned char time2[7]="wangkuod";
unsigned int a1=0,a2=0,a3=0;
int init(); //聲明初始化函數
int write_com(unsigned char);//聲明寫命令函數
int write_date(unsigned char);//聲明寫數據函數
int delay(unsigned char);//聲明延遲函數
unsigned char x;
//sbit RS = P1^0;
// sbit RW = P1^1;
//sbit EN = P1^2;
//unsigned char table[]="HELLO!";
//unsigned char table1[]="2018/4/16";
void main(void)//主函數
{
TRISD=0;
TRISBbits.TRISB0=1;
TRISBbits.TRISB1=1;
TRISBbits.TRISB2=1;
TRISBbits.TRISB5=0;
TRISBbits.TRISB6=0;
TRISBbits.TRISB7=0;
TRISAbits.TRISA0=1;
TRISAbits.TRISA1=1;
TRISAbits.TRISA2=1;
TRISAbits.TRISA6=0;
// INTCON |= 0xa0; //開全局中斷及Timer0 中斷
//INTCONbits.TMR0IE=1;
INTCONbits.GIE=1;
//INT0
INTCON2bits.INTEDG0=1;
INTCONbits.INT0IF=0;
INTCONbits.INT0IE=1;
//INT1
INTCON2bits.INTEDG1=1;
INTCON3bits.INT1IF=0;
INTCON3bits.INT1IE=1;
//int2
INTCON2bits.INTEDG2=1;
INTCON3bits.INT2IF=0;
INTCON3bits.INT2IE=1;
//TMR0H = 25536/256; //高8 位
//TMR0L = 25536%256; //低8 位
//T0CON = 0x88; //使能Timer0,并設置為16 位定時器,沒有預分頻
//AD
ADCON0=0x81;
//-- ADFM ADCS2 —— —— PCFG3 PCFG2 PCFG1 PCFG0
//-- 1 0 0 0 1 1 1 0
//右對齊(ADRESH 寄存器的高6 位讀作0),AN0 為模擬輸入位,參考正負電壓
//分別為VDD 和VSS
ADCON1 = 0x8e;
init();
// write_com(0x80);
// for(x=0;x<6;x++)
// {
// write_date(table[x]);
// delay(150);
// }
//for(x=0;x<6;x++)
// {
// write_date(time);
// delay(150);
// }
// write_com(0x80);
// for(x=0;x<17;x++)
// {
// write_date(table1[x]);
// delay(150);
// }
while(1)
{
unsigned int a;
lednum = AD_Trs();
write_com(0x80);
time2[1]='0';
lcd_show();
lednum = AD_Trs1();
write_com(0x80+0x08);
time2[1]='1';
lcd_show();
lednum = AD_Trs2();
write_com(0x80+0x40);
time2[1]='2';
lcd_show();
switch(intermode) {
case 0: {write_com(0x80+0x40+0x08);
lcd_show1();break;
}
case 1:
{write_com(0x80+0x40+0x08);
lcd_show2();break;}
case 2:
{write_com(0x80+0x40+0x08);
lcd_show3();break;
}
case 3:
{write_com(0x80+0x40+0x08);
lcd_show4();break;
}
case 4:
{write_com(0x80+0x40+0x08);
lcd_show5();break;
}
case 5:
{write_com(0x80+0x40+0x08);
lcd_show6();break;
}
default:
{write_com(0x80);
lcd_show1();break;
}
}
if(lednum>max1|lednum>max2|lednum>max3|lednum<min1|lednum<min2|lednum<min3){
//for(a=10;a>0;a--)
//{PORTAbits.RA3=0;
// delay(50);
// PORTAbits.RA3=1;
// delay(50);
// PORTAbits.RA3=0;
// delay(50);
// PORTAbits.RA3=1;
// delay(50);}
PORTAbits.RA6=1; }
}
}
#pragma code xx=0x0008 //MCC18 的中斷必需用一段匯編實現
void inter(void) //xx 為優先級,沒有優先級時,可省略xx
{
if(INTCONbits.INT0IF){
_asm
goto KeyInterrupt1
_endasm}
else if(INTCON3bits.INT1IF){
_asm
goto KeyInterrupt2
_endasm
}
else {
_asm
goto KeyInterrupt3
_endasm
}
}
//=======中斷服務函數==========
#pragma interrupt KeyInterrupt1
void KeyInterrupt1 (void)
{
if (INTCONbits.INT0IF && INTCONbits.INT0IE) //中斷標志位判斷
{
//T0CONbits.TMR0ON=~T0CONbits.TMR0ON;
INTCONbits.INT0IF = 0; //中斷標志位清零
switch(intermode) {
case 0:
{max1=max1+100; break;
}
case 1:
{max2=max2+100;break;}
case 2:
{max3=max2+100;break;
}
case 3:
{min1=min1+100;break;
}
case 4:
{min2=min2+100;break;
}
case 5:
{min3=min3+100;break;
}
default:
{max1=max1+100;break;
}
}
}
}
#pragma code
//=======中斷服務函數==========
#pragma interrupt KeyInterrupt2
void KeyInterrupt2 (void)
{
if (INTCON3bits.INT1IF && INTCON3bits.INT1IE) //中斷標志位判斷
{
//T0CONbits.TMR0ON=~T0CONbits.TMR0ON;
//intermode=~intermode;
INTCON3bits.INT1IF = 0; //中斷標志位清零
intermode++;
if(intermode>5)
{intermode=0;}
}
}
#pragma code
#pragma interrupt KeyInterrupt3
void KeyInterrupt3 (void)
{
if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) //中斷標志位判斷
{
//time=timem=j=0;
// T0CONbits.TMR0ON=0;
INTCON3bits.INT2IF = 0; //中斷標志位清零
switch(intermode) {
case 0:
{max1=max1-100; break;
}
case 1:
{max2=max2-100;break;}
case 2:
{max3=max2-100;break;
}
case 3:
{min1=min1-100;break;
}
case 4:
{min2=min2-100;break;
}
case 5:
{min3=min3-100;break;
}
default:
{max1=max1-100;break;
}
}
}
}
#pragma code
int init()//初始化函數體
{
EN = 0;
write_com(0X38);//設置16*2顯示,5*7點陣,8位數據接口
write_com(0X0C);//設置開顯示,不顯示光標
write_com(0X06);//寫一個字符時,整屏右移
write_com(0X01);//顯示清零
return 0;
}
int write_com(unsigned char com)//寫命令的函數體
{
RS = 0;
RW = 0;
P0 = com;
delay(5);
EN = 1;
delay(5);
EN = 0;
return 0;
}
int write_date(unsigned char date)//寫數據的函數體
{
RS = 1;
RW = 0;
P0 = date;
delay(5);
EN = 1;
delay(5);
EN = 0;
return 0;
}
int delay(unsigned char xms)
{
unsigned char x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
return 0;
}
void lcd_show1(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = max1/1000;
a2 = max1%1000/100;
a3 = max1%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='0';
time2[2]='M';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show2(void)
{
// unsigned char a,b;
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = max2/1000;
a2 = max2%1000/100;
a3 = max2%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='1';
time2[2]='M';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show3(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = max3/1000;
a2 = max3%1000/100;
a3 = max3%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='2';
time2[2]='M';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show4(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = min1/1000;
a2 = min1%1000/100;
a3 = min1%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='0';
time2[2]='m';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show5(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = min2/1000;
a2 = min2%1000/100;
a3 = min2%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='1';
time2[2]='m';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show6(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = min3/1000;
a2 = min3%1000/100;
a3 = min3%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[1]='2';
time2[2]='m';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
void lcd_show(void)
{
// unsigned char a,b;
// unsigned char time2[7];
// unsigned int time1[2];
// unsigned int time3[2];
// unsigned int a1=0,a2=0,a3=0;
//time3[0]=j/10;
//time3[1]=j%10;
//time1[0]=time/10;
//time1[1]=time%10;
if(lednum>max1|lednum>max2|lednum>max3|lednum<min1|lednum<min2|lednum<min3){
PORTAbits.RA6=~PORTAbits.RA6; }
//此算法用于取出一個整數的各個位,來顯示在LCD 上
a1 = lednum/1000;
a2 = lednum%1000/100;
a3 = lednum%100/10;
//a4 = lednum%10;
time2[0]='A';
time2[2]=' ';
time2[3]='0'+a1;
time2[4]='.';
time2[5]='0'+a2;
time2[6]='0'+a3;
for(x=0;x<7;x++)
{
write_date(time2[x]);
delay(15);
}
}
//============AD 轉化程序============
unsigned int AD_Trs()
{
unsigned int adval;
float advalf;
ADCON0=0x81;
ADGO = 1; //啟動AD 轉化
while(ADGO); //說明AD 轉化完成
adval = ADRESH;
adval = adval<<8|ADRESL;
advalf = adval/1023.0*5.0; //因為參考電壓為5 伏
adval = advalf*1000; //轉化為整數,以便顯示
return (adval);
}
unsigned int AD_Trs1()
{
unsigned int advall;
float advalf;
//-- ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE —— ADON
//-- 1 0 0 0 0 0 0 1
//選擇通道0(AN0),開啟AD 轉換并清零AD 轉換標志位
ADCON0=0x89;
//-- ADFM ADCS2 —— —— PCFG3 PCFG2 PCFG1 PCFG0
//-- 1 0 0 0 1 1 1 0
//右對齊(ADRESH 寄存器的高6 位讀作0),AN0 為模擬輸入位,參考正負電壓分別為VDD 和VSS
ADCON1 = 0x8e;
ADGO = 1; //啟動AD 轉化
while(ADGO); //說明AD 轉化完成
advall = ADRESH;
advall = advall<<8|ADRESL;
advalf = advall/1023.0*5.0; //因為參考電壓為5 伏
advall = advalf*1000; //轉化為整數,以便顯示
return (advall);
}
unsigned int AD_Trs2()
{unsigned int adval2;
float advalf;
ADCON0=0x91;
ADGO = 1; //啟動AD 轉化
while(ADGO); //說明AD 轉化完成
adval2 = ADRESH;
adval2 = adval2<<8|ADRESL;
advalf = adval2/1023.0*5.0; //因為參考電壓為5 伏
adval2= advalf*1000; //轉化為整數,以便顯示
return (adval2);
}
//==精確定時0.25us,這是由于51 用的晶振是4M 的,而PIC 的是16M 的,相應的指令周期為0.25us==
|