|
霍爾測(cè)速元件清單
1) 9*15萬用板
2) STC89C52單片機(jī)
3) 40腳IC座
4) 1602液晶
5) 16p母座
6) 16p排針
7) 10k電阻*3
8) 1k電阻
9) 3v直流電機(jī)
10) 3*1萬用板
11) 磁鐵*2
12) 201電位器
13) 3144霍爾傳感器
14) 103排阻
15) 100uf電解電容
16) 10uf電解電容
17) 30pf瓷片電容*2
18) 12M晶振
19) 自鎖開關(guān)
20) DC電源插口
21) 導(dǎo)線若干
22) 焊錫若干
23) USB電源線或電池盒
單片機(jī)程序源碼:
- #include<reg52.h> //包含頭文件
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int //宏定義
- /*************STC89單片機(jī)EEPROM參數(shù)定義和聲明********/
- #define RdCommand 0x01 //定義ISP的操作命令
- #define PrgCommand 0x02
- #define EraseCommand 0x03
- #define Error 1
- #define Ok 0
- #define WaitTime 0x01 //定義CPU的等待時(shí)間
- sfr ISP_DATA=0xe2;//寄存器申明
- sfr ISP_ADDRH=0xe3;
- sfr ISP_ADDRL=0xe4;
- sfr ISP_CMD=0xe5;
- sfr ISP_TRIG=0xe6;
- sfr ISP_CONTR=0xe7;
- char a_a;
- /********************************************/
- unsigned long temp=0;//報(bào)警上限轉(zhuǎn)速參數(shù)定義
- uchar h_w,h_q,h_b,h_s,h_g;//報(bào)警上限轉(zhuǎn)速的參數(shù)(萬、千、百、十、個(gè)位)
- /**************************************************/
- sbit COUNT_IN=P3^2;//霍爾傳感器信號(hào)輸入
- /****************************************************/
- //定義1602液晶相關(guān)管腳
- sbit rs=P2^7;
- sbit en=P2^6;
- sbit rw=P2^5;
- uchar menu;//液晶設(shè)置界面菜單
- /****************************************************/
- sbit key1=P1^1;//報(bào)警轉(zhuǎn)速參數(shù)設(shè)置按鍵
- sbit key2=P1^2;//加
- sbit key3=P1^3;//減
- sbit alarm=P1^0;//蜂鳴器報(bào)警
- /**************************************************/
- uint count,m,n; //定義計(jì)算速度變量
- unsigned long RPM=0; //定義速度變量
- unsigned long TT=0; //定義時(shí)間變量
- unsigned long sum=0; //計(jì)算平均值的總數(shù)
- unsigned char T_num=0; //平均值取值的次數(shù)
- unsigned long num=0; //單次轉(zhuǎn)速
- unsigned int TT1=0; //定義定時(shí)器中斷次數(shù)變量
- bit flag; //定義位變量,值只能是0或者1
- uchar p,sec;
- /********************************************************/
- //液晶初始化顯示定義
- uchar code tab1[]={"R:"}; //一行顯示的固定字符
- uchar code tab2[]={"r/min"}; //轉(zhuǎn)速顯示的固定字符
- uchar code tab3[]={"H:"}; //轉(zhuǎn)速顯示的固定字符
- /**************延時(shí)子函數(shù)定義************/
- void delay(uint x) //延時(shí)函數(shù),大約延時(shí)1ms,不精確
- {
- uint i,j; //定義延時(shí)函數(shù)變量
- for(i=0;i<x;i++) //for循環(huán)延時(shí)
- for(j=0;j<110;j++);
- }
- void alarming()//蜂鳴器報(bào)警子函數(shù)
- {
- alarm=0;
- delay(50);
- alarm=1;
- delay(50);
- }
- /******************************STC89單片機(jī) EERPROM函數(shù)******************/
- /*************打開 ISP,IAP 功能********************/
- void ISP_IAP_enable(void)
- {
- EA=0; //關(guān)中斷
- ISP_CONTR=ISP_CONTR&0x18; // 0001,1000
- ISP_CONTR=ISP_CONTR|WaitTime; //寫入硬件延時(shí)
- ISP_CONTR=ISP_CONTR|0x80; //ISPEN=1
- }
- /********************關(guān)閉 ISP,IAP 功能 ************/
- void ISP_IAP_disable(void)
- {
- ISP_CONTR=ISP_CONTR&0x7f; //ISPEN = 0
- ISP_TRIG=0x00;
- EA=1; //開中斷
- }
- /************公用的觸發(fā)代碼**********************/
- void ISPgoon(void)
- {
- ISP_IAP_enable();//打開 ISP,IAP 功能
- ISP_TRIG=0x46; //觸發(fā)ISP_IAP命令字節(jié)1
- ISP_TRIG=0xb9; //觸發(fā)ISP_IAP命令字節(jié)2
- _nop_();
- }
- /****************字節(jié)讀 *************************/
- unsigned char byte_read(unsigned int byte_addr)
- {
- EA=0;
- ISP_ADDRH=(unsigned char)(byte_addr>>8);//地址賦值
- ISP_ADDRL=(unsigned char)(byte_addr&0x00ff);
- ISP_CMD=ISP_CMD&0xf8;//清除低3位
- ISP_CMD=ISP_CMD|RdCommand;//寫入讀命令
- ISPgoon();//觸發(fā)執(zhí)行
- ISP_IAP_disable();//關(guān)閉ISP,IAP功能
- EA=1;
- return(ISP_DATA);//返回讀到的數(shù)據(jù)
- }
- /*****************扇區(qū)擦除 ************************/
- void SectorErase(unsigned int sector_addr)
- {
- unsigned int iSectorAddr;
- iSectorAddr=(sector_addr&0xfe00); //取扇區(qū)地址
- ISP_ADDRH=(unsigned char)(iSectorAddr>>8);
- ISP_ADDRL=0x00;
- ISP_CMD=ISP_CMD&0xf8;//清空低3位
- ISP_CMD=ISP_CMD|EraseCommand; //擦除命令3
- ISPgoon();//觸發(fā)執(zhí)行
- ISP_IAP_disable();//關(guān)閉ISP,IAP功能
- }
- /************************字節(jié)寫 *************************/
- void byte_write(unsigned int byte_addr, unsigned char original_data)
- {
- EA=0;
- ISP_ADDRH=(unsigned char)(byte_addr>>8);//取地址
- ISP_ADDRL=(unsigned char)(byte_addr & 0x00ff);
- ISP_CMD=ISP_CMD&0xf8;//清低3位
- ISP_CMD=ISP_CMD | PrgCommand;//寫命令2
- ISP_DATA=original_data;//寫入數(shù)據(jù)準(zhǔn)備
- ISPgoon();//觸發(fā)執(zhí)行
- ISP_IAP_disable();//關(guān)閉IAP功能
- EA =1;
- }
- /********************內(nèi)部eeprom寫函數(shù)**************/
- void write_eeprom()
- {
- SectorErase(0x2000);//先把扇區(qū)清空
- delay(1);
- SectorErase(0x2c00);//先把扇區(qū)清空
- delay(1);
- SectorErase(0x2d00);//先把扇區(qū)清空
- delay(1);
- /**************寫入?yún)?shù)******************/
- byte_write(0x2d00,h_w);//存萬位
- delay(1);
- byte_write(0x2d01,h_q);//存千位
- delay(1);
- byte_write(0x2d02,h_b);//存百位
- delay(1);
- byte_write(0x2d03,h_s);//存十位
- delay(1);
- byte_write(0x2d04,h_g);//存?zhèn)位
- delay(1);
-
- byte_write(0x2060,0x01);
- }
- /******************把數(shù)據(jù)從單片機(jī)內(nèi)部eeprom中讀出來*****************/
- void read_eeprom()
- {
- h_w=byte_read(0x2d00);//萬位讀回來
- delay(1);
- h_q=byte_read(0x2d01);//千位讀回來
- delay(1);
- h_b=byte_read(0x2d02);//百位讀回來
- delay(1);
- h_s=byte_read(0x2d03);//十位讀回來
- delay(1);
- h_g=byte_read(0x2d04);//個(gè)位讀回來
- delay(1);
- a_a=byte_read(0x2060);
- }
- /**************開機(jī)自檢eeprom初始化*****************/
- void init_eeprom()
- {
- a_a=byte_read(0x2060);
- if(a_a!=1) //新的單片機(jī)初始單片機(jī)內(nèi)問eeprom
- {
- a_a=1;
- write_eeprom();//保存數(shù)據(jù)
- delay(1);
- }
- }
- /********液晶寫入指令函數(shù)與寫入數(shù)據(jù)函數(shù),以后可調(diào)用**************/
- void write_1602com(uchar com)//****液晶寫入指令函數(shù)****
- {
- rs=0;//數(shù)據(jù)/指令選擇置為指令
- P0=com;//送入數(shù)據(jù)
- delay(1);
- en=1;//拉高使能端,為制造有效的下降沿做準(zhǔn)備
- delay(1);
- en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
- void write_1602dat(uchar dat)//***液晶寫入數(shù)據(jù)函數(shù)****
- {
- rs=1;//數(shù)據(jù)/指令選擇置為數(shù)據(jù)
- P0=dat;//送入數(shù)據(jù)
- delay(1);
- en=1; //en置高電平,為制造下降沿做準(zhǔn)備
- delay(1);
- en=0; //en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
- void lcd_init()//***液晶初始化函數(shù)****
- {
- uchar a;
- rw=0;
- write_1602com(0x38);//設(shè)置液晶工作模式,意思:16*2行顯示,5*7點(diǎn)陣,8位數(shù)據(jù)
- write_1602com(0x0c);//開顯示不顯示光標(biāo)
- write_1602com(0x06);//整屏不移動(dòng),光標(biāo)自動(dòng)右移
- write_1602com(0x01);//清顯示
- write_1602com(0x80);//顯示固定符號(hào)從第一行第1個(gè)位置之后開始顯示
- for(a=0;a<2;a++)
- {
- write_1602dat(tab1[a]);//向液晶屏寫固定符號(hào)部分
- }
- write_1602com(0x80+8);//顯示固定符號(hào)寫入位置,從第2個(gè)位置后開始顯示
- for(a=0;a<5;a++)
- {
- write_1602dat(tab2[a]);//寫顯示固定符號(hào)
- }
- write_1602com(0x80+0x40);//顯示固定符號(hào)寫入位置,從第2個(gè)位置后開始顯示
- for(a=0;a<2;a++)
- {
- write_1602dat(tab3[a]);//寫顯示固定符號(hào)
- }
- }
- void display() //顯示函數(shù)
- {
- if(RPM<=99999) //范圍內(nèi)時(shí)
- {
- uchar gw,sw,bw,qw,ww;//定義拆字變量
- ww=RPM/10000; //轉(zhuǎn)速/10000得到萬位
- qw=RPM%10000/1000; //轉(zhuǎn)速/10000的余數(shù)/1000得到千位
- bw=RPM%1000/100;//取得百位
- sw=RPM%100/10;//取得十位數(shù)字
- gw=RPM%10;//取得個(gè)位數(shù)字
- write_1602com(0x80+2); //選中第二行第二位
- if(ww==0) //萬位為0時(shí)
- {
- write_1602dat(' '); //顯示空格
- }
- else //萬位不為0時(shí)
- {
- write_1602dat(0x30+ww); //顯示萬位的數(shù)據(jù) +0x30是因?yàn)樵谝壕У淖謳?kù)中,0的地址是0x30,1的地址是0x31,以此類推
- }
- if((ww+qw)==0) //萬位和千位都為0時(shí)
- {
- write_1602dat(' '); //千位顯示空格
- }
- else //萬位和千位不都為0時(shí)
- {
- write_1602dat(0x30+qw); //顯示千位數(shù)據(jù)
- }
- if((ww+qw+bw)==0) //萬位、千位和百位都是0時(shí)
- {
- write_1602dat(' '); //顯示空格
- }
- else //萬位、千位和百位不都為0時(shí)
- {
- write_1602dat(0x30+bw); //顯示百位數(shù)據(jù)
- }
- if((ww+qw+bw+sw)==0) //萬位、千位、百位和十位都為0時(shí)
- {
- write_1602dat(' '); //顯示空格
- }
- else //萬位、千位、百位和十位不都為0時(shí)
- {
- write_1602dat(0x30+sw); //顯示十位數(shù)據(jù)
- }
- write_1602dat(0x30+gw); //顯示個(gè)位數(shù)據(jù) 數(shù)字+0x30得到該數(shù)字的LCD1602顯示碼
- }
- else //超過范圍時(shí)顯示-----
- {
- write_1602com(0x80+2); //選中第二行第二列
- write_1602dat('-'); //顯示‘-’
- write_1602dat('-'); //顯示‘-’
- write_1602dat('-'); //顯示‘-’
- write_1602dat('-'); //顯示‘-’
- write_1602dat('-'); //顯示‘-’
- }
- }
- /*********************報(bào)警轉(zhuǎn)速參數(shù)轉(zhuǎn)換函數(shù)************************/
- void conversion(unsigned long temp1)//數(shù)據(jù)轉(zhuǎn)換出 個(gè),十,百,千,萬
- {
- h_w=temp1/10000;
- h_q=temp1%10000/1000;
- h_b=temp1%1000/100;
- h_s=temp1%100/10;
- h_g=temp1%10;
- }
- void key_shezhi()
- {
- if(key1==0)
- {
- delay(10);//延時(shí)消抖
- if(key1==0)
- {
- menu++;//切換液晶顯示界面菜單
- if(menu>1)
- {
- menu=0;
- lcd_init();
- delay(5);
- }
- }
- while(!key1);
- }
- if(menu==0)
- {
- if(temp<RPM)//實(shí)際轉(zhuǎn)速大于設(shè)置的上限,產(chǎn)生報(bào)警
- {
- alarming();//報(bào)警
- }
- else
- {
- alarm=1;
- }
- display();//返回初始化顯示,顯示當(dāng)前的實(shí)時(shí)轉(zhuǎn)速
- write_1602com(0x80+0x40+2);//刷新顯示設(shè)置的報(bào)警參數(shù)
- write_1602dat(0x30+temp/10000);
- write_1602dat(0x30+temp%10000/1000);
- write_1602dat(0x30+temp%1000/100);
- write_1602dat(0x30+temp%100/10);
- write_1602dat(0x30+temp%10);
- temp=h_w*10000+h_q*1000+h_b*100+h_s*10+h_g;
- }
- if(menu==1)
- {
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- temp++;//參數(shù)加
- if(temp>29999)//最大值29999
- {
- temp=29999;
- }
- conversion(temp);//萬、千、百、十、個(gè)位轉(zhuǎn)換
- write_eeprom();//參數(shù)保存到EEPROM
- }
- }
- if(key3==0)//通過減按鍵
- {
- delay(10);
- if(key3==0)
- {
- if(temp>0)
- {
- temp--;//參數(shù)減
- }
- conversion(temp);//萬、千、百、十、個(gè)位轉(zhuǎn)換
- write_eeprom();//參數(shù)保存到EEPROM
- }
- }
- //conversion(temp);//萬、千、百、十、個(gè)位轉(zhuǎn)換
- //write_eeprom();//參數(shù)保存到EEPROM
- delay(30);//延時(shí)
- write_1602com(0x80+0x40+2);//在液晶上刷新參數(shù)顯示
- write_1602dat(0x30+temp/10000);
- write_1602dat(0x30+temp%10000/1000);
- write_1602dat(0x30+temp%1000/100);
- write_1602dat(0x30+temp%100/10);
- write_1602dat(0x30+temp%10);
- /*************************************************/
- write_1602com(0x80+0x40+6);//將光標(biāo)移動(dòng)到上限參數(shù)的個(gè)位
- write_1602com(0x0e);
- }
- }
- void init() //系統(tǒng)初始化設(shè)置
- {
- IT0=1; //INT0負(fù)跳變觸發(fā)
- TMOD=0x11;//定時(shí)器工作于方式1
- TH0=0;
- TL0=0;
- EA=1; //CPU開中斷總允許
- ET0=1;
- EX0=1;//開外部INTO中斷
- TR0=0;//啟動(dòng)定時(shí)
- TH1=0x3c;
- TL1=0xb0;
- ET1=1;
- TR1=1;
- }
- /*****************主函數(shù)*************************************/
- void main()
- {
- init(); //調(diào)用初始化函數(shù)
- lcd_init();//液晶初始化
- delay(5);
- init_eeprom();//初始化eeprom
- delay(10);
- read_eeprom();//讀取eeprom數(shù)據(jù)
- delay(10);
- while(1) //進(jìn)入while循環(huán)
- {
- key_shezhi();
- }
- }
- void EXINT0() interrupt 0 //外部中斷函數(shù),霍爾元件有信號(hào),會(huì)進(jìn)入此中斷
- {
- if(TR0==0) //霍爾有信號(hào)輸入時(shí),定時(shí)器沒有打開就打開定時(shí)器,準(zhǔn)備計(jì)時(shí)
- {
- TH0=0;
- TL0=0; //定時(shí)器清零
- TT=0; //計(jì)時(shí)變量清零
- TT1=0; //定時(shí)器中斷次數(shù)清零
- TR0=1; //打開定時(shí)器,開始計(jì)時(shí)
- p=0;
- sec=0;
- }
- else //第二次檢測(cè)到信號(hào)時(shí)
- {
- p=0;
- sec=0;
- TR0=0; //關(guān)閉定時(shí)器
- TT=TT1*65536+TH0*256+TL0; //計(jì)算兩次信號(hào)的時(shí)間差。中斷次數(shù)*65536+TH0*256+TL0,得到時(shí)間差
- TH0=0;
- TL0=0; //計(jì)算完成后,將定時(shí)器清零
- num=60000000/TT; //根據(jù)時(shí)間計(jì)算1min中的速度。一分鐘是60秒,一秒是1000毫秒,1毫秒是1000us,所以是60*1000*1000/時(shí)間,TT的單位是單片機(jī)的最快速度1微秒
- TT1=0; //計(jì)算完速度后,TT1清零
- if(num>1000) //轉(zhuǎn)速超過1000時(shí),取50次的平均值
- {
- sum=num+sum; //將數(shù)據(jù)加一起
- T_num++; //次數(shù)加
- if(T_num>=50) //加到50次
- {
- T_num=0; //次數(shù)清零
- RPM=sum/50; //總數(shù)除以50得到平均值
- sum=0; //計(jì)算完后總數(shù)清零
- }
- }
- else //轉(zhuǎn)速小于1000時(shí)
- {
- sum=0; //總數(shù)清零
- RPM=num; //數(shù)據(jù)直接賦值給轉(zhuǎn)速
- num=0; //數(shù)據(jù)清零
- T_num=0; //次數(shù)清零
- }
- }
- }
- void timeT0() interrupt 1 //兩次信號(hào)中間,定時(shí)器有中斷
- {
- TT1++; //說明達(dá)到一次65536,將TT1加1,計(jì)算時(shí),將TT1乘以65536就是這個(gè)的時(shí)間了
- TH0=0;
- TL0=0; //定時(shí)器清零
- }
- void timeT1() interrupt 3 //兩次信號(hào)中間,定時(shí)器有中斷
- {
- TH1=0x3c;
- TL1=0xb0; //定時(shí)器清零
- p++;
- if(p>=20)
- {
- p=0;
- sec++;
- if(sec>=5)
- {
- sec=0;
- RPM=0;
- TR0=0;
- }
- }
- }
復(fù)制代碼
|
-
-
元件清單.doc
2019-1-19 11:28 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
27.5 KB, 下載次數(shù): 9, 下載積分: 黑幣 -5
|