|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
简易自行车里程计仿真图及单片机源程序
% H/ V& t% d6 w+ |3 P6 p; K& r- [
3 R9 N6 j5 l3 }6 S1 ^: i: O- L; i! ^/ Z
由于仿真中没有霍尔传感器,实际呢霍尔就是感应磁信号,输出高低电平的脉冲信号,这样用脉冲就可以了,不同的频率代表电机转速的快慢 . |0 f# f8 `( g/ T3 d
单片机源程序: #include<reg52.h>
) i* t% f# a1 F" m% I, \5 p
`; t4 h/ j1 l2 d* K* ^#define uchar unsigned char
- d0 z6 f; T8 V7 a) v#define uint unsigned int7 |: ?& T( x& i9 T
& Q F2 U9 I- }& @! D1 S
sbit COUNT_IN=P3^2;5 j' n& y" V) c G3 }; t
* X1 M: y ^' c7 g, ` b& e8 F
//定义1602相关管脚
; K6 @0 I- J; }9 ?+ o0 g; Dsbit rs=P2^7;
6 A n$ a. u# z+ g, vsbit en=P2^6;+ j2 N: F# B9 q
: W/ h# @! s, {$ Iuint count;* p% w! m0 u+ n3 ^) k
unsigned long Velocity,Mileage;
$ ]$ y4 e9 n/ b0 a8 n9 s/ v1 |bit flag;8 C2 M7 ~2 S* {( r9 ^& B
uchar code tab1[]={" Speed: km/h"};
( W' R B4 V% n+ V1 l) Huchar code tab2[]={"Mileage: . km"}; $ Y; ?2 ^8 A$ M
. K) J# a2 w' m: p1 Dvoid delay(uint x)* U0 r" t% _* [
{
% f8 G; X" W' z, ] uint i,j;
+ ~7 r3 p" N* D* Z" S for(i=0;i<x;i++)
3 y. e8 s; g# @8 A( X8 t for(j=0;j<110;j++); o7 W7 ~% M8 y
}
5 m4 |! D+ [6 P Yvoid init()
" }4 Y* b, i! o) m7 A, j7 Z( f{* E% n. U, Z* `& J
IT0=1; //INT0负跳变触发
: k1 f5 j W/ ~! n$ n TMOD=0x01;//定时器工作于方式1
/ _, @9 G& K, t& H. E+ H8 P) P! x TH0=0x3c; //50ms2 h; h1 S* K8 |! k7 c% S
TL0=0xb0;
( k0 F- j+ x+ U0 N5 l EA=1; //CPU开中断总允许
4 D9 y+ L+ }: V+ D$ w* i ET0=1;//开定时中断: W2 w/ p1 _2 Y/ l% a
EX0=1;//开外部INTO中断
; Y* G% Z4 W" n5 g TR0=1;//启动定时
6 p- k3 G: m9 K" h0 h1 {! q}
; A" F1 h1 P8 i3 |# g1 g* @ K/********液晶写入指令函数与写入数据函数,以后可调用**************/
! ?& K! O- W: @! v, i) R
, r0 U* ~. c2 Ivoid write_1602com(uchar com)//****液晶写入指令函数****
1 M0 u5 R! i$ Y6 ^' |{ a- R. X! F* ]/ g
rs=0;//数据/指令选择置为指令
9 o# d) R( u- Z8 b) x P0=com;//送入数据
; U8 H8 d: x9 n5 C! j& @* M delay(1);
5 S/ \/ y1 f; @. y en=1;//拉高使能端,为制造有效的下降沿做准备
( B5 ~; ~ g: z! g8 r1 | delay(1);$ y. S, t$ d3 N; d. z
en=0;//en由高变低,产生下降沿,液晶执行命令' g# s2 s. g1 s/ g7 w8 G& }/ E/ S
" k9 C( M9 i. @# |3 x' D# H
}
* Z1 w( K* H% b. R2 I2 N; g: }' Q* ^: c# b4 u
, g$ g! q8 Z$ |void write_1602dat(uchar dat)//***液晶写入数据函数****/ ~# N* c! m* u5 ]1 {( h
{
. U- F: W2 W( D+ ~ g rs=1;//数据/指令选择置为数据
- i8 b% Z- t* _$ p9 p4 c1 v; c9 `% d P0=dat;//送入数据4 G% n. }6 e+ ?( t
delay(1);+ O5 @8 Z1 n! _4 g+ e' b$ ]" f& ^( O
en=1; //en置高电平,为制造下降沿做准备! Z: O3 g. ~( i3 W; L
delay(1);
. [+ e$ d% |. R w. ~& K( o en=0; //en由高变低,产生下降沿,液晶执行命令
; S9 _9 I L% p5 A! N! m}
' F# l8 C8 K( v$ W ?7 K5 O; X3 G% g. R$ O
! R0 v* g2 H- p6 O2 u
void lcd_init()//***液晶初始化函数****
+ |- W s \, z/ I{7 l( n- N% [& s7 j
uchar a;
5 w$ d8 L8 ?1 x' a, n write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
* [, g8 _& b+ L( Z write_1602com(0x0c);//开显示不显示光标8 _8 d4 @' x3 K$ Z# u) J# o
write_1602com(0x06);//整屏不移动,光标自动右移# H' x$ p+ b0 r2 A
write_1602com(0x01);//清显示" R! S4 U1 h* B' M& z9 F5 n! T
; D& Q2 V7 n+ { write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示) r' @, x2 [6 ~) n( w
for(a=0;a<16;a++)2 _9 \$ s6 i3 w0 R( X4 i
{# w' h) @1 ^, t8 h3 P
write_1602dat(tab1[a]);//向液晶屏写固定符号部分# u4 d: Q& |' t! k1 J$ ?
}" C7 ?, b) f2 N4 y
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
' H/ Z+ j# w2 I5 S( L/ u for(a=0;a<16;a++)$ z2 v. Y7 Q* O1 x5 x4 {
{
" w! h. m% f, a1 m- p2 N2 n R write_1602dat(tab2[a]);//写显示固定符号# R2 h# h, x4 K
}
, }: w. {/ x2 `8 U# ~0 Y}
' [9 N$ E$ a2 j& U1 K& K
3 L2 Y6 Y. i1 ~void display()3 n( a# g0 \! O' o% V" j
{8 t4 J. Y, }* d
// 1km/h=100m/0.1h 360s
, S- e N8 g7 E3 o. Q // 10km/h=100m/0.01h 36s
8 I+ H [* y- Z8 Z // 100km/h=100m/0.001h 3.6s# O1 P. B) ~# l6 p% C, w
; `# U; C! w9 F. e5 y4 [ `7 w
write_1602com(0x80+9);% _ W( o! C! S3 M% `
if(Velocity/100==0)( ~$ b9 V1 @2 d2 k* F
write_1602dat(' ');* H" p& m8 b' y% q- d0 \
else! r6 e# j% p, D! E
write_1602dat(0x30+Velocity/100);
& J0 K0 F( c% _ if((Velocity/100+Velocity%100/10)==0)
4 u. y6 Q% a/ y4 K write_1602dat(' ');
* l$ `4 h$ T3 x. } else- A S% |+ m2 V3 J4 [) ^( `
write_1602dat(0x30+Velocity%100/10);
: `9 K; |$ `! z write_1602dat(0x30+Velocity%10);//数字+30得到该数字的LCD1602显示码0 I9 R3 h5 m* h2 E: t9 ~
2 h. j' D; h! Y+ U* K+ n3 _ write_1602com(0x80+0x40+8);% S0 r. z% h, ~2 G
write_1602dat(0x30+Mileage/1000000);//数字+30得到该数字的LCD1602显示码
# o0 B/ z' A3 U9 `6 Y5 B' L write_1602dat(0x30+Mileage%1000000/100000);//数字+30得到该数字的LCD1602显示码 , `" i& n' c+ z( e( J3 H. G; D
write_1602com(0x80+0x40+11);
5 h4 Q7 ~/ n6 v3 H6 Z& } write_1602dat(0x30+Mileage%100000/10000);//数字+30得到该数字的LCD1602显示码* v3 A1 @9 o7 ?- K6 Q5 U$ Z, A
write_1602dat(0x30+Mileage%10000/1000);//数字+30得到该数字的LCD1602显示码
' t/ {, M2 ?9 r* ] ^! ^; } F0 W. y* k- x2 {
write_1602dat(0x30+Mileage%1000/100);//数字+30得到该数字的LCD1602显示码* B2 e( [( r V' l4 g1 g
}
% I7 Q5 e1 }" |1 z9 \5 ^
- C( {* M/ W4 h' A. e! cvoid main()
+ L# s) A1 e: w- x. q! L6 w{9 i: N4 k, c- p% N
init();) H% r @5 f2 L$ s0 {
lcd_init();& U. `+ c& N* H5 V& r/ H# @
while(1)! A/ z+ V% @+ _7 P+ Y1 i1 c
{; X$ b( \7 @8 Z* |
display();
9 m- \0 y: B2 @% d4 E1 U }: t% m- b. D* p% w
}
( d8 n& z2 t# Y( C' N% z- X
3 C* e; v: ]' L0 bvoid EXINT0() interrupt 00 k" c* U" H% B/ k2 w
{
. T) O" y7 h1 F( w count++;
$ {; L; o: ?- H z) H" V}2 D! a* O3 Q. R& C
8 C% s5 n! D( M/ x5 Evoid time0() interrupt 1
1 b8 }2 q( z* c{
. v9 A. ?; M0 S( R% y+ r( t. y, @* e uchar m;
0 [3 d1 J9 k1 ~6 }! D" V# h TH0=0x3c;* @" k/ c4 _8 n0 g* K# b9 [2 A
TL0=0xb0; //50ms
9 P1 M: M( H7 n0 w- D+ g m++;, u% R H# [' |& c; G
if(m>=10); }* C0 T+ Q: e. u2 ]/ Q! D
{' D5 e, g: u0 r2 E
m=0;
" l/ q0 i' E2 U" C, b" K Mileage=Mileage+Velocity*500/36; //里程m=速度km/h*1000*5/3.6- E8 j2 \" ~& [7 B" J
Velocity=count/5;//将100ms内的脉冲数
9 h. l. e: {" j& `! \ count=0;
3 K5 i1 I7 ^8 I9 d) e! k, y, |: Q3 @9 w- W- i) D( i! e7 C* |
- M: \$ Y# U6 Y
…………限于本文篇幅 余下代码请从论坛下载附件…………
7 ^- ^" p$ R( J& A+ t% k- f+ @3 v
, {% b- m! C! y8 T& F' ]: _7 k! } | / l8 D; k% h+ I% u8 a* F
|
|