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