|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
简易自行车里程计仿真图及单片机源程序$ O$ ~1 v. \0 x/ | R. D5 w' p
) _& g) d( [, A% Q ; a/ c* c! f: `# ~" B. g4 d7 P
4 V6 w# [/ h; q4 e; n由于仿真中没有霍尔传感器,实际呢霍尔就是感应磁信号,输出高低电平的脉冲信号,这样用脉冲就可以了,不同的频率代表电机转速的快慢
& d0 M! u$ h& e, ^/ J单片机源程序: #include<reg52.h>
! j6 }5 ?, _) m8 Y; N5 M K1 j2 w
; P% l% U& P: i+ P* t, c0 `; x! A& Z#define uchar unsigned char5 \5 }+ }& I8 a3 P3 \" q
#define uint unsigned int1 }" ]3 g# @+ R: b* n* H: `6 l% Q5 {
6 [, N5 X+ c9 s4 w R
sbit COUNT_IN=P3^2;
" c; t9 M" X/ J5 K& V( D7 K* H4 q2 S, W3 n
//定义1602相关管脚
; q$ r+ k: f! L% |6 G" ]! Vsbit rs=P2^7;7 Q y6 V6 T, k' H
sbit en=P2^6;% Y Q8 k- R# Q5 X, @& Y5 ?
+ n2 i9 s. e' |1 l; h3 U
uint count;
1 u+ {: f0 W1 _# a8 J) Junsigned long Velocity,Mileage;
5 B K, e A/ {# {: Y% pbit flag;
$ U2 }7 o0 L) Suchar code tab1[]={" Speed: km/h"}; ; Y* W/ F3 |; Z4 X" R* ~ \; n
uchar code tab2[]={"Mileage: . km"};
7 ]5 u/ i- {1 `( D; e M% i; T. B3 \" @7 A2 V4 k' @" J
void delay(uint x). L# m9 X! F2 q
{
* f, \# T$ X& a uint i,j;; ~7 P7 ]! o* B: W6 c% G( O6 x
for(i=0;i<x;i++)1 _2 |7 {% Q8 X' z8 r8 p1 [
for(j=0;j<110;j++);
6 M& C0 t1 A( M- B, _}, ~) i: s5 }' X; c0 L
void init()
- H( _: Y4 u3 u, R: O{
4 K6 ^, }) q! C+ \& } IT0=1; //INT0负跳变触发
, _! O0 A3 u) j. N6 }/ i) e3 j& k( g TMOD=0x01;//定时器工作于方式17 Q0 a, W# w' j( B1 w# `# b) D
TH0=0x3c; //50ms
: ^, R9 Z7 s# d1 C( @: G9 E3 p. ] `- m TL0=0xb0;' q; Z1 T4 f; { v: T! \( Q
EA=1; //CPU开中断总允许6 S0 e+ V) ?* a+ |
ET0=1;//开定时中断, e. L& _0 N A* V, ~, j+ c
EX0=1;//开外部INTO中断7 @1 l m' T5 O2 q6 g
TR0=1;//启动定时
1 d8 ~; Q* ? |; e}4 G. S! L: E( |& U
/********液晶写入指令函数与写入数据函数,以后可调用**************/' I( U' ?: F# R% h( r# u
0 e8 J0 z. i0 C+ s Z
void write_1602com(uchar com)//****液晶写入指令函数****+ z9 Q' ~ p0 q& z* G' I2 E' w
{
4 U% o! V1 m6 E9 y rs=0;//数据/指令选择置为指令& N8 ?) ~% v. }
P0=com;//送入数据
1 j( ^: V* V% u5 W; q% } delay(1);0 M% l9 \$ q$ Z+ {, L/ j( g. w( @
en=1;//拉高使能端,为制造有效的下降沿做准备9 H3 O% c9 T6 R6 u
delay(1);
9 }5 z# P3 A# {8 B en=0;//en由高变低,产生下降沿,液晶执行命令4 h( w/ U2 v( e0 Q5 X+ w X6 C1 f( w
s6 E+ N, ?1 a# S}
" Z4 ~) P y6 a# y- v) M
* p |8 {8 ?. c& U6 L9 T$ J- h* y( Z2 L: A% B5 j
void write_1602dat(uchar dat)//***液晶写入数据函数****1 ?, X9 S0 {" d3 D: x5 k( N
{
! \& y6 F, P+ I4 a' p/ q2 j) X+ a rs=1;//数据/指令选择置为数据
( z! N, V/ K8 } K B* {7 B P0=dat;//送入数据
8 m5 p/ }6 P5 K4 ^$ F/ k delay(1);
0 E( O2 I7 d7 X en=1; //en置高电平,为制造下降沿做准备
6 r: K! K) `! ]/ Z' Y2 N delay(1);
6 J9 }0 ]2 h& l0 b en=0; //en由高变低,产生下降沿,液晶执行命令- K* L* e/ P+ k* o9 B
}, |( ^- v3 b* j$ _! h% S$ R4 r
! q! I6 b* U" L; S' P1 v3 F
8 J( s( v) {$ K' J8 y, P) T* Ivoid lcd_init()//***液晶初始化函数****
! ]" h `! l# z1 m1 n' d3 `: s9 l P{9 u8 i1 D+ w8 r: m/ B! l6 r9 L
uchar a;( ~5 V1 n! T4 a R8 h# `
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据 d" C% T- k: j L. y
write_1602com(0x0c);//开显示不显示光标
0 M# G4 |/ I: H. m" I write_1602com(0x06);//整屏不移动,光标自动右移" K7 E: f0 H: L+ a# H- }
write_1602com(0x01);//清显示5 G4 @3 \, T# M% x! [
g P3 J: O4 z
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示# x: C$ a: Y K
for(a=0;a<16;a++)
5 g% B, [/ M" @" U) {/ b {
1 s/ O, U8 u+ m1 F8 y# z; W write_1602dat(tab1[a]);//向液晶屏写固定符号部分
4 P; {, ^ p1 B4 Z! |6 s }
! l8 q( t6 `8 ~' l write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
5 A. d5 o/ \) _- Q; `% c for(a=0;a<16;a++)( v" S5 a. J) `7 j. c
{7 D& o6 K) n, S+ B
write_1602dat(tab2[a]);//写显示固定符号" ~/ Q. K7 t4 h! B# k( n2 `1 h
}
4 {. I1 n9 Q) J7 @/ @- z* g5 G" N! G}6 {; i L8 Z# o/ w
( M( l1 W/ n& P1 U) D+ ?6 X) J
void display()# N; I5 x- {; }8 l. b. o! Q
{
/ O) ~: H5 j5 p4 h2 _4 `5 Y // 1km/h=100m/0.1h 360s* w( e# [8 L# K# n$ l
// 10km/h=100m/0.01h 36s
. t- h. x! j7 b // 100km/h=100m/0.001h 3.6s
9 N x- K& {- O, s B0 N1 X0 l8 |2 K I/ R* s9 `
write_1602com(0x80+9);
+ R, Z7 o `! N$ P! D# k5 U t. O1 ? if(Velocity/100==0)$ U$ @* p- M. Z) W$ o! g; q0 @
write_1602dat(' ');
\* j9 H+ t/ M- N3 a else0 r4 n' l6 ~; R5 X# n6 C* A8 r
write_1602dat(0x30+Velocity/100);
4 g2 D: `# V' D$ |% G: p1 x if((Velocity/100+Velocity%100/10)==0)
( e5 P# x9 X& q write_1602dat(' ');& B/ R( N e' ~8 g% O( i
else
% A% f5 H5 X3 Z write_1602dat(0x30+Velocity%100/10);
" E! f( j1 l4 x$ [; x/ ~% Y write_1602dat(0x30+Velocity%10);//数字+30得到该数字的LCD1602显示码8 f4 k5 D T6 p2 c, \
, }5 W( z' Z9 h write_1602com(0x80+0x40+8);
( r4 R8 A3 n5 d0 \ write_1602dat(0x30+Mileage/1000000);//数字+30得到该数字的LCD1602显示码
' ~. N! s) g5 O _1 \* g2 v write_1602dat(0x30+Mileage%1000000/100000);//数字+30得到该数字的LCD1602显示码 ! w( \9 T0 w2 C9 V- s; ^. O& k
write_1602com(0x80+0x40+11);" | G! x: J( W( M; Y' ~
write_1602dat(0x30+Mileage%100000/10000);//数字+30得到该数字的LCD1602显示码
: K2 d4 x2 l/ O" N5 B. p# n write_1602dat(0x30+Mileage%10000/1000);//数字+30得到该数字的LCD1602显示码
0 a. ]1 r. P( P2 X) j
# F5 v' e A) y2 q9 O5 d write_1602dat(0x30+Mileage%1000/100);//数字+30得到该数字的LCD1602显示码/ b W3 I d ?. V- I; ~) w! {
}
8 l l3 q" @( P3 z' f$ R- \* i, W, R
& `( v7 k1 C; [7 V; rvoid main()! @5 P( {9 n& d& d
{8 V( ]+ ]1 I( b/ {) O' _
init();1 A8 L; ^/ G, m1 [
lcd_init();+ o- g' I; y. `. y) V
while(1)/ J& N% v n% c, x1 G
{% w. O6 B5 F* y- D5 S9 i
display();& x3 `8 I( X% ?; Q* {
}) G/ L5 y0 B$ z
}: l1 Z* I p5 [: P/ O5 _: m, B% Z
" C; Y2 D1 _: k9 i8 gvoid EXINT0() interrupt 0+ c4 ]0 ?# j a# G, `4 ~
{
1 ]1 W T, w5 j# y, P5 p9 S9 t$ C0 B count++;" B, F- i( z) q. P% A9 }& O" h
}% G3 O+ Y5 o! V: K2 E- V$ |7 N# ?! \
6 Q6 k$ J, H3 i3 p' \8 o3 V% y
void time0() interrupt 1 ?2 \% j/ u" v: u* v! v
{: X9 B/ d! g" x9 d7 b: O
uchar m;
+ ]- }& c; j) U9 D! r TH0=0x3c;
9 e, Z4 @ a2 `2 q( S& d. X" Y2 F2 r TL0=0xb0; //50ms2 J# c# N" o' N& q+ ~2 U1 b
m++;9 F: `1 U( Q- z
if(m>=10). P# Y0 U8 b7 Q1 W7 |
{
% C6 y/ y5 z9 C' w, ]- {4 P8 s m=0;
4 v2 B0 u6 { |4 G Mileage=Mileage+Velocity*500/36; //里程m=速度km/h*1000*5/3.6
% r' ]) I1 z# u Velocity=count/5;//将100ms内的脉冲数
( c7 @9 W8 e4 @! Y" s/ a count=0;
3 Y% m. s0 D5 @2 m/ j5 Q; h' F) u$ L; S- H0 C
5 o- [! ?* ~" A! h* \/ s+ A…………限于本文篇幅 余下代码请从论坛下载附件…………5 y' a& H& z0 F N9 s* V5 X$ c
" t% O, w+ v/ s7 ?, s* t% r
| ' f' f. O; F. h. h& z% H
|
|