//實例81:用LCD顯示字符'A'
#include<reg51.h> //包含單片機寄存器的頭文件
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
//#define LED_PORT P1
//unsigned char led_pattern = 0xFE;
//bit led_mode = 0; // 0-流水燈模式 1-全亮模式
#define GPIO_KEY P1
unsigned char KeyValue; //用來存放讀取到的鍵值
sbit RS=P2^0; //寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P2^1; //讀寫選擇位,將RW位定義為P2.1引腳
sbit E= P2^2; //使能信號位,將E位定義為P2.2引腳
sbit BF=P0^7; //忙碌標志位,,將BF位定義為P0.7引腳
bit buzzer_flag = 0; //設立中斷標志位為FLAG=0;
sbit BUZZER=P2^6;
sbit KEY1=P3^0;
sbit KEY2=P3^1;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
sbit KEY5=P3^4;
void key();
//unsigned char i;
//void Delay500ms();
void delay_ms(unsigned int ms) {
unsigned int i, j;
for(i=0; i<ms; i++)
for(j=0; j<120; j++);
}
//void timer0_init() {
// TMOD = 0x01; // 定時器0模式1
// TH0 = 0xFC; // 1ms定時初值
// TL0 = 0x66;
// ET0 = 1; // 允許定時器0中斷
// TR0 = 1; // 啟動定時器0
//}
//
//void int0_init() {
// IT0 = 1; // 邊沿觸發
// EX0 = 1; // 允許外部中斷0
// EA = 1; // 開總中斷
//}
//
//void int1_init() {
// IT1 = 1; // 邊沿觸發
// EX1 = 1; // 允許外部中斷1
// EA = 1; // 開總中斷
//}
/*****************************************************
函數功能:延時1us
***************************************************/
void delay_us(uint i)
{
while(--i);
}
/*****************************************************
函數功能:延時1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒
***************************************************/
//void delay1ms()
//{
// unsigned char i,j;
// for(i=0;i<10;i++)
// for(j=0;j<33;j++)
// ;
// }
/*****************************************************
函數功能:延時若干毫秒
入口參數:n
***************************************************/
/*****************************************************
函數功能:判斷液晶模塊的忙碌狀態
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
unsigned char BusyTest(void)
{
bit result;
RS=0; //根據規定,RS為低電平,RW為高電平時,可以讀狀態
RW=1;
E=1; //E=1,才允許讀寫
delay_us(4); //延時4微秒,給硬件反應時間
result=BF; //將忙碌標志電平賦給result
E=0;
return result;
}
/*****************************************************
函數功能:將模式設置指令或顯示地址寫入液晶模塊
入口參數:dictate
***************************************************/
void Write_order_add (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根據規定,RS和R/W同時為低電平時,可以寫入指令
RW=0;
E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,
delay_us(2); //延時4微秒,給硬件反應時間 // 就是讓E從0到1發生正跳變,所以應先置"0"
P0=dictate; //將數據送入P0口,即寫入指令或地址
delay_us(4); //延時4微秒,給硬件反應時間
E=1; //E置高電平
delay_us(4); //延時4微秒,給硬件反應時間//空操作四個機器周期,給硬件反應時間
E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊
入口參數:y(為字符常量)
***************************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS為高電平,RW為低電平時,可以寫入數據
RW=0;
E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,
// 就是讓E從0到1發生正跳變,所以應先置"0"
P0=y; //將數據送入P0口,即將數據寫入液晶模塊
delay_us(4); //延時4微秒,給硬件反應時間
E=1; //E置高電平
delay_us(4); //延時4微秒,給硬件反應時間
E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:對LCD的顯示模式進行初始化設置
***************************************************/
void LcdInit(void)
{
delay_ms(15); //延時15ms,首次寫指令時應給LCD一段較長的反應時間
Write_order_add(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
delay_ms(5); //延時5ms
Write_order_add(0x38);
delay_ms(5);
Write_order_add(0x38);
delay_ms(5);
Write_order_add(0x0E); //(0x0c、0x0d、0x0e、0x0f顯示模式設置:顯示開,有光標,光標閃爍
delay_ms(5);
Write_order_add(0x06); //(0x04、0x06、0x07顯示模式設置:光標右移,字符不移
delay_ms(5);
Write_order_add(0x01); //清屏幕指令,將以前的顯示內容清除
delay_ms(5);
}
void main(void) //主函數
{
unsigned int i;
// timer0_init();
// int0_init();
// int1_init();
LcdInit();
// LED_PORT = 0xFF; //調用LCD初始化函數
while(1) {
if(buzzer_flag){
BUZZER = ~BUZZER;
delay_ms(1);
i++;
if(i >= 200) {
i = 0;
buzzer_flag = 0;
}
}
key();
}
}
//void timer0_isr() interrupt 1 {
// TH0 = 0xFC;
// TL0 = 0x66;
//
//
// // 定時器中斷服務程序
//}
//void int1_isr() interrupt 2 {
//// LED_PORT = 0x1F; // 所有LED亮 F8
//// delay_ms(2000); // 保持亮1秒
//// LED_PORT = 0xFF; // LED熄滅
//// Write_order_add(0xC7);
//// WriteData('L'); //將字符常量'A'寫入液晶模塊
//// WriteData('O');
//// WriteData('S');
//// WriteData('E');
//// WriteData(' ');
//// WriteData(' ');
//}
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
{
delay_ms(20);//延時10ms進行消抖
if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
{
//測試列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07): KeyValue=1;break;
case(0X0b): KeyValue=2;break;
case(0X0d): KeyValue=3;break;
case(0X0e): KeyValue=4;break;
}
//測試行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue;break;
case(0Xb0): KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0): KeyValue=KeyValue+12;break;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //檢測按鍵松手檢測
{
delay_ms(20);
a++;
}
}
}
}
void LCD_Dis(unsigned char p1, unsigned char p2)
{
buzzer_flag = 1;
Write_order_add(0xC7);
WriteData(p1); //將字符常量'A'寫入液晶模塊
WriteData(p2); //將字符常量'A'寫入液晶模塊
}
void key()
{
KeyDown();
switch(KeyValue){
case 1: LCD_Dis('1', ' '); break;
case 2: LCD_Dis('2', ' '); break;
case 3: LCD_Dis('3', ' '); break;
case 4: LCD_Dis('4', ' '); break;
case 5: LCD_Dis('5', ' '); break;
case 6: LCD_Dis('6', ' '); break;
case 7: LCD_Dis('7', ' '); break;
case 8: LCD_Dis('8', ' '); break;
case 9: LCD_Dis('9', ' '); break;
case 10: LCD_Dis('1', '0'); break;
case 11: LCD_Dis('1', '1'); break;
case 12: LCD_Dis('1', '2'); break;
case 13: LCD_Dis('1', '3'); break;
case 14: LCD_Dis('1', '4'); break;
case 15: LCD_Dis('1', '5'); break;
case 16: LCD_Dis('1', '6'); break;
}
KeyValue = 0;
if(!KEY1)
{
delay_ms(20);
while(!KEY1);
buzzer_flag = 1;
Write_order_add(0xC7);
WriteData('1'); //將字符常量'A'寫入液晶模塊
WriteData('7'); //將字符常量'A'寫入液晶模塊
}
if(!KEY2)
{
delay_ms(20);
while(!KEY2);
buzzer_flag = 1;
Write_order_add(0xC7);
WriteData('1'); //將字符常量'A'寫入液晶模塊
WriteData('8'); //將字符常量'A'寫入液晶模塊
}
if(!KEY3)
{
delay_ms(20);
while(!KEY3);
buzzer_flag = 1;
Write_order_add(0xC7);
WriteData('1'); //將字符常量'A'寫入液晶模塊
WriteData('9'); //將字符常量'A'寫入液晶模塊
}
if(!KEY4)
{
delay_ms(20);
while(!KEY4);
buzzer_flag = 1;
Write_order_add(0xC7);
WriteData('2'); //將字符常量'A'寫入液晶模塊
WriteData('0'); //將字符常量'A'寫入液晶模塊
}
if(!KEY5)
{
delay_ms(20);
while(!KEY5);
buzzer_flag = 0;
Write_order_add(0xC7); //將顯示地址指定為第1行第8列
WriteData(' '); //將字符常量'A'寫入液晶模塊
WriteData(' ');
}
// if(!KEY11)
// {
// delay_ms(20);
// while(!KEY11);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('9'); //將字符常量'A'寫入液晶模塊
// WriteData(' '); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY12)
// {
// delay_ms(20);
// while(!KEY12);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('0'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY13)
// {
// delay_ms(20);
// while(!KEY13);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY14)
// {
// delay_ms(20);
// while(!KEY14);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('2'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY15)
// {
// delay_ms(20);
// while(!KEY15);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('3'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY16)
// {
// delay_ms(20);
// while(!KEY16);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('4'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY17)
// {
// delay_ms(20);
// while(!KEY17);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('5'); //將字符常量'A'寫入液晶模塊
// }
// if(!KEY18)
// {
// delay_ms(20);
// while(!KEY18);
// buzzer_flag = 1;
// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
// WriteData('1'); //將字符常量'A'寫入液晶模塊
// WriteData('6'); //將字符常量'A'寫入液晶模塊
// }
}
//void int0_isr() interrupt 0 {
//// buzzer_flag = ~buzzer_flag;// 切換蜂鳴器狀態
//// LED_PORT = 0x7F; // 所有LED亮 FB
//// delay_ms(2000); // 保持亮1秒
//// LED_PORT = 0xFF; // LED熄滅
//// Write_order_add(0xC7); //將顯示地址指定為第1行第8列
//// WriteData('S'); //將字符常量'A'寫入液晶模塊
//// WriteData('U');
//// WriteData('C');
//// WriteData('C');
//// WriteData('E');
//// WriteData('S');
//
// //字符的字形點陣讀出和顯示由液晶模塊自動完成
//}
//
//void Delay500ms() //@12.000MHz
//{
// unsigned char i, j, k;
// i = 4;
// j = 205;
// k = 187;
// do
// {
// do
// {
// while (--k);
// } while (--j);
// } while(--i);
//}
|