|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完整的单片机霍尔测速程序, x1 D5 u. v8 q, e
, C7 _" e2 d: _& g" T4 w& T# i
/ N- @! C2 @$ k$ n0 \0 l$ o
/************霍尔测速仪******************/
6 l# L$ h3 N! a S/****************************************/% }, r: v( M1 {5 ^3 c
/****************************************/
- E2 b4 f$ H" ~ u, q/**编写人:刘梦宇**/6 s: w/ o6 a: C& ~4 z
/**主控芯片:STC89C52RC**/
" |0 C* }2 H7 m, s# }6 T4 Q( k7 Z/**晶振12MHZ**/
% v) \$ B V% w. ]8 F8 j#include<reg52.h>
" S, b8 L/ i) m5 B$ Y5 ^#include<intrins.h>
$ W7 m4 I8 R: [0 f. S) {' r1 y, O#define uint8 unsigned char
' U3 n- x* Z* j- E* ` [#define uint16 unsigned int
: ~/ |3 E( O) W. @#define CMD 0x002 c$ c2 n; G D6 s; {. R/ E( o
#define DAT 0x01
: {, T0 K5 B. S0 L/ T a* B#define DataPort P0//LCD数据口
4 G$ ~5 C B& h# y5 c, @sbit RW=P2^6;
% j9 }9 j: l9 ?& n- dsbit RS=P2^5;) b6 f; Z! x, v6 }) h; w H
sbit E=P2^7;/ ?4 T9 j$ k# Y* O: q" @$ E
uint16 N=0;( N6 P. w$ ^! p, ~8 {( F
uint8 C_50ms;
/ a/ q/ m5 G- ruint8 Z=0;
0 U" Z. ]: q9 _, b- I5 f M+ \uint8 count=0;
# }1 p4 r9 V' P" x1 h3 J. c9 \bit flag_1s=0;
# D6 X3 R+ Z. v' o; U: P/**ms级延时子程序**/
0 A1 m4 {! E8 C6 [- E5 x* _void delay(uint16 t)6 t% I% Y V8 y; S1 ~$ D: l
{. O5 a! j# j- Y# h2 W' G8 f% n
uint16 a;
9 v& F5 y. c6 |( s# P1 T for(;t>0;t--)2 L3 A, h7 n$ x$ v. A- M6 I
for(a=123;a>0;a--);
V" s0 h2 M$ x/ Z& K}
- O6 V0 c9 d3 B' I7 ?2 Q# A* ~/**LCD时序**/6 X2 f, K2 o ]/ { B" e. {% i
void write_LCD(uint8 dat,bit rs) p! q2 R, @9 F
{
8 s, F2 G+ b/ I+ @ E=0;
2 e2 v. M$ X, }9 s7 E, X RW=0;
% N: y) I5 A: Z. n: U/ V# a4 n) p RS=rs;//选择指令or数据2 A& `/ |* M4 p$ |
_nop_();9 J9 _/ y" ^, \* [
_nop_();
% K+ y0 g" H$ y) W2 G- m5 } D _nop_();" U. i$ A9 Y# z9 A$ r& l
E=1;
S4 [! X- u6 j _nop_();//delay(1);
4 `3 V4 ?% K1 f5 J/ z" q _nop_();
3 B/ ?# W, ^' a0 e* u# S( n _nop_();
Q4 m3 G3 G7 y8 k8 l DataPort=dat;//将数据送到LCD数据口. j3 k9 p. d% ^' x G( J* y
_nop_();4 w% B, ~, C6 n# H( S
_nop_();
5 B# D; d% k8 w! q4 L: J4 e) a8 s( E _nop_();
1 I- v# x+ c+ K& _& v E=0;; g5 `3 `/ Z( d+ g! z( ^
delay(1);
) }6 a( S, [" U/ x}
5 j, G3 I7 M4 z( p, V$ c- q/**LCD选择显示位置子函数**/
$ m3 x) k- [# N8 h) a" e. Rvoid SetXY(uint8 x,uint8 y)/ I3 _; O" E0 M5 t: a
{! d8 \- a' o3 L- r P
x=x&0x0f;//防止X、Y 超过量程
( R2 g P4 t1 t- e: K y=y&0x01;. J _) f2 n7 g' ~
if(y)
& ~- N' T1 v L8 f) C2 y {
7 i2 {: P; M+ z, B' P; ? write_LCD(0x80+x,CMD);
/ c3 ~' i+ g9 x" J; N }
1 @( F7 e+ q( U8 v$ P3 V else
8 U2 k$ q( R) s" ~! K {
' q1 e; @$ l: }, D& | write_LCD(0xc0+x,CMD);
" @9 E! h- }/ u# ], X }# ]8 a7 b* G$ n0 ?
}& `+ H6 |, b1 S s
/**转速数值转换子函数**/
6 F- O4 c, n8 u M1 ?7 _void disload(uint16 a)- l9 q1 s7 l; H# F
{$ k& g+ }3 ^9 o2 X2 W
SetXY(4,0);9 r8 S1 l! f+ n* e
write_LCD(a/1000+'0',DAT);% i: _4 O0 T9 t4 x. x& V
write_LCD(a%1000/100+'0',DAT);: d$ ]% E( d+ Z1 s7 U
write_LCD(a%100/10+'0',DAT);
8 m5 p# m" X2 h write_LCD(a%10+'0',DAT);
. B! m5 p2 {( T1 M$ g8 I( s write_LCD('r',DAT);, e1 o3 [1 }' ~
write_LCD('/',DAT);
# X# t5 [7 I' R3 `0 P# m' i4 V( b* S write_LCD('m',DAT);
$ g2 B- N# c' ~) k& K write_LCD('i',DAT);
: |4 \+ I' T8 h, z* ]+ E& A write_LCD('n',DAT);
& E) N8 w/ n4 G! \5 ^0 l6 d}+ y6 b; N" z3 Y# S2 @4 r
/**LCD字符指针函数**/# G! l# s. N/ ] [+ j9 l
void LCD_wrstr(uint8*str)
) j. D0 u% b* p( u/ k( s1 b& m{
, U! `0 d4 S4 q- g# |" ?! B while(*str!='\0')
$ L* P G' }- j- U; L/ { {
/ A. q7 ^3 c; S1 h write_LCD(*str,DAT);
" @% F- L1 V) t& Z str++;
; _: ^9 ^% B: ], z }( Z: a5 w; r/ d8 J1 |
}" q o: P4 @1 d9 K
/**初始化子程序**/
$ E8 W- f$ |$ w! tvoid All_init()
. c3 s# I& T1 b! O{
! k2 ?# `7 K3 f5 y delay(500);
2 {% R* \3 g$ S9 G: U' ` write_LCD(0x38,CMD);
/ x8 X9 r% X6 \- R" | write_LCD(0x38,CMD);/ Y( }+ O' J) l2 C# w: u/ F
write_LCD(0x0c,CMD);/ G& [ N% S- \8 v1 v: b2 R
write_LCD(0x01,CMD);
8 _( C$ P2 h4 t delay(10);
2 q: }1 V; T/ n/ G
3 M/ T6 N5 t. o1 i' e/ e g* u SetXY(0,1);//设置标题显示位置
8 V; }& \% [9 S LCD_wrstr("Tachometer:");
# d4 e7 U" O# g5 X8 c0 J: D2 ?
7 g7 v% |, T% P- }& e1 [+ Y, p TMOD=0x01;//设置T0位工作方式1——作为16位定时器
+ S$ a" W4 A) p! _9 _" `; p X ET0=1;//打开定时器0的中断
3 [/ w3 i* t2 n7 o* Q. C TR0=1;//打开定时器0
% N9 z0 O5 H, e4 H1 l. T7 U TH0=(65536-50000)/256;//装入初值$ k2 @3 Q1 l6 j1 X4 V/ d5 \- P
TL0=(65536-50000)%256;4 j% \$ f4 z5 f$ M' X
IT0=1;//外部中断0为下降沿中断0 Y/ C1 g2 G1 u! M4 B4 M6 C
EX0=1;//打开外部中断( l: }4 k+ [; W5 C0 j) M
EA=1;//打开总中断; V8 }7 Z" G3 S* `9 z6 X
}
7 ]# Q' L$ a1 ^# o( }6 J( m2 S" {void main()) U3 B9 a; I: X7 V* D0 o
{
; _" |/ Y- J1 u9 O {2 i5 L6 d/ \ All_init();//先进行初始化! ?2 t e: _. X6 e2 @8 {3 Z
while(1) z( j) _% V: ?8 b2 Z% S! A* v
{
1 o7 W, C4 k& K; S if(flag_1s==1)% p {+ u0 O1 ]" {* w
{: U3 g1 Z* {' v; O4 O- k' R
flag_1s=0;//1s标志位清零5 k3 f3 |5 u1 v( a, [2 u7 _) T$ X- Z
disload(N);
. W: F$ d" w; N) D9 @ }! g7 K7 s& C& V0 Y3 ~6 L
}
9 A6 w# z |) X* G2 M, [/ u
) U! o5 t/ t6 L2 k* k2 a l}
0 T( z$ v5 Y% W; E& l; q/**定时器0中断服务子程序**/1 U$ {8 u1 d5 j3 U( z0 d- |* F
void timer0() interrupt 1
$ g7 e6 a$ i% m$ h' I7 f' I2 c{
; @2 t* D6 h& ^ TH0=(65536-50000)/256;
& e' k' P: r' G5 s3 Z# D) R0 I8 u TL0=(65536-50000)%256; p: e2 v- I4 U) E; ^0 z7 R
if(++C_50ms>19); F) Q- _9 p) b9 j3 C7 O4 q$ e
{+ x {# w# K4 E; @5 t
EX0=0;//关闭外部中断0
+ B+ Y4 y9 r8 ^" \3 ~" \ C_50ms=0;//定时1s之后C_50ms清零5 }$ g1 @5 n) {# ]4 f) Q( W; E/ o4 K
N=60*Z;//计算转速% a( a& u- k. d& V+ Z5 Q( L
Z=0;//初始化圈数
0 r. n, q8 u2 b C# j: N0 s flag_1s=1;//1s标志位置14 \- I8 M; [# X: v* V$ M5 N' b4 m
TH0=0x3c;//重新赋值/ q; j M. |) e! |
TL0=0xb0;0 s; s7 z. Z/ T' y
EX0=1;//打开外部中断0,开始计数。0 g' h0 E7 O% q! C; b4 d& V
}
+ Z5 s- `9 Z: Y; x) h4 _0 t}
. L! t" p- J0 Lvoid wai0() interrupt 0# Y& v! U- s" }. i2 x$ \/ m
{
) d; V' ?! H5 j+ u$ U count++;$ z( }) |# j9 s; g
if(count==2) //两次外部脉冲,电机转一圈。
2 S8 `; P8 H @' k& r8 N {
# T- }/ f7 z/ H0 P6 ?5 ^! n+ a Z++;//转圈+1
+ y: q5 X1 _, `* E) v. K count=0;//初始计数值
' F+ A+ @# G7 u/ ~. v( R }: I; a9 ]( s3 }4 q
1 @ w) E4 v: v7 h' S, _, k}7 z d. r! M! s% C
, F& R, m) \( ?5 ~8 y
|
|