首頁>Club>
4
回覆列表
  • 1 # 程式開發許可權

    #include<reg52.h> //宣告包含51標頭檔案

    #include<stdio.h> //宣告包含輸入輸出函式

    #include<intrins.h> //宣告包含位移函式

    #define uchar unsigned char // 宏定義

    #define uint unsigned int // 宏定義

    #define CHECK_BUSY

    sbit RS = P3^5; //液晶引腳定義

    sbit RW = P3^6;

    sbit EN = P3^4;

    sbit wela=P2^7;//數碼管引腳定義

    sbit dula=P2^6;

    void DelayMs(int z)// 1ms延時函式

    {

    int x,y;

    for (x=z;x>0;x--)

    for(y=110;y>0;y--);

    }

    /***********LED判忙函式***********/

    bit LCD_Check_Busy()

    {

    #ifdef CHECK_BUSY

    P0= 0xFF;

    RS=0;

    RW=1;

    EN=0;

    _nop_();

    EN=1;

    return (bit)(P0 & 0x80);

    #else

    return 0;

    #endif

    }

    /***********LED寫入命令函式***********/

    void write_com(uchar com)

    {

    while(LCD_Check_Busy()); //忙則等待

    RS=0;

    RW=0;

    EN=1;

    P0= com;

    _nop_();

    EN=0;

    }

    /**********LED寫入資料函式**********/

    void write_dat(uchar dat)

    {

    while(LCD_Check_Busy()); //忙則等待

    RS=1;

    RW=0;

    EN=1;

    P0= dat;

    _nop_();

    EN=0;

    }

    /*******LED寫入字元函式***********/

    void LCD_Write_Char(uchar x,uchar y,uchar dat)

    {

    if (y == 0)

    {

    write_com(0x80 + x);

    }

    else

    {

    write_com(0xC0 + x);

    }

    write_dat( dat);

    }

    /******寫入字串函式***********/

    void Write_String(uchar x,uchar y,uchar *s)

    {

    while (*s)

    {

    LCD_Write_Char(x,y,*s);

    s++;

    x++;

    }

    }

    /*****LED初始化函式******/

    void LCD_Init()

    {

    RW=0;

    dula=0; //關閉數碼管顯示

    wela=0; //關閉數碼管顯示

    write_com(0x38); /*顯示模式設定*/

    DelayMs(5);

    write_com(0x06);/*顯示游標移動設定*/

    DelayMs(5);

    write_com(0x0C); /*顯示開及游標設定*/

    write_com(0x01); /*顯示清屏*/

    }

    /*按鍵掃描函式,返回掃描鍵值*/

    uchar KeyScan() //鍵盤掃描函式,使用行列反轉掃描法

    {

    unsigned char cord_h,cord_l;//行列值中間變數

    P3=0x0f; //行線輸出全為0

    cord_h=P3&0x0f; //讀入列線值

    if(cord_h!=0x0f) //先檢測有無按鍵按下

    {

    DelayMs(10); //去抖

    if((P3&0x0f)!=0x0f)

    {

    cord_h=P3&0x0f; //讀入列線值

    P3=cord_h|0xf0; //輸出當前列線值

    cord_l=P3&0xf0; //讀入行線值

    while((P3&0xf0)!=0xf0);//等待鬆開並輸出

    return(cord_h+cord_l);//鍵盤最後組合碼值

    }

    }

    return(0xff); //返回該值

    }

    unsigned char KeyPro()

    {

    switch(KeyScan())

    {

    case 0xee:return "1";break;//0 按下相應的鍵顯示相對應的碼值

    case 0xed:return "2";break;//1

    case 0xeb:return "3";break;//2

    case 0x7e:return "+";break;//3

    case 0xe7:return "4";break;//4

    case 0xde:return "5";break;//5

    case 0xdd:return "6";break;//6

    case 0x7d:return "-";break;//7

    case 0xdb:return "7";break;//8

    case 0xd7:return "8";break;//9

    case 0xbe:return "9";break;//a

    case 0x7b:return "x";break;//b

    case 0xbd:return "0";break;//c

    case 0xbb:return ".";break;//d

    case 0xb7:return "=";break;//e

    case 0x77:return "/";break;//f

    default:return 0xff;break;

    }

    }

    main()

    {

    unsigned char num,i,sign;

    unsigned char temp[16]; //最大輸入16個

    bit firstflag;

    float a=0,b=0;

    unsigned char s;

    LCD_Init(); //初始化液晶屏

    DelayMs(10);//延時用於穩定,可以去掉

    write_com(0x01); //清屏

    Write_String(0,0,"I LIKE MCU"); //寫入第一行資訊,主迴圈中不再更改此資訊,所以在while之前寫入

    Write_String(0,1,"QXMCU"); //寫入第二行資訊,提示輸入密碼

    for(s=0;s<25;s++)//延時5s

    DelayMs(200);

    write_com(0x01);

    while (1) //主迴圈

    {

    num=KeyPro(); //掃描鍵盤

    if(num!=0xff) //如果掃描是按鍵有效值則進行處理

    {

    if(i==0) //輸入是第一個字元的時候需要把改行清空,方便觀看

    write_com(0x01);

    if(("+"==num)|| (i==16) || ("-"==num) || ("x"==num)|| ("/"==num) || ("="==num))//輸入數字最大值16,輸入符號表示輸入結束

    {

    i=0; //計數器復位

    if(firstflag==0) //如果是輸入的第一個資料,賦值給a,並把標誌位置1,到下一個資料輸入時可以跳轉賦值給b

    {

    sscanf(temp,"%f",&a);

    firstflag=1;

    }

    else

    sscanf(temp,"%f",&b);

    for(s=0;s<16;s++) //賦值完成後把緩衝區清零,防止下次輸入影響結果

    temp[s]=0;

    LCD_Write_Char(0,1,num);

    ///////////////////////

    if(num!="=") //判斷當前符號位並做相應處理

    sign=num; //如果不是等號記下標誌位

    else

    {

    firstflag=0; //檢測到輸入=號,判斷上次讀入的符合

    switch(sign)

    {

    case "+":a=a+b;

    break;

    case "-":a=a-b;

    break;

    case "x":a=a*b;

    break;

    case "/":a=a/b;

    break;

    default:break;

    }

    sprintf(temp,"%g",a); //輸出浮點型,無用的0不輸出

    Write_String(1,1,temp);//顯示到液晶屏

    sign=0;a=b=0; //用完後所有資料清零

    for(s=0;s<16;s++)

    temp[s]=0;

    }

    }

    else if(i<16)

    {

    if((1==i)&& (temp[0]=="0") )//如果第一個字元是0,判讀第二個字元

    {

    if(num==".") //如果是小數點則正常輸入,游標位置加1

    {

    temp[1]=".";

    LCD_Write_Char(1,0,num);//輸出資料

    i++;

    } //這裡沒有判斷連續按小數點,如0.0.0

    else

    {

    temp[0]=num; //如果是1-9數字,說明0沒有用,則直接替換第一位0

    LCD_Write_Char(0,0,num);//輸出資料

    }

    }

    else

    {

    temp[i]=num;

    LCD_Write_Char(i,0,num);//輸出資料

    i++; //輸入數值累加

    }

    }

    }

    }

    }

  • 中秋節和大豐收的關聯?
  • 盜賊練開鎖最快方法?