久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4376|回復: 4
打印 上一主題 下一主題
收起左側

單片機霍爾測速設計最終版程序與元件清單

[復制鏈接]
跳轉到指定樓層
樓主
ID:470473 發表于 2019-1-19 11:30 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
霍爾測速元件清單
1)        9*15萬用板
2)        STC89C52單片機
3)        40腳IC座
4)        1602液晶
5)        16p母座
6)        16p排針
7)        10k電阻*3
8)        1k電阻
9)        3v直流電機
10)        3*1萬用板
11)        磁鐵*2
12)        201電位器
13)        3144霍爾傳感器
14)        103排阻
15)        100uf電解電容
16)        10uf電解電容
17)        30pf瓷片電容*2
18)        12M晶振
19)        自鎖開關
20)        DC電源插口
21)        導線若干
22)        焊錫若干
23)        USB電源線或電池盒

單片機程序源碼:

  1. #include<reg52.h>                        //包含頭文件
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int        //宏定義

  5. /*************STC89單片機EEPROM參數定義和聲明********/
  6. #define RdCommand 0x01 //定義ISP的操作命令
  7. #define PrgCommand 0x02
  8. #define EraseCommand 0x03
  9. #define Error 1
  10. #define Ok 0
  11. #define WaitTime 0x01 //定義CPU的等待時間
  12. sfr ISP_DATA=0xe2;//寄存器申明
  13. sfr ISP_ADDRH=0xe3;
  14. sfr ISP_ADDRL=0xe4;
  15. sfr ISP_CMD=0xe5;
  16. sfr ISP_TRIG=0xe6;
  17. sfr ISP_CONTR=0xe7;
  18. char a_a;
  19. /********************************************/
  20. unsigned long temp=0;//報警上限轉速參數定義
  21. uchar h_w,h_q,h_b,h_s,h_g;//報警上限轉速的參數(萬、千、百、十、個位)
  22. /**************************************************/
  23. sbit COUNT_IN=P3^2;//霍爾傳感器信號輸入
  24. /****************************************************/
  25. //定義1602液晶相關管腳
  26. sbit rs=P2^7;
  27. sbit en=P2^6;
  28. sbit rw=P2^5;
  29. uchar menu;//液晶設置界面菜單
  30. /****************************************************/
  31. sbit key1=P1^1;//報警轉速參數設置按鍵
  32. sbit key2=P1^2;//加
  33. sbit key3=P1^3;//減
  34. sbit alarm=P1^0;//蜂鳴器報警
  35. /**************************************************/
  36. uint count,m,n;                                //定義計算速度變量
  37. unsigned long RPM=0;                        //定義速度變量
  38. unsigned long TT=0;                                //定義時間變量
  39. unsigned long sum=0;                        //計算平均值的總數
  40. unsigned char T_num=0;                        //平均值取值的次數
  41. unsigned long num=0;                        //單次轉速
  42. unsigned int TT1=0;                                //定義定時器中斷次數變量
  43. bit flag;                                        //定義位變量,值只能是0或者1
  44. uchar p,sec;
  45. /********************************************************/
  46. //液晶初始化顯示定義
  47. uchar code tab1[]={"R:"};         //一行顯示的固定字符
  48. uchar code tab2[]={"r/min"};                //轉速顯示的固定字符
  49. uchar code tab3[]={"H:"};                //轉速顯示的固定字符

  50. /**************延時子函數定義************/
  51. void delay(uint x)                //延時函數,大約延時1ms,不精確
  52. {
  53. uint i,j;                        //定義延時函數變量
  54. for(i=0;i<x;i++)        //for循環延時
  55. for(j=0;j<110;j++);
  56. }
  57. void alarming()//蜂鳴器報警子函數
  58. {
  59. alarm=0;
  60. delay(50);
  61. alarm=1;
  62. delay(50);
  63. }
  64. /******************************STC89單片機 EERPROM函數******************/
  65. /*************打開 ISP,IAP 功能********************/
  66. void ISP_IAP_enable(void)
  67. {
  68. EA=0;       //關中斷
  69. ISP_CONTR=ISP_CONTR&0x18;       // 0001,1000
  70. ISP_CONTR=ISP_CONTR|WaitTime; //寫入硬件延時
  71. ISP_CONTR=ISP_CONTR|0x80;      //ISPEN=1
  72. }
  73. /********************關閉 ISP,IAP 功能 ************/
  74. void ISP_IAP_disable(void)
  75. {
  76. ISP_CONTR=ISP_CONTR&0x7f; //ISPEN = 0
  77. ISP_TRIG=0x00;
  78. EA=1;   //開中斷
  79. }
  80. /************公用的觸發代碼**********************/
  81. void ISPgoon(void)
  82. {
  83. ISP_IAP_enable();//打開 ISP,IAP 功能
  84. ISP_TRIG=0x46; //觸發ISP_IAP命令字節1
  85. ISP_TRIG=0xb9; //觸發ISP_IAP命令字節2
  86. _nop_();
  87. }
  88. /****************字節讀 *************************/
  89. unsigned char byte_read(unsigned int byte_addr)
  90. {
  91. EA=0;
  92. ISP_ADDRH=(unsigned char)(byte_addr>>8);//地址賦值
  93. ISP_ADDRL=(unsigned char)(byte_addr&0x00ff);
  94. ISP_CMD=ISP_CMD&0xf8;//清除低3位  
  95. ISP_CMD=ISP_CMD|RdCommand;//寫入讀命令
  96. ISPgoon();//觸發執行  
  97. ISP_IAP_disable();//關閉ISP,IAP功能
  98. EA=1;
  99. return(ISP_DATA);//返回讀到的數據
  100. }
  101. /*****************扇區擦除 ************************/
  102. void SectorErase(unsigned int sector_addr)
  103. {
  104. unsigned int iSectorAddr;
  105. iSectorAddr=(sector_addr&0xfe00); //取扇區地址
  106. ISP_ADDRH=(unsigned char)(iSectorAddr>>8);
  107. ISP_ADDRL=0x00;
  108. ISP_CMD=ISP_CMD&0xf8;//清空低3位  
  109. ISP_CMD=ISP_CMD|EraseCommand; //擦除命令3  
  110. ISPgoon();//觸發執行
  111. ISP_IAP_disable();//關閉ISP,IAP功能
  112. }
  113. /************************字節寫 *************************/
  114. void byte_write(unsigned int byte_addr, unsigned char original_data)
  115. {
  116. EA=0;
  117. ISP_ADDRH=(unsigned char)(byte_addr>>8);//取地址
  118. ISP_ADDRL=(unsigned char)(byte_addr & 0x00ff);
  119. ISP_CMD=ISP_CMD&0xf8;//清低3位
  120. ISP_CMD=ISP_CMD | PrgCommand;//寫命令2
  121. ISP_DATA=original_data;//寫入數據準備
  122. ISPgoon();//觸發執行  
  123. ISP_IAP_disable();//關閉IAP功能
  124. EA =1;
  125. }
  126. /********************內部eeprom寫函數**************/
  127. void write_eeprom()
  128. {
  129. SectorErase(0x2000);//先把扇區清空
  130. delay(1);
  131. SectorErase(0x2c00);//先把扇區清空
  132. delay(1);
  133. SectorErase(0x2d00);//先把扇區清空
  134. delay(1);

  135. /**************寫入參數******************/
  136. byte_write(0x2d00,h_w);//存萬位
  137. delay(1);
  138. byte_write(0x2d01,h_q);//存千位
  139. delay(1);
  140. byte_write(0x2d02,h_b);//存百位
  141. delay(1);
  142. byte_write(0x2d03,h_s);//存十位
  143. delay(1);
  144. byte_write(0x2d04,h_g);//存個位
  145. delay(1);
  146.                                    
  147. byte_write(0x2060,0x01);
  148. }
  149. /******************把數據從單片機內部eeprom中讀出來*****************/
  150. void read_eeprom()                                                                                                                                 
  151. {
  152. h_w=byte_read(0x2d00);//萬位讀回來
  153. delay(1);
  154. h_q=byte_read(0x2d01);//千位讀回來
  155. delay(1);
  156. h_b=byte_read(0x2d02);//百位讀回來
  157. delay(1);
  158. h_s=byte_read(0x2d03);//十位讀回來
  159. delay(1);
  160. h_g=byte_read(0x2d04);//個位讀回來
  161. delay(1);
  162. a_a=byte_read(0x2060);         
  163. }
  164. /**************開機自檢eeprom初始化*****************/
  165. void init_eeprom()
  166. {
  167. a_a=byte_read(0x2060);
  168. if(a_a!=1)                //新的單片機初始單片機內問eeprom
  169. {
  170.   a_a=1;
  171.   write_eeprom();//保存數據
  172.   delay(1);
  173. }        
  174. }

  175. /********液晶寫入指令函數與寫入數據函數,以后可調用**************/
  176. void write_1602com(uchar com)//****液晶寫入指令函數****
  177. {
  178. rs=0;//數據/指令選擇置為指令
  179. P0=com;//送入數據
  180. delay(1);
  181. en=1;//拉高使能端,為制造有效的下降沿做準備
  182. delay(1);
  183. en=0;//en由高變低,產生下降沿,液晶執行命令
  184. }
  185. void write_1602dat(uchar dat)//***液晶寫入數據函數****
  186. {
  187. rs=1;//數據/指令選擇置為數據
  188. P0=dat;//送入數據
  189. delay(1);
  190. en=1; //en置高電平,為制造下降沿做準備
  191. delay(1);
  192. en=0; //en由高變低,產生下降沿,液晶執行命令
  193. }
  194. void lcd_init()//***液晶初始化函數****
  195. {
  196. uchar a;
  197. rw=0;
  198. write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
  199. write_1602com(0x0c);//開顯示不顯示光標
  200. write_1602com(0x06);//整屏不移動,光標自動右移
  201. write_1602com(0x01);//清顯示

  202. write_1602com(0x80);//顯示固定符號從第一行第1個位置之后開始顯示
  203. for(a=0;a<2;a++)
  204. {
  205.   write_1602dat(tab1[a]);//向液晶屏寫固定符號部分
  206. }
  207. write_1602com(0x80+8);//顯示固定符號寫入位置,從第2個位置后開始顯示
  208. for(a=0;a<5;a++)
  209. {
  210.   write_1602dat(tab2[a]);//寫顯示固定符號
  211. }
  212. write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示
  213. for(a=0;a<2;a++)
  214. {
  215.   write_1602dat(tab3[a]);//寫顯示固定符號
  216. }
  217. }

  218. void display()                         //顯示函數
  219. {
  220. if(RPM<=99999)                 //范圍內時
  221. {
  222.   uchar gw,sw,bw,qw,ww;//定義拆字變量
  223.   ww=RPM/10000;                //轉速/10000得到萬位
  224.   qw=RPM%10000/1000;        //轉速/10000的余數/1000得到千位
  225.   bw=RPM%1000/100;//取得百位
  226.   sw=RPM%100/10;//取得十位數字
  227.   gw=RPM%10;//取得個位數字
  228.   write_1602com(0x80+2);         //選中第二行第二位

  229.   if(ww==0)                                         //萬位為0時
  230.   {
  231.    write_1602dat(' ');                         //顯示空格
  232.   }
  233.   else                                                 //萬位不為0時
  234.   {
  235.    write_1602dat(0x30+ww);                 //顯示萬位的數據        +0x30是因為在液晶的字庫中,0的地址是0x30,1的地址是0x31,以此類推
  236.   }

  237.   if((ww+qw)==0)                                 //萬位和千位都為0時
  238.   {
  239.    write_1602dat(' ');                         //千位顯示空格
  240.   }
  241.   else                                                 //萬位和千位不都為0時
  242.   {
  243.    write_1602dat(0x30+qw);                 //顯示千位數據
  244.   }

  245.   if((ww+qw+bw)==0)                         //萬位、千位和百位都是0時
  246.   {
  247.    write_1602dat(' ');                         //顯示空格
  248.   }
  249.   else                                                 //萬位、千位和百位不都為0時
  250.   {
  251.    write_1602dat(0x30+bw);                 //顯示百位數據
  252.   }

  253.   if((ww+qw+bw+sw)==0)                 //萬位、千位、百位和十位都為0時
  254.   {
  255.    write_1602dat(' ');                         //顯示空格
  256.   }
  257.   else                                                 //萬位、千位、百位和十位不都為0時
  258.   {
  259.    write_1602dat(0x30+sw);                 //顯示十位數據
  260.   }               
  261.   write_1602dat(0x30+gw);                 //顯示個位數據    數字+0x30得到該數字的LCD1602顯示碼
  262. }
  263. else                  //超過范圍時顯示-----
  264. {
  265.   write_1602com(0x80+2);         //選中第二行第二列
  266.   write_1602dat('-');                         //顯示‘-’
  267.   write_1602dat('-');                         //顯示‘-’
  268.   write_1602dat('-');                         //顯示‘-’
  269.   write_1602dat('-');                         //顯示‘-’
  270.   write_1602dat('-');                         //顯示‘-’
  271. }
  272. }

  273. /*********************報警轉速參數轉換函數************************/
  274. void conversion(unsigned long temp1)//數據轉換出 個,十,百,千,萬
  275. {  
  276. h_w=temp1/10000;
  277. h_q=temp1%10000/1000;
  278. h_b=temp1%1000/100;
  279. h_s=temp1%100/10;
  280. h_g=temp1%10;        
  281. }

  282. void key_shezhi()
  283. {
  284. if(key1==0)
  285. {
  286.   delay(10);//延時消抖
  287.   if(key1==0)
  288.   {
  289.    menu++;//切換液晶顯示界面菜單
  290.    if(menu>1)
  291.    {
  292.         menu=0;
  293.         lcd_init();
  294.         delay(5);
  295.    }
  296.   }
  297.   while(!key1);
  298. }

  299. if(menu==0)
  300. {
  301.    if(temp<RPM)//實際轉速大于設置的上限,產生報警
  302.    {
  303.     alarming();//報警
  304.    }
  305.    else
  306.    {
  307.     alarm=1;
  308.    }

  309.    display();//返回初始化顯示,顯示當前的實時轉速
  310.    write_1602com(0x80+0x40+2);//刷新顯示設置的報警參數
  311.    write_1602dat(0x30+temp/10000);
  312.    write_1602dat(0x30+temp%10000/1000);
  313.    write_1602dat(0x30+temp%1000/100);
  314.    write_1602dat(0x30+temp%100/10);
  315.    write_1602dat(0x30+temp%10);

  316.    temp=h_w*10000+h_q*1000+h_b*100+h_s*10+h_g;
  317. }
  318. if(menu==1)
  319. {
  320.   if(key2==0)
  321.   {
  322.    delay(10);
  323.    if(key2==0)
  324.    {
  325.     temp++;//參數加
  326.         if(temp>29999)//最大值29999
  327.         {
  328.          temp=29999;
  329.         }
  330.         conversion(temp);//萬、千、百、十、個位轉換
  331.     write_eeprom();//參數保存到EEPROM
  332.    }
  333.   }
  334.   if(key3==0)//通過減按鍵
  335.   {
  336.    delay(10);
  337.    if(key3==0)
  338.    {
  339.     if(temp>0)
  340.         {
  341.          temp--;//參數減
  342.         }
  343.         conversion(temp);//萬、千、百、十、個位轉換
  344.     write_eeprom();//參數保存到EEPROM
  345.    }
  346.   }
  347.   //conversion(temp);//萬、千、百、十、個位轉換
  348.   //write_eeprom();//參數保存到EEPROM

  349.   delay(30);//延時
  350.   write_1602com(0x80+0x40+2);//在液晶上刷新參數顯示
  351.   write_1602dat(0x30+temp/10000);
  352.   write_1602dat(0x30+temp%10000/1000);
  353.   write_1602dat(0x30+temp%1000/100);
  354.   write_1602dat(0x30+temp%100/10);
  355.   write_1602dat(0x30+temp%10);
  356.   /*************************************************/
  357.   write_1602com(0x80+0x40+6);//將光標移動到上限參數的個位
  358.   write_1602com(0x0e);
  359. }
  360. }

  361. void init()                                //系統初始化設置
  362. {
  363. IT0=1;        //INT0負跳變觸發        
  364. TMOD=0x11;//定時器工作于方式1
  365. TH0=0;         
  366. TL0=0;
  367. EA=1; //CPU開中斷總允許
  368. ET0=1;
  369. EX0=1;//開外部INTO中斷
  370. TR0=0;//啟動定時

  371. TH1=0x3c;
  372. TL1=0xb0;
  373. ET1=1;
  374. TR1=1;
  375. }
  376. /*****************主函數*************************************/
  377. void main()                  
  378. {
  379. init();        //調用初始化函數
  380. lcd_init();//液晶初始化
  381. delay(5);
  382. init_eeprom();//初始化eeprom
  383. delay(10);
  384. read_eeprom();//讀取eeprom數據
  385. delay(10);
  386. while(1)          //進入while循環
  387. {
  388.   key_shezhi();
  389. }
  390. }

  391. void EXINT0() interrupt 0 //外部中斷函數,霍爾元件有信號,會進入此中斷
  392. {
  393. if(TR0==0)                                           //霍爾有信號輸入時,定時器沒有打開就打開定時器,準備計時
  394. {
  395.   TH0=0;
  396.   TL0=0;                                           //定時器清零
  397.   TT=0;                                           //計時變量清零
  398.   TT1=0;                                           //定時器中斷次數清零
  399.   TR0=1;                                           //打開定時器,開始計時
  400.   p=0;
  401.   sec=0;
  402. }
  403. else                                                   //第二次檢測到信號時
  404. {
  405.   p=0;
  406.   sec=0;
  407.   TR0=0;                                           //關閉定時器
  408.   TT=TT1*65536+TH0*256+TL0;  //計算兩次信號的時間差。中斷次數*65536+TH0*256+TL0,得到時間差
  409.   TH0=0;
  410.   TL0=0;                                           //計算完成后,將定時器清零
  411.   num=60000000/TT;                   //根據時間計算1min中的速度。一分鐘是60秒,一秒是1000毫秒,1毫秒是1000us,所以是60*1000*1000/時間,TT的單位是單片機的最快速度1微秒
  412.   TT1=0;                                           //計算完速度后,TT1清零
  413.   if(num>1000)                           //轉速超過1000時,取50次的平均值
  414.   {
  415.    sum=num+sum;                   //將數據加一起
  416.    T_num++;                           //次數加
  417.    if(T_num>=50)                   //加到50次
  418.    {
  419.         T_num=0;                   //次數清零
  420.     RPM=sum/50;                   //總數除以50得到平均值
  421.         sum=0;                           //計算完后總數清零
  422.    }
  423.   }
  424.   else                                           //轉速小于1000時
  425.   {
  426.    sum=0;                                   //總數清零
  427.    RPM=num;                           //數據直接賦值給轉速
  428.    num=0;                                   //數據清零
  429.    T_num=0;                           //次數清零
  430.   }
  431. }
  432. }

  433. void timeT0() interrupt 1                   //兩次信號中間,定時器有中斷
  434. {
  435. TT1++;                                                   //說明達到一次65536,將TT1加1,計算時,將TT1乘以65536就是這個的時間了
  436. TH0=0;
  437. TL0=0;                                                   //定時器清零
  438. }

  439. void timeT1() interrupt 3                   //兩次信號中間,定時器有中斷
  440. {
  441. TH1=0x3c;
  442. TL1=0xb0;                                                   //定時器清零
  443. p++;
  444. if(p>=20)
  445. {
  446.   p=0;
  447.   sec++;
  448.   if(sec>=5)
  449.   {
  450.    sec=0;
  451.    RPM=0;
  452.    TR0=0;
  453.   }
  454. }
  455. }


