?? b(interrupt).c
字號:
/***************************************************
本機接收A機發來時間數據,UART采用查詢中斷方式收發數據,
通過LCD1602顯示當前時間
****************************************************/
#include<pic166x.h>
#define uchar unsigned char
#define _nop_() asm("nop")
//定義LCM接口
#define EN RA2//RA2
#define RW RA1//RA1
#define RS RA0//RA0
#define LCD PORTB //數據口
uchar line[]={"hello world!"};
uchar num[]={"0123456789:'. "};
uchar ACC,time[7],i=0;
void interrupt uart_rxd(void)
{
uchar temp;
temp=RCREG;
TXREG=temp; //時間數據以“標識碼+時間”格式發送,使用0xa0~0xa6作標識碼
if(temp>0x99) i=temp-0xa0;
else time[i]=temp;
//中斷標志由硬件清零
}
//***********1602"忙"檢測*************/
void checkbf()
{
uchar check;
TRISB=0XFF;
for(; ;)
{
RS=0; //FOR IR
RW=1; // READ
EN=1;
check=LCD;//讀出液晶數據引腳(D0-D7)值,D7=0表示液晶“不忙”
EN=0;
if(!(check&0x80)) break;//不斷檢測,直到液晶不“忙”
}
TRISB=0X00;
}
//*************寫命令字節,flag決定是否在寫之前檢測"忙"狀態********/
void wir(uchar cc,uchar flag)
{
GIE=0; //關中斷
if(flag) checkbf(); //如果flag=1,則發命令前先進行“忙”檢測
RS=0; //把命令字節(cc)寫入到1602的IR(指令寄存器)
RW=0; // WRITE
EN=1;
LCD=cc;//寫入命令字節cc
EN=0;
GIE=1; //開關斷
}
//********* 往1602發數據字節,發之前先進行“忙”檢測 *************/
void wdat(uchar dat)
{
GIE=0; //關中斷
checkbf();
RS=1; //把這個字節(dat)寫入1602的DR(數據寄存器)
RW=0; // WRITE
EN=1;
LCD=dat; //往1602寫入用來顯示的數據(1個字節)
EN=0;
GIE=1; //開關斷
}
//****************在1602顯示屏(X,Y)坐標處顯示數據dd(占屏幕一個字的位置)***********/
/*void wbyte(uchar X,uchar Y,uchar dd)
{
if(Y==1) X|=0xc0;// second line
else X|=0x80;// first line 對坐標進行處理
wir(X,1);//先寫坐標
wdat(dd);//再送要顯示的數據
}*/
//****************從1602顯示屏(X,Y)坐標處開始顯示一連串數據***********/
void wstr(uchar X,uchar Y,uchar *da)//da為待顯示的字符串數組名
{
if(Y==1) X|=0xc0;//second line
else X|=0x80; //first line
wir(X,1); //先寫坐標
while(*da>0) wdat(*da++); //不斷往1602送字符串數據,直到字符串尾(字符串以“/0”結尾)
}
//*********5毫秒延時程序**********************/
void delay5ms()
{
uchar i,j=250;
for(i=10;i>0;i--)
while(--j);
}
//***********初始化1602**********************/
void init()
{
delay5ms();
delay5ms();
delay5ms();//初始化一般發生在上電復位后不久,延時15ms,待系統穩定下來
wir(0x38,0);
delay5ms();
wir(0x38,0);
delay5ms();
wir(0x38,0);//重復三次寫入命令字節0X38,不檢測忙信號
//下面命令字節的含義參照課本1602命令字表(RS=0,RW=0的)
wir(0x38,1);//功能設定:8位數據,雙列字,5*7字型
wir(0x08,1);//turn off light
wir(0x01,1);// clean the screen
wir(0x0c,1);// 開顯示屏,不開游標和閃爍功能
wir(0x06,1);//設定AC+1
}
/**************UART communication****************/
void init_uart()
{
TRISC=0x80;
SPBRG=25;
SPEN=1; //open serial port
CREN=1;
TXEN=1;
GIE=1;
PEIE=1;
RCIE=1; // 開中斷
}
/*
void send_byte(uchar dat)
{
TXREG=dat;
do{
; }while(!TXIF);
}
uchar rec_byte()
{
if(RCIF) return RCREG;
else return 0xff;
}
gettime(uchar *dat)
{
uchar i,temp;
for(i=7;i>0;i--)
{
for(;;)
{
temp=rec_byte();
if(temp!=0xff) break;
}
*dat++=temp;
send_byte(temp);
}
}
*/
/*************主函數main**************************/
void main()
{
uchar temp;
TRISA=0x00; //output
TRISB=0X00; //output(LCD DATA)
init_uart();
init();//初始化1602
while(1)
{
// gettime(time); //接收A機發來時間數據
wstr(0,0,line);//以字符串寫入方式顯示字符串line內容
wir(0xc0,1); //寫入第二行首坐標0xc0
temp=time[4];
temp>>=4;
temp&=0x0f;
wdat(num[temp]);
temp=time[4];
temp&=0x0f;
wdat(num[temp]);
wdat('.'); //"."
temp=time[3];
temp>>=4;
temp&=0x0f;
wdat(num[temp]);
temp=time[3];
temp&=0x0f;
wdat(num[temp]);
wdat(' ');
temp=time[2];
temp>>=4;
temp&=0x0f;
wdat(num[temp]);
temp=time[2];
temp&=0x0f;
wdat(num[temp]);
wdat(':');
temp=time[1];
temp>>=4;
temp&=0x0f;
wdat(num[temp]);
temp=time[1];
temp&=0x0f;
wdat(num[temp]);
wdat(num[11]); // '
temp=time[0];
temp>>=4;
temp&=0x0f;
wdat(num[temp]);
temp=time[0];
temp&=0x0f;
wdat(num[temp]);
}
}
/*
wbyte(0,1,num[1]);
// wir(0xc0,1); //寫入第二行首坐標0xc0
// wdat(num[1]); //之后不斷往1602送數據,每送一個字節,1602地址會自動加1
wdat(num[2]); //這樣后面的數據才不會覆蓋前面的
wdat(num[12]);
wdat(num[1]);
wdat(num[8]);
wdat(num[13]);
// wir(0xc7,1); //改變1602內部地址寄存器值,即自己挑選顯示位置
wdat(num[1]);
// wir(0xca,1);
wdat(num[3]);
wdat(num[10]);
wdat(num[1]);
wdat(num[9]);
wdat(num[11]);
*/
//控制1602顯示可以采用“寫坐標+寫數據”,“寫坐標+寫數據”在屏上特定位置顯示一個字,
//也可以寫入一個坐標后不斷寫入數據,直到該屏幕的最末(如上例)。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -