SOGO論壇
  登入   註冊   找回密碼
查看: 1503|回覆: 1
列印 上一主題 下一主題

[程式設計] 請問要加入可輸入溫度值的矩陣鍵盤要如何寫? [複製連結]

Rank: 2

狀態︰ 離線
跳轉到指定樓層
1
發表於 2013-10-21 15:10:49 |只看該作者 |倒序瀏覽 | x 1
//****************************************************************//
// DHT21 8051範例程式
//功能 :透過RS232串列埠將溫濕度資料傳送回電腦端,串列埠傳輸速率 9600
//硬體連接: P2.0上拉電阻5K連接DHT11的PIN2
// PIN1接電源, PIN4接地
//****************************************************************//

#include <AT89X51.H>
#include <intrins.h>
//****************************************************************//??
#define RS P3_7                                           /*定義LCD,RS*/
#define RW P3_6                                           /*定義LCD,RW*/
#define E P3_5                                           /*定義LCD,E*/
#define DB P1                                           /*定義LCD,DB*/
void init(void);                                   /*宣告用到init程式*/
void position(char line,column);  /*宣告用到position副程式*/
void wrins(char instruction);           /*宣告用到wrins副程式*/
void display(char *string);           /*宣告用到wrdata副程式*/
void wrdata(char d);                            /*宣告用到delayms副程式*/
void delayms(unsigned int time);
char keypad(void);
void WriteLCDstring(char,char *);
unsigned char KeyTemp=0xff;
unsigned char KeyData=0xff;
//****************************************************************//
typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 無符號8位元整數 */
typedef signed char S8; /* defined for signed 8-bits integer variable 有符號8位元整數 */
typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 無符號16位元整數 */
typedef signed int S16; /* defined for signed 16-bits integer variable 有符號16位元整數 */
typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 無符號32位元整數 */
typedef signed long S32; /* defined for signed 32-bits integer variable 有符號32位元整數 */
typedef float F32; /* single ecision floating point variable (32bits) 單精確度浮點數(32位長度) */
typedef double F64; /* double precision floating point variable (64bits) 雙精確度浮點數(64位長度) */

#define uchar unsigned char
#define uint unsigned int
#define Data_0_time 4

//----------------------------------------------//
//----------------定義區--------------------//
//----------------------------------------------//
U8 U8FLAG1,k1;
U8 U8count1,U8temp1;
U8 U8T_data_H1,U8T_data_L1,U8RH_data_H1,U8RH_data_L1,U8checkdata1;
U8 U8T_data_H_temp1,U8T_data_L_temp1,U8RH_data_H_temp1,U8RH_data_L_temp1,U8checkdata_temp1;
U8 U8comdata1;
//----------------------------------------------//
//----------------定義區--------------------//
//----------------------------------------------//
U8 U8FLAG2,k2;
U8 U8count2,U8temp2;
U8 U8T_data_H2,U8T_data_L2,U8RH_data_H2,U8RH_data_L2,U8checkdata2;
U8 U8T_data_H_temp2,U8T_data_L_temp2,U8RH_data_H_temp2,U8RH_data_L_temp2,U8checkdata_temp2;
U8 U8comdata2;
//----------------------------------------------//
//----------------定義區--------------------//
//----------------------------------------------//
U8 outdata[5]; //定義發送的位元組數
U8 indata[5];
U8 count, count_r=0;
U8 str2[5]={"%"};
U8 str1[5]={"C"};
code char string1[]="F1:display";      /*宣告字串*/
code char string2[]="F2:enter";
//code char string[];
U16 U16temp1,U16temp2;
/*void SendData(U8 *a)
{
outdata[0] = a[0];
outdata[1] = a[1];
outdata[2] = a[2];
outdata[3] = a[3];
outdata[4] = a[4];
count = 1;
SBUF=outdata[0];
}*/

//延遲100us
void Delay(U16 j)
{
U8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);

}
}

//延遲10us
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}

void COM1(void)
{

U8 i;
for(i=0;i<8;i++)
{

U8FLAG1=2;
//----------------------
P2_1=0 ; //T
P2_1=1 ; //T
//----------------------

while((!P2_0)&&U8FLAG1++);
Delay_10us();
Delay_10us();
// Delay_10us();
U8temp1=0;
if(P2_0)U8temp1=1;
U8FLAG1=2;
while((P2_0)&&U8FLAG1++);

//----------------------
P2_1=0 ; //T
P2_1=1 ; //T
//----------------------
//超時則跳出for迴圈
if(U8FLAG1==1)break;
//判斷資料位元是0還是1

// 如果高電壓高過預定0高電平值則資料位元為 1

U8comdata1<<=1;
U8comdata1|=U8temp1; //0
}//rof
}

//--------------------------------
//-----濕度讀取副程式 ------------
//--------------------------------
//----以下變數均為全域變數--------
//----溫度高8位元== U8T_data_H1------
//----溫度低8位元== U8T_data_L1------
//----濕度高8位== U8RH_data_H1-----
//----濕度低8位== U8RH_data_L1-----
//----校驗 8位 == U8checkdata1-----
//----調用相關副程式如下----------
//---- Delay();, Delay_10us();,COM();
//--------------------------------

void RH1(void)
{
//主機拉低18ms
P2_0=0;
Delay(180);
P2_0=1;
//匯流排由上拉電阻拉高 主機延時20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主機設為輸入 判斷從機回應信號
P2_0=1;
//判斷從機是否有低電平回應信號 如不回應則跳出,回應則向下運行
if(!P2_0) //T !
{
U8FLAG1=2;
//判斷從機是否發出 80us 的低電平回應信號是否結束
while((!P2_0)&&U8FLAG1++);
U8FLAG1=2;
//判斷從機是否發出 80us 的高電平,如發出則進入資料接收狀態
while((P2_0)&&U8FLAG1++);
//資料接收狀態
COM1();
U8RH_data_H_temp1=U8comdata1;
COM1();
U8RH_data_L_temp1=U8comdata1;
COM1();
U8T_data_H_temp1=U8comdata1;
COM1();
U8T_data_L_temp1=U8comdata1;
COM1();
U8checkdata_temp1=U8comdata1;
P2_0=1;
//資料校驗

U8temp1=(U8T_data_H_temp1+U8T_data_L_temp1+U8RH_data_H_temp1+U8RH_data_L_temp1);
if(U8temp1==U8checkdata_temp1)
{
U8RH_data_H1=U8RH_data_H_temp1;
U8RH_data_L1=U8RH_data_L_temp1;
U8T_data_H1=U8T_data_H_temp1;
U8T_data_L1=U8T_data_L_temp1;
U8checkdata1=U8checkdata_temp1;
}//fi
}//fi

}
void COM2(void)
{

U8 i;
for(i=0;i<8;i++)
{

U8FLAG2=2;
//----------------------
P2_3=0 ; //T
P2_3=1 ; //T
//----------------------

while((!P2_2)&&U8FLAG2++);
Delay_10us();
Delay_10us();
// Delay_10us();
U8temp2=0;
if(P2_2)U8temp2=1;
U8FLAG2=2;
while((P2_2)&&U8FLAG2++);

//----------------------
P2_3=0 ; //T
P2_3=1 ; //T
//----------------------
//超時則跳出for迴圈
if(U8FLAG2==1)break;
//判斷資料位元是0還是1

// 如果高電壓高過預定0高電平值則資料位元為 1

U8comdata2<<=1;
U8comdata2|=U8temp2; //0
}//rof
}

//--------------------------------
//-----濕度讀取副程式 ------------
//--------------------------------
//----以下變數均為全域變數--------
//----溫度高8位元== U8T_data_H2------
//----溫度低8位元== U8T_data_L2------
//----濕度高8位== U8RH_data_H2-----
//----濕度低8位== U8RH_data_L2-----
//----校驗 8位 == U8checkdata2-----
//----調用相關副程式如下----------
//---- Delay();, Delay_10us();,COM();
//--------------------------------

void RH2(void)
{
//主機拉低18ms
P2_2=0;
Delay(180);
P2_2=1;
//匯流排由上拉電阻拉高 主機延時20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主機設為輸入 判斷從機回應信號
P2_2=1;
//判斷從機是否有低電平回應信號 如不回應則跳出,回應則向下運行
if(!P2_2) //T !
{
U8FLAG2=2;
//判斷從機是否發出 80us 的低電平回應信號是否結束
while((!P2_2)&&U8FLAG2++);
U8FLAG2=2;
//判斷從機是否發出 80us 的高電平,如發出則進入資料接收狀態
while((P2_2)&&U8FLAG2++);
//資料接收狀態
COM2();
U8RH_data_H_temp2=U8comdata2;
COM2();
U8RH_data_L_temp2=U8comdata2;
COM2();
U8T_data_H_temp2=U8comdata2;
COM2();
U8T_data_L_temp2=U8comdata2;
COM2();
U8checkdata_temp2=U8comdata2;
P2_2=1;
//資料校驗

U8temp2=(U8T_data_H_temp2+U8T_data_L_temp2+U8RH_data_H_temp2+U8RH_data_L_temp2);
if(U8temp2==U8checkdata_temp2)
{
U8RH_data_H2=U8RH_data_H_temp2;
U8RH_data_L2=U8RH_data_L_temp2;
U8T_data_H2=U8T_data_H_temp2;
U8T_data_L2=U8T_data_L_temp2;
U8checkdata2=U8checkdata_temp2;
}//fi
}//fi

}

//----------------------------------------------
//main()功能描述: AT89C51 11.0592MHz 串列埠發
//送溫濕度資料,串列傳輸速率 9600
//----------------------------------------------
void main()
{
  init();
  position(1,1);
  display(string1);
  position(2,1);
  display(string2);
  while(1);
//uchar str[6]={"RS232"};
/* 系統初始化 */
TMOD = 0x20; //計時器T1使用工作方式2
TH1 = 253; // 設置初值
TL1 = 253;
TR1 = 1; // 開始計時
SCON = 0x50; //工作方式1,串列傳輸速率9600bps,允許接收
ES = 1;
EA = 1; // 打開所以中斷
TI = 0;
RI = 0;
// SendData(str) ; //發送到串列埠
Delay(1); //延時100US(12M晶振)
while(1);
if(KeyData=0xff)
{

//------------------------
//調用溫濕度讀取副程式
RH1();
RH2();
//串列埠顯示程式
//--------------------------
str1[0]=U8T_data_H1 /10 +0X30;
str1[1]=U8T_data_H1 %10 +0X30;
str2[0]=U8T_data_H2 /10 +0X30;
str2[1]=U8T_data_H2 %10 +0X30;

// SendData(str) ; //發送到串列埠
//讀取模組資料週期不易小於 2S
Delay(2000);
init();

position(1,1);
//choice();
display(str1);
position(2,1);
//choice();
display(str2);
}//elihw

}// main
void init(void)
{
delayms(30);
wrins(0x38);
wrins(0x38);
wrins(0x38);
wrins(0x38);

wrins(0x08);
wrins(0x01);

wrins(0x06);
wrins(0x0c);
}
void position(char line,column)
{
unsigned char instruction;
line--;
column--;
instruction=0x80+(0x40*line + column);
wrins(instruction);

}
void wrins(char instruction)
{
RS=0;
RW=0;
E=0;
delayms(1);
E=1;
DB=instruction;
delayms(1);
E=0;
delayms(8);
}

void display(char *string)
{
char k1=0;
while(string[k1] !=0x00)
{
wrdata(string[k1]);
k1++;
}
}

void wrdata(char d)
{
RS=1;
RW=0;
E=0;
delayms(1);
E=1;
DB=d;
delayms(1);
E=0;
delayms(1);
}

void delayms(unsigned int time)
{
unsigned int n;
while(time>0)
{
n=120;
while(n>0) n--;
time--;
}
}
喜歡嗎?分享這篇文章給親朋好友︰
               感謝作者     

Rank: 4

數位軟體勳章

狀態︰ 離線
2
發表於 2013-10-21 19:18:49 |只看該作者
提供一個 4*4 keypad 掃描程式,供參考!先模仿別人怎樣寫程式,融會貫通 。
  1. unsigned char keypad()                        // 讀取 4 X 4 小鍵盤的按鍵   副程式
  2. {
  3.         unsigned char value;                        // keypad 輸入值
  4.         unsigned char scanline[] = {0xfe,0xfd,0xfb,0xf7};                // 掃描線  1110   1101   1011   0111
  5.         unsigned char col,row,temp;        // 宣告行列變數
  6.         value = 0xff;                                        // 設定鍵盤初始值
  7.         for(row=0 ; row<4 ; row++)                // 列掃描 4 次
  8.         {
  9.                 P1 = scanline[row];                        // 輸出掃描線
  10.                 temp = P1 & 0xf0;                        // 讀取偵測線          左nibble
  11.                 if(temp != 0xf0)                         // 有某一個按鍵被按到           有按鍵輸入
  12.                 {
  13.                         os_wait2(K_TMO,1);                // debounce 10 mS
  14.                         if(temp != 0xf0)
  15.                         {
  16.                                 for(col=0 ; col<4 ; col++)        // 行掃描 4 次
  17.                                 {
  18.                                         if(temp == ((scanline[col] & 0x0f) << 4))                // 左移 4 bit                  右 nibble
  19.                                         {
  20.                                                 value = row * 4 + col;                                                // 計算鍵值公式
  21.                                                 while((P1 & 0xf0) != 0xf0);                                // 等待按鍵放開
  22.                                         }
  23.                                 }
  24.                         }
  25.                 }
  26.         }
  27.         return value;                                        // 傳回按鍵值 0 ~ 15 ,無按鍵輸入傳回 0xff
  28. }
複製代碼
已有 1 人評分威望 收起 理由
紅塵孤鳥 + 2 感謝您熱心幫助會員解決問題,論壇需要您的.

總評分: 威望 + 2   查看全部評分

請注意︰利用多帳號發表自問自答的業配文置入性行銷廣告者,將直接禁訪或刪除帳號及全部文章!
您需要登錄後才可以回覆 登入 | 註冊


本論壇為非營利自由討論平台,所有個人言論不代表本站立場。文章內容如有涉及侵權,請通知管理人員,將立即刪除相關文章資料。侵權申訴或移除要求:abuse@oursogo.com

GMT+8, 2024-4-25 10:19

© 2004-2024 SOGO論壇 OURSOGO.COM
回頂部