|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完整的单片机霍尔测速程序" y+ I! ^; t% Z7 O: F: G
( Q9 K+ b" L j- j4 Q3 e
: @6 p9 O: S. M- v, s/************霍尔测速仪******************/
2 l! \8 E' w: H; W4 u% |& F) r1 H+ ]/****************************************/8 A) [3 |& ?! t" p) i$ B
/****************************************/. W: Z" Q3 {) c8 S4 }
/**编写人:刘梦宇**/ m3 I# [& ?2 {, x9 l B. N; p- \9 y
/**主控芯片:STC89C52RC**/
# a. c. p- p% e& r1 ~/**晶振12MHZ**/) @( ^3 T! r7 q9 |
#include<reg52.h>2 g4 s& x, Q& U$ I: b* [
#include<intrins.h>
! E2 P; X# l: i0 E#define uint8 unsigned char( U0 `2 t6 Z( S" L+ {, R
#define uint16 unsigned int
' N: t- Q4 e" V+ ?* g1 R; W' O- X#define CMD 0x00
6 }0 O3 n( u! [+ k' l. t#define DAT 0x01
* |/ J5 p3 @/ i5 {2 Q#define DataPort P0//LCD数据口' g" Z3 k% s4 N" ^- H. ^. F% W
sbit RW=P2^6;1 u/ _. @( l8 g
sbit RS=P2^5;
6 s' o8 B* c7 [' Lsbit E=P2^7;0 S( Z. e! T: T1 N# i8 z' v
uint16 N=0;( E: u2 M: _# h
uint8 C_50ms;
: t& {" M j2 c$ L+ m% t) _. Vuint8 Z=0;
& x2 q3 V0 `1 S9 z7 I1 Z5 F, P$ wuint8 count=0;
+ P: r! ]0 S! N3 c7 u4 sbit flag_1s=0;" K" u" l2 _3 m( A5 ]
/**ms级延时子程序**/: {& i+ A7 t# Y" D
void delay(uint16 t)
' q& Q4 s& O6 _9 n, ^{5 Z4 n4 u3 A4 V2 Y' S7 A
uint16 a;; F K. m5 o+ w$ |; H6 r
for(;t>0;t--)
$ i! |; ?9 ?6 v; G' c0 `8 q for(a=123;a>0;a--);
" Z3 l- ^3 Q2 T5 t}
# E! Z8 `' x1 [! [. x/**LCD时序**/6 F* x/ v* h6 d8 c$ E- W+ m: t
void write_LCD(uint8 dat,bit rs)
6 w$ f* G8 K; W5 E! l( \' d{
' w- Q9 g$ T; r/ K/ F E=0;
8 x w! l# I7 @! u$ T; h" Y8 e RW=0;
) M& p. b- l# {7 G% \( b RS=rs;//选择指令or数据3 ~( A2 {& c7 a- w" u! M. y4 d
_nop_();9 K9 A) Z# V( N& y
_nop_();" o! i( k) ]5 @7 r# z. W1 U1 C
_nop_();
& @' E3 z& a) @2 V' e E=1;$ g- \: ^" s- H
_nop_();//delay(1);
+ N% ^7 I$ i8 o0 l. o9 k0 |9 M( I _nop_();7 s/ O7 ` A$ g; H
_nop_();1 j* O. p" U7 j
DataPort=dat;//将数据送到LCD数据口
1 I- z! Z5 f6 ^3 |: u _nop_();
# B0 n7 B/ ~1 b3 l _nop_();+ L# b; t0 k. F4 B
_nop_();
# o, G8 C: l: q, @ U E=0;" s8 j' {8 Y5 B$ t2 Z) j E& R
delay(1);
0 X5 j0 a) a) K' ]5 R}+ J" Q- H# b* [/ G4 R7 q
/**LCD选择显示位置子函数**/
+ H3 Y. T5 c' v4 N- |7 z* [+ a8 qvoid SetXY(uint8 x,uint8 y)' T; j- `- ?" R/ X5 f7 i( f
{
8 @/ B4 y) {4 Z7 W3 L x=x&0x0f;//防止X、Y 超过量程
5 o9 a+ w5 O5 y% X y=y&0x01;6 m9 |( _3 X; P8 x- H4 |; K$ Q
if(y)
3 o/ M6 P) q8 }. [7 r {
+ `. s- B+ s0 q: E' J4 k. w write_LCD(0x80+x,CMD);9 M! |& ]7 L& j _- J
}
: `( b2 X! Z7 u. y$ n" P else* G' G( y* O5 Q( s' g
{! ?: h0 s7 D* ]# H0 v
write_LCD(0xc0+x,CMD);: h" j9 w* p4 o2 g5 M3 v; O: D
}
1 |+ s2 I, |7 v* `2 d7 S}
4 X# n# ?8 W. o+ M: D( w+ d/**转速数值转换子函数**/8 \: Z; Z5 |9 [( k% \; _! A1 o/ K
void disload(uint16 a): G5 W3 t) {5 k3 l1 P0 N1 a: a
{
- D% r3 A) l; M. d SetXY(4,0);
0 V7 X# u9 D7 ]9 W- P. n, V( V write_LCD(a/1000+'0',DAT);
' H) Z$ s" e& X! s* [: o0 O write_LCD(a%1000/100+'0',DAT);
, g8 F& `9 Q5 Y' N write_LCD(a%100/10+'0',DAT);" _+ t; z* P# |. J" z
write_LCD(a%10+'0',DAT);
9 b. C; n9 U* X" R2 ~1 j' h" W write_LCD('r',DAT);
+ c" M% f/ V4 I2 V1 D0 O4 c write_LCD('/',DAT);7 P" o9 I, `! s
write_LCD('m',DAT);
/ u4 q: Z; P* T4 V! y+ t write_LCD('i',DAT);
/ {; Z) T3 q- J! m; C: Z8 R write_LCD('n',DAT);
4 w) i8 t* Z5 m' \}
( W6 i/ U, p9 n" ^4 S# V% W/ N/**LCD字符指针函数**/, {- O4 J7 k- x/ F$ P% Q
void LCD_wrstr(uint8*str). k2 b8 R9 O; ^
{
* j5 r a5 J) }" F I while(*str!='\0')
4 x1 A& B u' l, { C. I9 o2 x {) C2 D) p# X/ v$ P0 U" c
write_LCD(*str,DAT);' B2 x8 F6 o @6 ~% `
str++;* A8 U. R' E8 u" |9 ]1 j
}+ o- r8 g/ c. l+ g
}, L A% H4 w! a' w( H7 v
/**初始化子程序**/+ D2 q4 P: O5 m9 P
void All_init()
! C9 S8 S$ B! a1 `{
4 W9 m3 U, k5 F7 C. M delay(500);
; W% Q5 [1 T& h7 V0 e% p write_LCD(0x38,CMD);
3 b8 U4 }) W; K5 e! P write_LCD(0x38,CMD);& Z, {7 ~. ]* y/ B1 i/ N
write_LCD(0x0c,CMD);
4 W' z s+ i" ^: I write_LCD(0x01,CMD);
( ^+ U o. n. H1 K delay(10);6 P' q$ m$ Q2 K" \
% r5 O9 J" A' c* Y' \6 o; D SetXY(0,1);//设置标题显示位置
- O; r3 r. J' V, o$ o5 n LCD_wrstr("Tachometer:");7 J0 Q' F, w3 }3 F3 \4 d
2 a8 s0 A; `" R) {2 S7 l' M TMOD=0x01;//设置T0位工作方式1——作为16位定时器& v% p( R8 G% T/ r
ET0=1;//打开定时器0的中断) u; a( S, |* G! R
TR0=1;//打开定时器0: i- W# P/ c) z# n* l" a
TH0=(65536-50000)/256;//装入初值4 f) n, e: j8 G" ^6 |
TL0=(65536-50000)%256;4 f# A2 f1 Y/ P! S% S
IT0=1;//外部中断0为下降沿中断
3 X3 s/ e" }0 h u* u% A* Y! M1 J EX0=1;//打开外部中断) Y4 e7 k/ K% \6 ~
EA=1;//打开总中断. j [% p) |5 A/ K
}# l' K' `6 h& q# \; m- [$ ]# n
void main()1 d0 [0 J6 o n3 y
{
: k8 w% t/ j$ I' `% M All_init();//先进行初始化7 [' m/ Q0 J" m+ z
while(1)
" Q! l9 k; j5 V/ G {4 [2 e; Y, q; q0 |* @% F3 p
if(flag_1s==1)
w$ b- }9 l" T: {' X/ v4 f {) S& ?3 P' P+ e1 v: x
flag_1s=0;//1s标志位清零
, D3 X; q4 Q* @! O% o5 c2 Q disload(N);- L, [# a3 ? A" H, ]7 N/ g
}
- ~' H* w2 {' X3 J# B6 d2 { }- p6 J3 \' j, [
$ S+ ]8 M2 J, f7 A}
* F$ E2 Z) q! u- s/ }/**定时器0中断服务子程序**/! ~7 g5 |& s7 l3 W7 c. ~$ o4 R$ g3 A1 Q
void timer0() interrupt 1 U5 A Y- J7 T0 p8 }8 [) v6 |* R. H& w
{
) O }8 a3 H+ z. _8 Y! N% n9 u& V TH0=(65536-50000)/256;
$ u8 k( r5 }- Y# o8 p0 r c TL0=(65536-50000)%256;8 S8 ` z& B9 y7 H! o; l3 y+ S8 j( D2 ?
if(++C_50ms>19)) }2 p- o2 m1 G; V: c) F7 J$ k
{
4 n1 C! J- C3 R- k+ l) \& K6 J. ? EX0=0;//关闭外部中断0
" a0 y" F2 k6 D C_50ms=0;//定时1s之后C_50ms清零
3 J: F3 u3 j8 o1 n/ } N=60*Z;//计算转速% @+ X: D' M3 V) P: g5 Z2 t' F
Z=0;//初始化圈数" U2 {) L: [5 L# e" N
flag_1s=1;//1s标志位置1( _. D7 e) Z" ~1 y
TH0=0x3c;//重新赋值
8 o# O" @1 N$ K1 T TL0=0xb0;; o: [$ P: m/ P) t5 |7 O. [& H
EX0=1;//打开外部中断0,开始计数。
; q' C$ m/ }' s2 u* ] }
6 u8 A) R! ^; t8 r1 s}
) ~& ?3 e; Q! A8 q4 Evoid wai0() interrupt 0, U- j! Q6 v: x/ ?
{4 o5 v4 h% j3 q2 j: |- a) k% n7 W) @+ b
count++;
6 \: Y# L- [5 ]" q6 l' z if(count==2) //两次外部脉冲,电机转一圈。
' E2 Q1 I- Y6 r. \ {, ?' q- @) e" C* V+ M: `
Z++;//转圈+1
|9 R8 ^, x8 S# W$ T count=0;//初始计数值
# z1 r( u" R" @' v0 o8 c8 P5 ~2 h+ P }) v& M- e, P% O+ J5 e( j
. ~1 z+ }2 d, l$ @; q}# d) J: V9 ?3 j% r; f, R
0 V& d. _" l# j: y( m4 [
|
|