復制代碼

元件清單.doc

27.5 KB, 下載次數: 9, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2019-1-19 13:43 | 只看該作者
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣
回復

使用道具 舉報

板凳
ID:470473 發表于 2019-2-16 15:07 | 只看該作者
admin 發表于 2019-1-19 13:43
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣

你好,要怎么補全,再發一個帖子嗎
回復

使用道具 舉報

地板
ID:517235 發表于 2019-5-4 18:23 | 只看該作者
袁繼輝 發表于 2019-2-16 15:07
你好,要怎么補全,再發一個帖子嗎

原貼修改上傳原理圖
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费一级欧美在线观看视频 | 欧美在线观看网站 | av成人在线观看 | 欧美精品欧美精品系列 | 成人免费视频观看 | 国产精品九九视频 | 女人精96xxx免费网站p | 日韩在线小视频 | 精品一区二区三区入口 | 一级特黄色毛片 | 午夜精品 | 日本一区二区不卡 | 久久99视频 | 欧美国产中文 | 欧美bondage紧缚视频 | 国产高清免费 | 福利av在线| 免费看大片bbbb欧美 | 国产一区二区精 | 黄色网址大全在线观看 | 国产精品视频久久 | 欧美一区二区三区小说 | 91就要激情| 在线视频一区二区 | 成人午夜看片 | 国产片侵犯亲女视频播放 | 中国一级特黄真人毛片 | 久久精品| 一级片av | 中文字幕亚洲精品 | 欧美日韩国产一区二区三区 | 国产精品毛片无码 | 日韩精品一区二区三区在线观看 | 日韩欧美在线不卡 | 综合色影院 | 色网在线观看 | 久久a久久 | 日韩精品视频中文字幕 | 国产精品精品视频一区二区三区 | 中文字幕一区二区三区在线视频 | 欧美日韩国产一区二区 |