1. 程式人生 > >51小東西霍爾計數器

51小東西霍爾計數器

很久沒有碰51了,  發現對於暫存器操作又程式設計大一那時候,啥也不懂了,對於本次這個小東西,還特意去圖書館借了三本51微控制器的書籍來看,頓時茅塞頓開。這個小東西需要一個顯示的東西來讓使用者看到此時的計件數目,我選了1602模組,本來想用數碼管的,  但是數碼管感覺好簡單的樣子。。。。木有時序的操作。。。這也是我做東西以來第一次用1602。。。說來也是慚愧。。。好了 ,再次接下來是用了3144的霍爾模組來測試程式的可行性。。。這裡要注意區分感測器的類別,霍爾分為開關型和線性型的,一個輸出數字量,一個輸出模擬量。這個百度一下就知道了。


大概就是這個樣子= =、

接下來是程式碼咯。

首先是LCD部分

#include"lcd.h"


/*******************************************************************************
* 函 數 名         : Lcd1602_Delay1ms
* 函式功能  : 延時函式,延時1ms
* 輸    入         : c
* 輸    出         : 無
* 說    名         : 該函式是在12MHZ晶振下,12分頻微控制器的延時。
*******************************************************************************/


void Lcd1602_Delay1ms(uint c)   //誤差 0us
{
    uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
 for(a=1;a>0;a--);
}      
}
   
}


/*******************************************************************************
* 函 數 名         : LcdWriteCom
* 函式功能  : 向LCD寫入一個位元組的命令
* 輸    入         : com
* 輸    出         : 無
*******************************************************************************/
#ifndef LCD1602_4PINS//當沒有定義這個LCD1602_4PINS時
void LcdWriteCom(uchar com) //寫入命令
{
LCD1602_E = 0;     //使能
LCD1602_RS = 0;  //選擇傳送命令
LCD1602_RW = 0;  //選擇寫入

LCD1602_DATAPINS = com;     //放入命令
Lcd1602_Delay1ms(1);//等待資料穩定


LCD1602_E = 1;         //寫入時序
Lcd1602_Delay1ms(5); //保持時間
LCD1602_E = 0;
}
#else 
void LcdWriteCom(uchar com) //寫入命令
{
LCD1602_E = 0;//使能清零
LCD1602_RS = 0;//選擇寫入命令
LCD1602_RW = 0;//選擇寫入


LCD1602_DATAPINS = com;//由於4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);


LCD1602_E = 1;//寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;


//Lcd1602_Delay1ms(1);
LCD1602_DATAPINS = com << 4; //傳送低四位
Lcd1602_Delay1ms(1);


LCD1602_E = 1;//寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 數 名         : LcdWriteData
* 函式功能  : 向LCD寫入一個位元組的資料
* 輸    入         : dat
* 輸    出         : 無
*******************************************************************************/  
#ifndef LCD1602_4PINS  
void LcdWriteData(uchar dat)//寫入資料
{
LCD1602_E = 0;//使能清零
LCD1602_RS = 1;//選擇輸入資料
LCD1602_RW = 0;//選擇寫入


LCD1602_DATAPINS = dat; //寫入資料
Lcd1602_Delay1ms(1);


LCD1602_E = 1;   //寫入時序
Lcd1602_Delay1ms(5);   //保持時間
LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)//寫入資料
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //選擇寫入資料
LCD1602_RW = 0; //選擇寫入


LCD1602_DATAPINS = dat;//由於4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);


LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;


LCD1602_DATAPINS = dat << 4; //寫入低四位
Lcd1602_Delay1ms(1);


LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 數 名       : LcdInit()
* 函式功能: 初始化LCD屏
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/  
#ifndefLCD1602_4PINS
void LcdInit() //LCD初始化子程式
{
 LcdWriteCom(0x38);  //開顯示
LcdWriteCom(0x0c);  //開顯示不顯示游標
LcdWriteCom(0x06);  //寫一個指標加1
LcdWriteCom(0x01);  //清屏
LcdWriteCom(0x80);  //設定資料指標起點
}
#else
void LcdInit() //LCD初始化子程式
{
LcdWriteCom(0x32);//將8位匯流排轉為4位匯流排
LcdWriteCom(0x28);//在四位線下的初始化
LcdWriteCom(0x0c);  //開顯示不顯示游標
LcdWriteCom(0x06);  //寫一個指標加1
LcdWriteCom(0x01);  //清屏
LcdWriteCom(0x80);  //設定資料指標起點
}
#endif

然後是main



#include <reg51.h>  //此檔案中定義了51的一些特殊功能暫存器
#include <intrins.h>
#include"lcd.h"




//--定義全域性變數--//
unsigned char PuZh[14]="The amount is:";
unsigned char ge, shi, bai, qian, wan;


//--定義要使用的IO口--//
#define  GPIO_KEY P1  //獨立鍵盤用P1口
//#define  GPIO_LED P0  //led使用P0口


//--宣告全域性函式--//
void Delay10ms(unsigned int c);   //延時10ms
unsigned char Key_Scan();


/*******************************************************************************
* 函 數 名         : main
* 函式功能  : 主函式
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void main(void)
{
//unsigned char  keyNum;
unsigned char i;
EA = 1;
EX0 = 1;
IT0 = 1;



LcdInit();
for(i=0; i<14; i++)
{
if(i == 14)
{
LcdWriteCom(0x80 + 0x40 );  //+ 0x40
}
LcdWriteData(PuZh[i]);
}



while (1)
{
//keyNum = Key_Scan();  //掃描鍵盤
LcdWriteCom(0x80 + 0x4f);
LcdWriteData('0' + ge);


LcdWriteCom(0x80 + 0x4e);
LcdWriteData('0' + shi);


LcdWriteCom(0x80 + 0x4d);
LcdWriteData('0' + bai);


LcdWriteCom(0x80 + 0x4c);
LcdWriteData('0' + qian);


LcdWriteCom(0x80 + 0x4b);
LcdWriteData('0' + wan);
if(ge>9) 
{
ge = 0;
shi++;
}


if(shi>9) 
{
shi = 0;
bai++;
}


if(bai>9) 
{
bai = 0;
qian++;
}


if(qian>9) 
{
qian = 0;
wan++;
}


if(wan>9) 
{
ge = 0;
shi = 0;
bai = 0;
qian = 0;
wan = 0;
}
}
}








 /*******************************************************************************
* 函 數 名         : Delay10ms
* 函式功能  : 延時函式,延時10ms
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void ex0_int() interrupt 0
{
EA = 0;
ge++;
EA = 1;
}




/*******************************************************************************
* 函 數 名         : Delay10ms
* 函式功能  : 延時函式,延時10ms
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/


//void Delay10ms(unsigned int c)   //誤差 0us
//{
//    unsigned char a, b;
//
////--c已經在傳遞過來的時候已經賦值了,所以在for語句第一句就不用賦值了--//
//    for (;c>0;c--)
//{
//for (b=38;b>0;b--)
//{
//for (a=130;a>0;a--);
//}
//           
//}       
//}

註釋懶得刪除了,  用開發板的程式隨便改了下就行。   不過特別注意中斷部分,微控制器最重要的莫過於中斷和定時器了,  這裡就不在大神們面前班門弄斧了。其實就是通過依靠外部中斷來實現。