|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完整的单片机霍尔测速程序; x( ]+ R' s! F7 Y+ W; L4 W( A F' E2 T
1 B: K2 S2 H' B' \2 J- a+ O
4 s0 `3 X: D, n% l1 c" P- z3 ~3 E/************霍尔测速仪******************/ B5 b- }+ y3 ~, G* `
/****************************************/
: R: i/ B; H, P! Z/ m. R/****************************************/1 z9 D$ T3 g! w6 ?, ?% S! |
/**编写人:刘梦宇**/( A2 K* |& {! ?) h2 R
/**主控芯片:STC89C52RC**/' f0 v! k% B/ S) @/ S# u2 I0 w
/**晶振12MHZ**/
s4 g) A+ h" L$ X2 v* i d#include<reg52.h>
- ^1 _ `7 p% |! j#include<intrins.h>
; F! k: Z1 B0 t#define uint8 unsigned char* t8 p0 J0 X e5 Y$ t* F$ E
#define uint16 unsigned int% \9 Y! s: N' Y/ r: ]( {8 ]3 \
#define CMD 0x002 n+ {. f! C9 Y. W+ r
#define DAT 0x01% b& ?9 f+ A4 [) W, [& `- _
#define DataPort P0//LCD数据口
; Z0 U6 \+ q% o. c0 q9 a, ksbit RW=P2^6; u, P4 ?9 W( l3 p% y# S- w4 ?
sbit RS=P2^5;
( m; L; x* v# W, [sbit E=P2^7;+ [3 F$ M5 ~% ~ _8 U
uint16 N=0;& T' \0 @* Q: d l7 @8 d
uint8 C_50ms;6 v1 L2 l! q( d0 O- a- I
uint8 Z=0;
' I# X; e: a. Huint8 count=0;
! O+ M- e% F! ~' v: e0 Kbit flag_1s=0;
4 ?$ _$ ?) a8 a$ M8 ]4 k/**ms级延时子程序**/2 Q3 h O+ b* o6 ]9 C
void delay(uint16 t)
+ R5 {3 o, z- Z K5 q S{
1 L1 m5 R5 w- E7 x9 X+ I6 n uint16 a;
: _. i b, S/ i0 r3 e" m! L; ` for(;t>0;t--)4 _2 B5 L9 D+ F* g; x
for(a=123;a>0;a--);
1 u: c! D% |4 P3 O) E8 r} t% L$ b0 S4 I: s
/**LCD时序**/" T8 \& @5 F+ h
void write_LCD(uint8 dat,bit rs)
9 L' G& i* C" W{3 N/ ?8 r- {! ?, e
E=0;2 g, A9 B, s" Y! C
RW=0;
8 U/ E$ Z8 K, Y5 X. v' ~' C RS=rs;//选择指令or数据6 ~7 s# X& z: v. Z
_nop_();
$ c8 I, h2 ]: I$ W( Q+ X _nop_();
4 Y( w# {' o) x' ]/ F _nop_();- b; c9 c/ T! u: ]0 W' V
E=1; ? s; _$ [$ x% J$ Y
_nop_();//delay(1);
& n4 r! P8 F, s+ ^ _nop_(); k, `7 {5 X; u& X r
_nop_();. J( n; j9 C$ Z# k( N' F. A
DataPort=dat;//将数据送到LCD数据口
: O3 l; i @; ^, u/ Z# q$ l _nop_();" d3 J, C- w& t2 }& h
_nop_();" ^& H6 s4 ^! S4 }$ c' i8 b; N& w$ j
_nop_();6 B5 B7 a6 M# S- e" F$ w9 C4 \4 s1 g
E=0;
, X+ N4 O. T8 r& e5 K* z( i delay(1);
% a. d8 g, T' u$ \}9 T6 y6 |. b* b9 V, ^- P# j
/**LCD选择显示位置子函数**/
$ }8 v$ ~% ]3 `, Z& o( O4 A& tvoid SetXY(uint8 x,uint8 y)
$ u1 n" p( D8 g, G5 }9 D{
1 u' Y1 L) a: s, _ x=x&0x0f;//防止X、Y 超过量程
) p. j$ \7 j5 ~6 h y=y&0x01;
$ v2 q1 D9 u5 h if(y)- F c( U0 E$ @( h* r9 m0 x( e: ~9 N+ ]
{: p, N& F; E+ v0 [0 M
write_LCD(0x80+x,CMD);
5 h2 d; I/ r$ T K }" W! U9 C+ D; E; d; {
else
& z# G+ D2 k9 M/ S, ] w {
6 F' ~2 h6 v+ ?/ T8 C8 L write_LCD(0xc0+x,CMD);
3 i% Y* n7 R7 W# C2 G F } w4 v$ n) {/ L; k l+ n8 s
}
) k* C G, m3 k. N O: D4 A/**转速数值转换子函数**/5 f; i9 V @" t1 B) o+ q4 _' d$ |; e
void disload(uint16 a). v% W8 {( w! { W; q( L
{
0 y, D1 [ j- s7 ?# c3 P SetXY(4,0);
( c1 I( t/ {9 x: f$ a5 D- s r0 i- w9 ? write_LCD(a/1000+'0',DAT);0 X* y5 N, O# c: W4 i' W
write_LCD(a%1000/100+'0',DAT);
# Z6 A1 R* o# P5 W' b' e write_LCD(a%100/10+'0',DAT);
& O4 q. z }9 n9 g( X: S& l \& y write_LCD(a%10+'0',DAT);
0 S. ?, K W( j write_LCD('r',DAT);
4 N+ `7 |/ |2 Q! O8 t* j ` write_LCD('/',DAT);! b2 D. U+ D+ \$ Y
write_LCD('m',DAT);
' z2 R% a& l9 ?' o, m; A write_LCD('i',DAT);
+ _$ g3 _! G* t7 t& V1 u write_LCD('n',DAT);
: b0 {9 ?6 J2 L* L}
! t/ ~. E- H- l! j" H/**LCD字符指针函数**/
+ e0 Y9 Y9 p N: b6 H s- ivoid LCD_wrstr(uint8*str)
9 u2 X g J2 q( [) k& q4 c* y" y# x{
+ S( F. R4 j+ g while(*str!='\0')) O) \9 A% p5 x% g3 d
{
* i5 @( L' s* V" w write_LCD(*str,DAT);3 n: J3 ^ p3 P( y9 J; r
str++;
" D* g3 \( V' z7 k% i }
" G& Q ?- w* W# X& A! V; _3 I}; E+ ^& ]/ |5 F/ F, z, O E. m
/**初始化子程序**/$ @( E" `" M0 j
void All_init()$ \% o# ~$ o1 Y
{; Y/ k; @) L8 k B+ i5 w
delay(500);7 G/ @3 e& Y- T; p# r, a
write_LCD(0x38,CMD);
- U j# ^) f9 l* u( n9 i write_LCD(0x38,CMD);
: T, ?) P: D+ `* W& D write_LCD(0x0c,CMD);6 j$ g3 J% j" L; U; e7 I
write_LCD(0x01,CMD);
" s0 m* |9 @# H! S' j delay(10);4 @7 f8 }+ K! }# U d$ V$ H$ n
! E$ V8 H2 x/ ?6 Q) f* p4 ^+ w0 U, \
SetXY(0,1);//设置标题显示位置
/ Q1 Q6 h3 Z0 z3 M# [0 j( ] LCD_wrstr("Tachometer:");. a8 E" J3 K7 v* f2 d
- D; j+ M; T, H/ @% b% K
TMOD=0x01;//设置T0位工作方式1——作为16位定时器0 ?( D" Z. D/ y! r* ?; n
ET0=1;//打开定时器0的中断
5 X& Y6 _& J6 @& | TR0=1;//打开定时器0
0 A+ Y; |. n/ R: D4 q TH0=(65536-50000)/256;//装入初值 r e2 L- ?+ f C$ t. j) R
TL0=(65536-50000)%256;% f- G3 x" F5 m4 I" @' w9 m
IT0=1;//外部中断0为下降沿中断
' k2 X5 [2 N( @ s& C EX0=1;//打开外部中断
( s" h) w+ C% G3 \ EA=1;//打开总中断
" A6 L' f7 k; R0 Z: d2 O6 L}6 a7 i' v1 R/ j( b; @
void main()
9 p2 Q% w1 @1 ~7 W+ F! U4 |{
9 N9 Z5 Y9 z1 q' i% f: ? All_init();//先进行初始化/ L, q3 w$ ~( _" x( u
while(1)6 G( V+ V2 J4 K/ J2 N/ d
{
; {" @4 x* L- V2 n9 \ if(flag_1s==1) ~+ y, }% \6 p1 a4 Q
{
4 z, y0 t. h/ l, Q! U8 v/ k flag_1s=0;//1s标志位清零6 H7 {0 \& [1 E" n r, q, e
disload(N);
; K/ K: f8 _8 V! T: M O4 s; Q2 V! x }
$ K5 V: @& v6 e7 g8 F, Y }9 C5 Z# @6 X4 I ]' L: D
" k3 `" Q" a+ s0 j}
- e6 O' l8 }, P% p" X4 S4 q/**定时器0中断服务子程序**// ~* Y, J6 F& w
void timer0() interrupt 1
4 J/ l/ u& V0 `" g6 ]5 f{
5 s5 H6 k4 v5 G$ N/ f TH0=(65536-50000)/256;
$ ~. V: L c6 H/ s' K TL0=(65536-50000)%256;% E; G! `! T4 E5 ?1 [3 g
if(++C_50ms>19)% _. B" y1 v4 r! Y4 p
{
+ }' Q0 Z6 O' m9 S& a EX0=0;//关闭外部中断0; \# \) f. T/ K) g6 T
C_50ms=0;//定时1s之后C_50ms清零
% O' d3 g/ u: Z5 S6 O. S- A N=60*Z;//计算转速6 L, i8 E: P5 g
Z=0;//初始化圈数
$ T6 ~; }8 F1 n flag_1s=1;//1s标志位置15 a9 f& b0 @6 o* h% e: b
TH0=0x3c;//重新赋值4 h" a3 Z2 \6 r. g( |
TL0=0xb0;$ y, z" @8 ?" q* ~- F) i+ ^+ U) y8 w
EX0=1;//打开外部中断0,开始计数。: U: q* [! m% |1 C2 l' Z/ D
}
' b" Z; o+ ]1 a1 N8 E# P( E4 q}
) B* P; i9 h3 p" w$ Jvoid wai0() interrupt 05 A, I2 J7 f4 i' ^8 O4 o' _0 d2 x
{7 ^6 E) F- g2 M$ g+ R8 f ~) s
count++;
& u/ r$ @6 J* p* i if(count==2) //两次外部脉冲,电机转一圈。
# r% Q; T: C0 u$ f* g4 o% W {2 _& j, D& i9 S8 k3 |' j/ V
Z++;//转圈+1: |- h- z9 z9 `/ \8 B
count=0;//初始计数值
x! e2 |7 l, p2 p. r0 Z0 Q }' w) w% k# \9 b% R, G3 r* y- x& O
& z8 L3 i& b/ K+ q# t}$ y9 W+ W( C+ @1 D ?1 N; D
& A/ \2 R9 F3 ]" D# s' o |
|