|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
简易自行车里程计仿真图及单片机源程序
) {+ _ |3 j/ A% l0 a
: Y6 B& M# w6 V8 v! c0 H
4 r4 m6 ~- X" D0 \( P/ b( w/ o2 i& K
由于仿真中没有霍尔传感器,实际呢霍尔就是感应磁信号,输出高低电平的脉冲信号,这样用脉冲就可以了,不同的频率代表电机转速的快慢 ) x; i- [7 `0 r Z3 {3 G
单片机源程序: #include<reg52.h>
; S0 A* o: A3 ^6 z C6 R- E8 @5 `" f
#define uchar unsigned char
+ d5 G: L- B2 q#define uint unsigned int1 S( {2 [! k' y. i! X
- u4 v7 U* l4 m3 p
sbit COUNT_IN=P3^2;, a1 m3 Y% O8 j6 j% g
$ t( w8 m$ S; z9 @4 N$ z& c( t
//定义1602相关管脚
" h7 p7 [5 Q& m: L# e/ a, a ssbit rs=P2^7;
9 E# Z8 i& Q3 W( J Osbit en=P2^6;# {: ?" ^5 k* `2 i8 x
1 K* r& s- ]( e/ Juint count;
# L1 ?0 i$ S4 y# Z) funsigned long Velocity,Mileage;' b1 i% }; n5 F9 P, I
bit flag;8 B6 B1 ~8 o* `& D$ u6 P% x4 y6 r
uchar code tab1[]={" Speed: km/h"};
0 H# U# P' W1 l* r. H: Z; quchar code tab2[]={"Mileage: . km"};
9 C5 k9 n$ L/ ?8 M* n8 _( `' d7 [/ h R4 h
void delay(uint x)
, h) G5 ?3 [. ?4 f2 d- _3 O: l{" J1 G& g0 F: M: @
uint i,j;
1 o4 z8 x; q. o5 L" J for(i=0;i<x;i++)
# j9 k$ C v1 j6 k for(j=0;j<110;j++);
$ X. j( p; B) c9 L: b) P7 I. _}% c# ^7 {9 k4 F8 `0 v# T
void init()+ Q* m [ ?8 |3 k2 Z$ u/ a
{
0 J/ w, U, j6 A x$ S IT0=1; //INT0负跳变触发 / B! ]+ u/ L& O$ f1 e, ]8 J: p: p
TMOD=0x01;//定时器工作于方式1
- q% A* {) Q( Y0 [ TH0=0x3c; //50ms5 \( x- D# i9 k3 |
TL0=0xb0;
" s# D/ j1 o3 ]. x# f* \. N EA=1; //CPU开中断总允许5 Z& t8 D& R4 f+ ]8 ^3 j
ET0=1;//开定时中断
$ v& X. @2 y, `8 k, L+ h1 f EX0=1;//开外部INTO中断) z6 G' H# l' z( e1 f9 Y) r
TR0=1;//启动定时
8 Q& Q- z. F! m! H; }}
2 {5 p* w( Z' A* K/********液晶写入指令函数与写入数据函数,以后可调用**************/
$ o' M3 o( u6 V% x% S& Z) b3 N- { Z3 u! T" j! Y5 r& Q
void write_1602com(uchar com)//****液晶写入指令函数****
a7 F- U* a" `1 x{; Q% q e* k; A8 |+ U
rs=0;//数据/指令选择置为指令/ w6 |+ k+ \; B5 `6 Q
P0=com;//送入数据
, V4 u2 I) W7 D6 m: u delay(1);, Q4 f, G' E+ b
en=1;//拉高使能端,为制造有效的下降沿做准备7 g, f8 N; v6 |
delay(1);
2 E3 {& p- r8 N C1 X' o en=0;//en由高变低,产生下降沿,液晶执行命令* L) P# n8 C, b& ~0 I
6 a% j# G7 \' H! M3 S}
% c, g) w' I2 ?' s: B Z2 ?, D: j( V+ E! F" a e; I
& p6 q/ {" v; F, V- V' t4 A
void write_1602dat(uchar dat)//***液晶写入数据函数****# D) R. K, x; D4 w
{! U/ n# l/ j$ t# i4 \% o
rs=1;//数据/指令选择置为数据
/ z7 b4 C { ^1 {0 F, z P0=dat;//送入数据
0 ]) |+ ?7 L O) @ delay(1);+ @; E1 g4 \9 b* Y; K
en=1; //en置高电平,为制造下降沿做准备; |8 J2 \& _ i4 \; O' S: b8 a
delay(1);# r7 `6 `2 H `0 k U& b- J' h( z
en=0; //en由高变低,产生下降沿,液晶执行命令
( R" Y. M- E6 K% v" V- [: L}
$ d& a& z. S. G9 t: L# Z, J, U
7 ]" d2 ]: o1 {. z8 P- x+ n( z. [* r$ C, g J
void lcd_init()//***液晶初始化函数****- d4 s! f) M; w% B# p
{
2 y8 p1 g6 j# F3 V- Y uchar a;
& y0 a2 [ B. Y( ]; T write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据' S0 f) O0 ~' c7 V) V+ T) O
write_1602com(0x0c);//开显示不显示光标/ E& M! d# C& I5 W' ^
write_1602com(0x06);//整屏不移动,光标自动右移
3 u* ?9 p3 m9 U1 v5 m+ r! V, u% ? write_1602com(0x01);//清显示
. Z) a1 P( ?! m* K. g& {2 D$ k. v4 N8 }$ J0 j
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
; k9 Z( X, u0 } for(a=0;a<16;a++)* m; x. |6 u7 R5 Q4 O" Y
{
+ Q& x# o. l; q4 B/ T- {! o7 t write_1602dat(tab1[a]);//向液晶屏写固定符号部分( k$ R3 _% p5 @( n. Y2 m7 d5 v4 o
}; b" k# u- H) r0 ~ {. \0 c
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
& y5 I! Y8 W2 T1 D3 ? for(a=0;a<16;a++)
4 S( V4 y, Q. S6 U4 K+ W! M; R9 c4 _ {0 X5 `$ g0 N! R# n5 j( c: c+ C
write_1602dat(tab2[a]);//写显示固定符号! \, f- U. Y% u% t9 c
}8 `4 E$ s! N: U! I3 O
}" a2 G N& q9 v& B
, F8 z& e) }7 _" J, K- w& W
void display()4 l3 A+ G9 O- H. e) w7 ^
{9 V( x L6 N% P" j! F
// 1km/h=100m/0.1h 360s
' v4 f7 r" ~. ^, p4 Y" s // 10km/h=100m/0.01h 36s
9 Q6 U2 c5 J0 k8 x // 100km/h=100m/0.001h 3.6s3 M- u9 ?' j2 \5 m- Q) M7 \
4 a8 l$ {$ R3 [& a) H
write_1602com(0x80+9);9 c7 ] I' w+ J/ r9 G2 e
if(Velocity/100==0)6 T7 @* ~5 }4 o: Z; i4 r, t
write_1602dat(' ');3 W! ]& r# K+ C, D! S$ A
else( m# [, \+ k: C+ J0 T) u, a
write_1602dat(0x30+Velocity/100);
! C5 |9 c7 S: x: t8 g, T) X if((Velocity/100+Velocity%100/10)==0)4 w5 C* F+ u5 d' l6 J5 s/ m& u
write_1602dat(' ');
+ _- V* R# y( P, m' A# O! R$ D else
0 i# g. [; b' `$ v$ N6 C% J: b, u$ w write_1602dat(0x30+Velocity%100/10);
' `, c2 q' P9 M% Q/ |# P1 f1 V; t write_1602dat(0x30+Velocity%10);//数字+30得到该数字的LCD1602显示码
% ?- D2 D" K) B! S" m8 x! n. c" }" f
write_1602com(0x80+0x40+8);
. ?% Y3 K; r, u' \6 {! C8 q write_1602dat(0x30+Mileage/1000000);//数字+30得到该数字的LCD1602显示码: q# b8 E& _! g0 I5 F6 F
write_1602dat(0x30+Mileage%1000000/100000);//数字+30得到该数字的LCD1602显示码 ; _9 q: d2 P, b6 R2 V9 M
write_1602com(0x80+0x40+11);- }* E3 ~+ f" ?
write_1602dat(0x30+Mileage%100000/10000);//数字+30得到该数字的LCD1602显示码$ {- g' w0 s z# c
write_1602dat(0x30+Mileage%10000/1000);//数字+30得到该数字的LCD1602显示码1 E/ Y0 H0 H3 v7 g8 ^# m( b. r) q
! B( Q2 h5 T& K4 n; {
write_1602dat(0x30+Mileage%1000/100);//数字+30得到该数字的LCD1602显示码) b- F, j3 U5 g
}
4 K; p( G# i) a, T# A! h
# D! X5 g3 p7 e9 A$ I# _4 Mvoid main(): F% `; `& S/ F( C; K, I
{
l; g. S- x4 {; @* A init();( t3 o U5 A5 q9 C
lcd_init();
2 }3 J% J4 e, ^ while(1)) W* k0 h1 y" s( f, |/ G9 A+ G" b' b
{3 ]5 i- i1 M: S+ }; Y- V" T
display();3 Z5 e2 d/ U% d8 A2 [: P$ m: d
}' y+ ]$ K+ m* r6 v1 f
}. f1 [( T" x/ K `9 C2 V
9 O3 w4 I& o# e
void EXINT0() interrupt 0
" T4 S& i2 x! j/ z4 O* |{
! k- ~1 e' p- g6 [( i& P$ c+ m5 y count++;
& U/ P1 T7 o& H}' G7 l* |& q+ C. N
* c! G Q/ g4 {) B- F8 G/ R) R
void time0() interrupt 1/ A9 u/ ~. V. P. n- f9 x
{
2 U, Z) S3 @1 y& q- w uchar m;
" A" S5 W( @$ W4 ` f, ~; w TH0=0x3c;* t& G- w0 s' i5 G5 F& a- v6 D
TL0=0xb0; //50ms( N- V: `0 d/ Q# x) _. ~4 D1 h) O: B
m++;% J# k* a/ {7 ~" M
if(m>=10)* c# E/ S& E5 p# ?% B a* {
{- x1 S2 }+ d' ?9 a
m=0;# J! I9 U& B% d
Mileage=Mileage+Velocity*500/36; //里程m=速度km/h*1000*5/3.6
: a- {. H0 s: O& c/ R Velocity=count/5;//将100ms内的脉冲数! ^. c, P7 k4 k6 p( l7 u- I
count=0; % K& D7 I+ G2 h) k% p( X' J
; a. Y/ \3 C+ P# y t3 O4 g- l: o; k: y n. e
…………限于本文篇幅 余下代码请从论坛下载附件………… ~) v. m& o W. j/ A3 T
l! g; D* m) X, Y3 Y+ h# k: J* Q! R
| 8 ^' w& x; o* m( h0 s$ p- p
|
|