|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完整的单片机霍尔测速程序: X- [) b! Y7 j1 v& j0 L
( y& g2 R% y) U" n2 {- a
4 S6 m1 L# X3 V. u' {/ g/************霍尔测速仪******************/; k5 y9 n4 z; ^6 |% b5 q
/****************************************/
* Q* F3 h3 b2 \9 i9 i/****************************************/
: ~; D% U& a/ g V% q/**编写人:刘梦宇**/: X O2 G; Y" M! d
/**主控芯片:STC89C52RC**/
% d8 g1 K0 U4 F& w7 r/**晶振12MHZ**/# S5 N0 {7 S( p6 v4 A
#include<reg52.h>
5 G9 a& u+ l* M#include<intrins.h>* b" p1 F" T/ j1 Q: Z
#define uint8 unsigned char& J& D/ w& e6 l! i" C' T
#define uint16 unsigned int
* L! Q& T0 ~9 N9 |2 Z% x* `9 o: d#define CMD 0x00, V( o$ f' z4 G& }4 g/ o
#define DAT 0x01
% ]/ |3 a3 g- l9 A, u4 k#define DataPort P0//LCD数据口
8 P, s3 q# J. N, v U5 usbit RW=P2^6;: v5 `6 E7 \( o* l
sbit RS=P2^5;* {; G4 p. M9 Y- U2 D( K" k. o
sbit E=P2^7;
9 ]" X) r9 g& U" suint16 N=0;; B5 s( {( Z$ \4 c% } S! I
uint8 C_50ms;$ c, u h+ Y3 G
uint8 Z=0;
W4 {4 D$ \# p' \* Z* _uint8 count=0;* o$ Z# A, ?9 U* P
bit flag_1s=0;/ G/ r# s" X) i$ H. b+ J# Q
/**ms级延时子程序**/
/ h: r0 S, k- bvoid delay(uint16 t)
/ z, D4 ?% Z! C( L/ K{. E1 |/ x; v7 ~
uint16 a;, p! w! w" T: U, e& Q
for(;t>0;t--)+ q: }% j6 H1 F/ A% h
for(a=123;a>0;a--);+ ^2 Z( G7 Q! ]+ B. q! p/ t$ @' I
} }% i( P+ l2 J5 [$ m! s
/**LCD时序**/: G Q1 u; H" q4 Q9 d
void write_LCD(uint8 dat,bit rs)8 q# R/ G* P8 l' ]8 T! S5 x& C7 K
{
# V9 _2 l$ [: H/ y E=0;
/ g) I$ Z2 l$ F$ x* x$ W" G: M RW=0;
7 E* u7 V: P! j; p RS=rs;//选择指令or数据
% ^, l& S/ N4 R# Y5 Q _nop_();
- U0 a2 b$ {( V* q* o/ R _nop_();
2 J' s/ |% H( c% e9 _+ A _nop_();- \% R* C; t$ H F9 }
E=1;! X" Y3 x) C B3 \; i4 h1 @
_nop_();//delay(1);
& R2 v. y" S a' `5 ] _nop_();
$ d" {: H! e0 n' M& |7 C/ q _nop_();
% _& ? o3 Y. [+ W7 K1 ]8 C DataPort=dat;//将数据送到LCD数据口
' g, b: P( h2 Z _nop_();
0 L+ |# e4 c Y' B _nop_();- Z7 G+ Q6 g3 H% y8 E( o; R
_nop_();7 ]2 r' E" ^& B: z( Y
E=0;$ r# D+ k% @$ I; U3 P, i
delay(1);9 \" c6 Z9 }* Y. G3 I
}
; t. p7 S/ q- o, {, ~3 S0 k/**LCD选择显示位置子函数**/6 D% |: R( [; G+ T" T! P1 L9 ^) x# |
void SetXY(uint8 x,uint8 y)
2 P8 P( v9 x; Y, G{
9 n3 ?8 E0 X1 L7 o" d5 x x=x&0x0f;//防止X、Y 超过量程
7 D( J* c8 k6 c y=y&0x01;
2 Y0 L( _2 f* f; a if(y)% {2 E) m: b6 r+ O; n T
{
$ U1 Q6 E( {! ?6 y1 Z7 K write_LCD(0x80+x,CMD);
4 r# j2 E( @& K8 R( a/ R( s; y }& N2 s' ^ H3 D; L w& }* i
else
# K r" [% M3 @+ T- i$ [ {& l$ l# y: ~( ~# H$ {7 @. G" f" e
write_LCD(0xc0+x,CMD);
5 v* e# L* [8 o8 r0 x1 e7 w }; l6 n, |3 j K3 E" K6 I
} b9 q: ^& @. e g+ _! s* |% c
/**转速数值转换子函数**/, i& {3 V; i2 S
void disload(uint16 a)
0 C2 _) i% E+ b: O/ r, L& C* I{
1 J" c$ m& ^, c! M& r( u9 Y+ c SetXY(4,0);
, x4 y6 _' }8 ?* m write_LCD(a/1000+'0',DAT);7 C# G+ E% f& `$ f( Q
write_LCD(a%1000/100+'0',DAT);5 R8 y* I) K* K, p. w
write_LCD(a%100/10+'0',DAT);7 S/ y" M' M9 T. N2 m( X; J x* [
write_LCD(a%10+'0',DAT);
, s0 @+ U V0 Q! E Q' C write_LCD('r',DAT);
, i1 |- T4 z. Z write_LCD('/',DAT);
2 v5 i, \: F0 w$ P% k0 ? write_LCD('m',DAT);, p- J) h) `, d) j7 x
write_LCD('i',DAT);7 r8 l2 ~9 p5 ~4 y1 g" f: @% O
write_LCD('n',DAT);, E$ D$ f& W8 v( u
}
" g4 n3 B3 b; c$ x N/**LCD字符指针函数**/
, ^- h7 y0 ~! m$ g2 P2 S: Xvoid LCD_wrstr(uint8*str)
3 F7 \7 B! n/ |4 _( l# W3 G% _) Y{# v! _" T/ k$ N. }* x/ h' u9 H
while(*str!='\0')& T: F- _% U3 w' y9 I) F9 K, `
{
/ Z( R& F) A2 V t write_LCD(*str,DAT);
1 C, M4 t6 {7 O, V3 e str++;
9 T7 Z: S' ^8 q }* p6 K, o, P' I( |6 p7 U |
}
0 c+ x, P/ b+ ? D) I& Q/**初始化子程序**/
# V' \ T% b9 ~" _* P- K3 s* Xvoid All_init()
, \( W: x8 a' U3 O0 l a7 ~{, u) n- M2 V6 n4 W1 z' O3 Y
delay(500);( R3 g' g5 k& ~+ u/ q+ _# \5 m8 w
write_LCD(0x38,CMD);
2 W6 E2 ]2 M( g4 ]* Y" }* g6 n write_LCD(0x38,CMD);
+ F y4 q; @2 K" J write_LCD(0x0c,CMD);: w) Z$ A. G4 ^1 f" F0 H: c: k% w& V
write_LCD(0x01,CMD);
7 R6 w B- e8 s2 A delay(10);
8 n) _9 G0 y5 Y1 n7 u) H+ O! J% ~2 i3 k+ p
SetXY(0,1);//设置标题显示位置9 D4 B4 Y, A2 p2 n
LCD_wrstr("Tachometer:");- o3 U0 V& ?1 U! c$ G
3 x' i" C! y' I
TMOD=0x01;//设置T0位工作方式1——作为16位定时器
! _7 v9 L- t4 w- O3 T ET0=1;//打开定时器0的中断
2 }1 D4 l8 `4 R0 G9 K TR0=1;//打开定时器0
u2 p( P* }# [9 u! o TH0=(65536-50000)/256;//装入初值' c& n0 G6 D4 _5 P$ ^
TL0=(65536-50000)%256;& |" J9 V5 g% Q+ W# g2 I
IT0=1;//外部中断0为下降沿中断8 L; U' P' N/ C% d5 \# E Z
EX0=1;//打开外部中断
+ p) u$ i- R# Y; f* b EA=1;//打开总中断3 J& K) t3 A# `8 T
}8 s& c$ G5 _) I/ Y" e
void main()/ |0 ]+ G+ H. u* b9 X7 z! U
{8 x6 e( S& K& z1 h* k
All_init();//先进行初始化! R8 F) l! \% [0 [
while(1)
1 l* U8 A" P) I- T {
7 h, F5 S: ?: P+ v) [$ s if(flag_1s==1)$ v0 f# i+ a( u
{3 S& K2 i& Q- ~# n! N* E3 X
flag_1s=0;//1s标志位清零! z9 d6 D0 ]6 r+ t3 e
disload(N);
2 x/ t" n' G7 J }! a7 y0 P$ j; u1 z3 |: T. z
}
( u2 Y k6 O% L3 u8 {; O5 y. D# y a9 H* i1 ^9 v
}
7 Q% j1 C0 D+ d2 \/**定时器0中断服务子程序**/$ H4 v' \; G) _# _3 T" U, ~
void timer0() interrupt 1
( X& K1 \3 c& w/ g' A# E/ {{
! y6 F- [) f) |$ V, N F% D( p' F TH0=(65536-50000)/256;: F% q1 ]1 d' a" D0 ]3 _
TL0=(65536-50000)%256;
# O& B2 g3 S0 c$ Z# `3 M3 B5 ^ if(++C_50ms>19)
9 @7 T2 A ?2 ~% Z# x1 V9 g7 \ {) u/ O- b2 w- e+ w, X; Y) _
EX0=0;//关闭外部中断0: f& K% _( O+ v7 T$ j/ X3 \/ s
C_50ms=0;//定时1s之后C_50ms清零
; z5 p+ T3 b! z3 S9 D j0 c N=60*Z;//计算转速1 b% b+ x/ y- \3 \5 t
Z=0;//初始化圈数- u; [- D! j1 X, ~
flag_1s=1;//1s标志位置1
: l+ C' Y( h3 m2 U5 Q( \4 v% | TH0=0x3c;//重新赋值- l; f, n" E6 z. y, A% l
TL0=0xb0;
, a" {* o, G: |) l& R/ ? EX0=1;//打开外部中断0,开始计数。2 H4 H9 D0 R9 s8 {7 y
}
% h, O$ D# Y2 Q6 l/ [}
' _( i& {9 y! Evoid wai0() interrupt 0
: Q% H' |$ A, u{% i7 p7 I7 g: e1 |
count++;
: b9 t- W" A% ^* h/ e m if(count==2) //两次外部脉冲,电机转一圈。
+ x) L9 d4 P9 i8 J9 f {
- {* F; F9 C4 T5 g$ g Z++;//转圈+1, F5 R' v+ s+ }( o6 d8 R& {
count=0;//初始计数值
1 e8 R! `, H* g) b6 v' f }/ B4 L2 s! l7 M% g$ P; a
1 j1 a5 P4 s$ l B) g% J
}
: q; i( O- ^' _9 v5 u5 K' x4 j( t {1 `' C4 N4 B8 q7 @
|
|