TA的每日心情 | 开心 2019-11-20 15:00 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机酒精检测仪源程序+仿真 DXP格式用 altium designer Summer 软件打开 + b6 w% l3 v8 u: w3 U
protel99格式用 protel99SE 软件打开
; y8 ?; W# z) ]# v# }6 qPDF格式用 PDF 软件打开
" s- \$ h4 [/ k% L% H' uWord格式用 Word 或用WPS 软件打开
+ B( W" z* C0 V3 E' B
- S/ j' |) S3 l2 @+ e; K, o( E6 |. z+ F4种格式的原理图都内容是一样的 只是打开方式不同- ?. X& U6 [2 \
$ r1 [. l' n2 d R2 P+ i F; A4 {
请看原理图焊接,不要看仿真图焊接。# |: ? R7 r8 }3 @ ^( f# Q
3 }0 L. o/ T! B
wrod格式里面的原理图是复制出来的,有一点点变行变形,麻烦大家注意一下,尽量看其他三种格式的图焊接,
3 i0 G, w m" x* N: a/ w0 i: G' E, I. M9 b# l. W ~; F
如果论文里面的原理图和原理图文件夹内的图不一样的话,请大家以原理图文件夹内的为准,原理图文件夹的图是和实物配套的,可以自己截图或复制,然后粘贴到论文里面去。
! k9 `' g; r( i2 p1 z4 J1 ^) r. F
单片机源程序:
L* x- z6 |4 V3 y8 g: _+ |' p
( n9 {9 ^: P% b2 V/ `8 T7 J7 F#include <reg52.h> //调用单片机头文件7 `6 N* j5 }1 g
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
2 \# @2 B3 O* o7 l2 @( X! g#define uint unsigned int //无符号整型 宏定义 变量范围0~65535' |7 o: | C! u8 D6 R1 M4 N/ M
uchar a_a;
' Y6 w- C; q/ {6 V+ O#include <intrins.h>. Q% \9 ~) N# ^9 c
# t6 D; ?4 S* J$ R* L8 }% [- x" \3 ^4 S! a+ y
//数码管段选定义 0 1 2 3 4 5 6 7 8 9
' U8 b) P% {' K1 u' Puchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x04,0x14,( a# O0 a) i. J% U9 _
0x0c,0xa4,0x27,0xc4,0x26,0x2e,0xff}; //断码- V# J1 h B0 T8 m$ s6 o: i
) F; j0 |$ i2 l9 J4 [( x7 {
//数码管位选定义4 @3 _- y `* N5 T
uchar code smg_we[]={0x7f,0xbf,0xdf,0xef};
. m- d4 h( @# a+ Q5 h/ g% X1 uuchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8}; % r. ]+ u$ H+ A- i h# B. |
uchar smg_i = 4; //显示数码管的个位数: J/ C* V6 [. s/ ] J5 q
' I$ y% M: D3 \4 F) q) Asbit CS=P3^2; //CS定义为P1口的第4位脚,连接ADC0832CS脚
- _' \1 \6 M( w7 Z, c8 u( Jsbit SCL=P3^3; //SCL定义为P1口的第3位脚,连接ADC0832SCL脚
; v; L$ P6 d$ P; v3 k) o- z1 asbit DO=P3^4; //DO定义为P1口的第4位脚,连接ADC0832DO脚
3 U3 s; p4 }/ f. B1 O; P- W# Z0 f( `4 S( {8 X& S
sbit beep = P3^6; //蜂鸣器IO口定义- Z ]. A$ E7 K. O8 n' A( A
long dengji,s_dengji = 50; //酒精等级. D( n4 a) _ P
6 M, G- f% W2 ~$ d1 @! ebit flag_300ms = 1;
' O; C/ n1 l; Y- x4 u& c5 s9 W; vuchar menu_1; //菜单设计的变量
% W! @) S/ ^) j3 q' e: v) A9 b% Z; {8 G
#define RdCommand 0x01 //定义ISP的操作命令9 N2 y0 Z3 O2 P1 `7 v" |
#define PrgCommand 0x02' k' \' _' T# c. A
#define EraseCommand 0x03 ; o, j9 m6 ?, f3 `6 V
#define Error 1
3 v8 E4 B$ {9 O7 g% J$ C( V#define Ok 0
I- w+ p8 z& b& h3 f D#define WaitTime 0x01 //定义CPU的等待时间
# |/ H) t4 p; psfr ISP_DATA=0xe2; //寄存器申明
( I$ q. d2 x3 }1 r: Qsfr ISP_ADDRH=0xe3; R( `3 B7 d8 r$ P
sfr ISP_ADDRL=0xe4;
5 d/ |& i/ V9 G- jsfr ISP_CMD=0xe7;
( D. ?, G: V/ U" W# A2 L% g4 | vsfr ISP_TRIG=0xe6;
: H+ O- f2 u# U* |) Vsfr ISP_CONTR=0xe5;
1 ]* A2 l: C) _+ W. M. a7 j; g, K: M- `$ T+ l$ d
/* ================ 打开 ISP,IAP 功能 ================= */
1 w" p! M1 a$ g; r2 z1 p. Cvoid ISP_IAP_enable(void): ^, c9 k$ B. A+ z. C" ?2 }
{
& ~4 u6 C9 l: }- F; Q EA = 0; /* 关中断 */
+ s, J7 ?5 l4 u1 d8 L1 V( W; k Z ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */* [0 C' q' t# Z; V
ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */
- C+ z3 `1 K3 I# i. \- N5 Q ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */' ?8 P6 ?6 F' q
}
. _# X x$ h! {$ @2 ] {/* =============== 关闭 ISP,IAP 功能 ================== */
3 _1 y7 |9 r2 R3 O, Nvoid ISP_IAP_disable(void)3 Z9 L6 \ d4 {. W d+ F
{" }( i. D8 b b+ M+ A5 \# u
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */1 N; s4 `. p7 ?8 }
ISP_TRIG = 0x00;
2 x+ S3 g; K h* m/ }3 c EA = 1; /* 开中断 */
, l" ~" U( _1 V$ i6 Q9 S1 h) j7 o}
6 n) P; X+ g# H; |% R/* ================ 公用的触发代码 ==================== */
+ k6 f Y6 W3 N/ P! d. Hvoid ISPgoon(void)0 X( ?1 o$ P ~. G) G
{7 f% T+ U. f4 @: }) Y: r; |4 J! P4 m
ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */
2 O5 g2 X) d6 L2 G2 T' {' ~ ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */
! d' h8 y7 X+ g" M$ G; r ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */
( D3 h8 o; D/ {3 i7 m | _nop_();5 m6 a( f* C+ a( {2 K( k2 G% |
}+ h1 j, Z$ L* S0 _7 C( B% S
/* ==================== 字节读 ======================== */7 X# N2 C$ b" M' e3 N6 {% ~0 r
unsigned char byte_read(unsigned int byte_addr)% a7 G3 C$ t7 I) d5 ^( N, s5 @
{1 U0 z! v( l. ]8 U$ `, X- D
EA = 0;
- T/ y* A, e6 c ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */
% I( c6 M. c) C: j f ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
3 _. g% X& n- X, v9 u ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */) ? X- d6 r9 e9 S- K
ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */: _6 a1 J) Y' W( c1 B
ISPgoon(); /* 触发执行 */2 f& z' h" g8 [ X/ M
ISP_IAP_disable(); /* 关闭ISP,IAP功能 */
. {2 g' s/ T. b, l EA = 1;
- D& i* Q8 i! ]5 E3 y return (ISP_DATA); /* 返回读到的数据 */- j y* H$ D3 B! f+ ^' v7 J
}% S2 X# B" e" ]% u
/* ================== 扇区擦除 ======================== *// h$ L8 d* U1 w; k: J. b
void SectorErase(unsigned int sector_addr)- Y& Z& d5 r+ m5 k
{
: y. L: ^/ N) E; W: R unsigned int iSectorAddr;* x* Q& ~% K8 c% N1 W! J b
iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
! n" r6 d* {0 b0 D, o8 y ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
$ D J+ _$ a, }; Z* W ISP_ADDRL = 0x00;
& n5 j2 J: a7 M8 F ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */8 j" F( } U% E/ S! y4 ]
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */! \# ^% `: Y: r; B
ISPgoon(); /* 触发执行 */
4 S) X# h; u. A7 K) Y' b0 D ISP_IAP_disable(); /* 关闭ISP,IAP功能 */9 E( P- {6 O% g: j2 S9 b3 Z
}4 o f; T0 z+ i6 K* Y4 Y
/* ==================== 字节写 ======================== */
' _" a( S% L) a% u1 h0 l, Ivoid byte_write(unsigned int byte_addr, unsigned char original_data)( T4 V" {" z& d+ H
{
R1 b$ B3 N: U- C EA = 0;
) r& V7 w. K3 f/ Q( @/ l SectorErase(byte_addr);
# H C, q* ^6 ^9 I- l3 `! k8 { ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */: v& ~: ]' j) y& Z( h8 o
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
6 e/ {6 `7 T. e2 l. c, y ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */
9 y5 Z; X/ k( k2 J9 x0 N ISP_DATA = original_data; /* 写入数据准备 */
' E) N, a1 c3 o2 [( g+ V8 k ISPgoon(); /* 触发执行 */
- x& \6 W- }5 E9 \3 |5 y6 I# b0 k' ^ ISP_IAP_disable(); /* 关闭IAP功能 */8 l0 e: f) v- g0 R. ]0 O
EA =1;
1 b0 e5 e0 E2 T, |( ?}
3 Q9 w" B! y5 z( v$ |9 ?9 V
! h) l# M0 h: l8 o9 v
+ R- a% R! i* `/***********************1ms延时函数*****************************/
+ u4 o% c0 Z5 ~9 jvoid delay_1ms(uint q)
. g6 k- Y6 i- B6 I. M. `2 N. ^{
2 w# \( V: Z# G3 I uint i,j;
! K7 m: f2 I' W5 q6 S/ r for(i=0;i<q;i++)
# C0 s b# f/ g8 w( g3 u6 F for(j=0;j<120;j++);
/ D4 [. j; E" Y; N2 |, Q}' N' D/ A4 J( y) q$ b
. e5 ?3 f# q8 ^* G4 W9 l
/******************把数据从单片机内部eeprom中读出来*****************/1 W8 L \% `6 ]; C# k+ u6 H% r
void read_eeprom() //读出保存数据
' j9 G- P+ J" w{
9 F! G5 p& l B3 W* u' i! }- j s_dengji = byte_read(0x2001);1 {! {& d" z U' d
s_dengji <<= 8;
4 K$ r' G4 ~) W. t! x6 r! G! z s_dengji |= byte_read(0x2000);% o, z9 }/ a( [- A* J5 b0 U4 ~
a_a = byte_read(0x2058);
+ K3 h; W5 t+ I* b3 k; T}
- ?: a4 x4 S* t7 J7 g
& l2 @# V$ z3 K7 A$ J/******************把数据保存到单片机内部eeprom中******************/
8 [- _3 O6 e' d; I/ ~void write_eeprom() //保存数据; b% n. d- x# d0 _' g
{
8 `* I9 S; R) B } SectorErase(0x2000);3 e! d9 s& `6 w" ?! z1 V; s. x
byte_write(0x2000, s_dengji % 256);
5 n& U7 u9 H2 X3 h; o/ g byte_write(0x2001, s_dengji / 256);# V6 P' y: n8 {
byte_write(0x2058,a_a); 9 ^8 H+ t' U$ h/ [% |1 X" r# j, n
}
: ]0 n/ r0 v/ X
5 H' S* v6 _: F! S M) E& r2 C/**************开机自检eeprom初始化*****************/6 ]( o; E- U5 j; l9 d8 d" m1 B
void init_eeprom() ////开始初始化保存的数据
: S( j r3 _5 @; x0 S{$ V6 Q* [/ P" C2 w- r7 x
read_eeprom(); //读出保存数据 |2 q. Q3 c# x' W0 ]. W1 U
if(a_a != 33): \+ H" K, v- q1 P, v0 ^0 I
{0 C* ^# _1 m' b
a_a = 33;
( c: {3 M$ I& d3 v s_dengji = 80;! w/ Y2 Y0 C' O( \9 p H8 l
write_eeprom(); //保存数据$ z) s8 O2 S1 F; o/ i6 \$ F
}
$ Q; R9 e' W: j' u}
2 Z1 Z: h& {. W. ^% \( |, t- n. K: `# ?. _+ L
/***********读数模转换数据********************************************************/
6 {0 v! N4 A; B//请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的+ M3 ]9 u, P5 _# T' O9 T
// 1 0 0 通道
0 S! D, X2 Z7 A1 S# D6 ? // 1 1 1 通道
5 w" D3 a5 y" E( Y7 K; xunsigned char ad0832read(bit SGL,bit ODD)
- e* r+ q0 [$ O{9 {0 Q1 w" l" b% ]! w; [
unsigned char i=0,value=0,value1=0; - L) A6 F0 S p8 L2 g0 e% }4 l
SCL=0;* V8 L) q, o9 B9 D
DO=1;) L- H" I1 x* U
CS=0; //开始
$ ~, H- @; `5 k$ m5 `7 z+ G5 t SCL=0; //第一个上升沿 * W7 C' k4 b$ e# N A1 K' }. Y
SCL=1;* n( x, D3 p8 k) u1 F7 J# X
DO=SGL;
2 X/ z9 H1 n. a4 |: Z5 z1 H$ X SCL=1; //第二个上升沿 [8 Z d; F/ a2 f0 ?
SCL=0;
7 n, E( ]8 y6 m& U( S. v DO=ODD;
7 A |* M* l* ?# v* l SCL=1; //第三个上升沿
! x7 ?+ \7 `9 s4 d; R! w, x SCL=0; //第三个下降沿
/ Q; D; g V5 O! l DO=1;
( o2 W, z1 U: `3 `& |) a' u for(i=0;i<8;i++)
5 B3 ^9 T3 E* H$ G" h {
! {0 E3 d5 m- H+ M; f2 P SCL=0;: ^$ A9 a" b1 l) e" R% z
SCL=1; //开始从第四个下降沿接收数据0 v `( ?+ `9 r1 }
value<<=1;
* J" ~3 e" _' T+ q6 o1 Q- U if(DO)% G* v5 E; \$ a8 I, ]- I
value++;
* A: R b. ]) l. f. E* \ }
; g1 f; @( W1 r' E for(i=0;i<8;i++)
) [2 b- J" W# ~' _, Y1 p: i% F { //接收校验数据" V; i" P4 z3 B( {2 s& k
value1>>=1;
8 }1 T' N4 W4 u) n if(DO)
8 ]" S* I1 n) g7 A, I value1+=0x80;
+ X1 [8 z; u8 [# D9 n) {9 d SCL=0;
" p7 c: R% P9 @9 J5 _ SCL=1;
" G& C0 N9 }- b- i" Q' _ }: ^1 F- R' r) A6 [$ l( s* Z0 e
CS=1;9 t! t, G+ K$ u R: z
SCL=1; 8 d8 _) F5 r2 D; E$ ^& ?
if(value==value1) //与校验数据比较,正确就返回数据,否则返回0
' s6 x! ]. c2 Z& e5 h- P return value;
& x2 G8 W G# N) ^1 c* R return 0;2 {: O' V! P* V. o; R8 K u9 _
}3 o/ V8 d4 k' D* V3 w0 r/ B8 m
1 q, v# z3 k2 y* }/********************独立按键程序*****************/
F: ~; D+ r& E1 Yuchar key_can; //按键值, W* c2 t" B# D I, p/ @
' f, n+ }6 }; N- C# H1 Q
void key() //独立按键程序; A- j' ?% ^8 \! @9 R5 e
{
/ ^. V+ R, B8 a: j0 g1 X5 v static uchar key_new;3 h* N) P& m1 m$ X7 \* `+ e# m
key_can = 20; //按键值还原
, {' |4 s+ C3 A; d P2 |= 0x0f; //把按键的IO口输出为高电平# v$ z* V3 s. x0 q
if((P2 & 0x0f) != 0x0f) //按键按下: G! w& x5 F2 o2 V; p
{
O$ I' k' c$ W9 e delay_1ms(1); //按键消抖动, z; _! W/ n" [5 p( Q4 U
if(((P2 & 0x0f) != 0x0f) && (key_new == 1))
( d3 n7 X* L7 e) C9 W- f { //确认是按键按下
4 c7 ~$ f @% ` key_new = 0;/ L2 m: Q0 y- Z$ T
switch(P2 & 0x0f)7 G; ~. }& T# F2 u
{
& O: r" S7 _+ A8 T3 x/ `8 ` case 0x0e: key_can = 3; break; //得到k1键值
- b. q! X" u. A1 L/ L. n" y case 0x0d: key_can = 2; break; //得到k2键值
! X/ T7 E$ i* P7 M# b& N case 0x0b: key_can = 1; break; //得到k3键值
* l. \: d# q3 w" W/ t+ R( B// case 0x07: key_can = 1; break; //得到k4键值
& b/ f, r* G* ^* g, L! Y }
6 v2 Q$ K9 H- q! e; x }
* S8 r; Y$ M" c }
8 d# k& X2 P7 Y else 3 o! o0 s, M3 W& m/ f& I" }& ^) q
key_new = 1;
! Q, M$ l# X% w! M2 ]}# c( Y0 x& D& n) d% a! ~
* p; A$ w% \& b4 D) k+ d( O. N) V5 Z4 P- i: L5 W* y
# T4 [3 Z2 x1 t! s7 c
/****************按键处理数码管显示函数***************/" B8 r* H. l- }
void key_with()
% P! g( s" i# e0 l9 s& r{& t# c% O3 f$ A" ~( O
if(key_can == 1) //设置键
5 m v3 X6 M( R0 z: i3 } {7 i8 j- b1 _# ], u, }3 X
menu_1 ++;5 y5 r' n: ?: h% G( v2 v9 j
if(menu_1 >= 2)5 a9 ~5 i* f5 u+ Y. e
{( T$ F% v4 n& J+ H
menu_1 = 0;; P N6 c; q! Z" F. i6 {
}
$ e) I: q* w6 b* L4 G }
; c( I' E1 m" f# L if(menu_1 == 1) //设置酒精报警值! @5 C$ }& C* N. j+ p3 n
{
1 a& W6 {$ H3 o7 M* ` smg_i = 4; //显示4位数码管" z) `1 L3 @0 p- Z L
if(key_can == 2)
( T7 W- q1 Q) \3 E% @6 \* ? {
( O2 L& G: d; P# A2 X3 V- V ] s_dengji ++ ; //加1 * w0 C: r( J- K9 |' j5 E5 i
if(s_dengji > 500)
{" s, T; |! j s_dengji = 500;9 o2 I# M- c7 V9 h5 H! l% K* u
}0 ^; \6 F L, j* b* q: b
if(key_can == 3)( H: P- l6 Y+ L1 j3 w% Y
{
# U( ?( i$ d5 P# q- t. m$ U- r s_dengji -- ; //减1 . N0 ^% ^* x" i! W- d
if(s_dengji <= 1)! d. J0 t) P* ~5 ^3 `& U7 j& ?
s_dengji = 1;! `; O* {2 A' l; d
}) ?3 y" ]$ p0 i$ B, y; [( v
dis_smg[0] = smg_du[s_dengji % 10]; //取个位显示
0 O" E0 S/ L F dis_smg[1] = smg_du[s_dengji / 10 % 10] ; //取十位显示 S: S L+ J9 [; _& L" @
dis_smg[2] = smg_du[s_dengji / 100 % 10] ; //
9 j9 Q/ p4 x" Y dis_smg[3] = 0x0c; //a5 g4 e. ^! k* }! x5 ^. u& K$ u1 K
write_eeprom(); //保存数据$ S" R4 S% L1 Z6 V
}
' O! j1 g/ s- D+ \: q}
4 N4 |; q0 h3 M, J: ?4 u$ I# F: P: `3 b6 d& k& h5 g
' d9 B- P7 \% _/***********************数码显示函数*****************************/
7 F9 p' ~) e! z" V: Pvoid display()6 I: ~# w# B( L5 [/ U
{$ _; h/ n9 A' `& t( x
static uchar i;
$ R6 b& L, h+ v' `3 U. ^8 g P1 = 0xff; //消隐
! j! F+ e8 Z, V* ^ P2 = smg_we; //位选$ L: A' R e$ D: B2 _
P1 = dis_smg; //段选 # Y1 I% o' J# T/ N/ r4 |
i ++;
. T1 K) f9 S3 n0 R if(i >= smg_i)( ~& u& H* u, `; A O0 }! i' v
i = 0; ' [: z9 J* ?# o B9 d2 C( W Z9 w3 q
}, O% R8 A6 }- H. h. W4 L( G {
1 S( ^# E" g: R" C2 [) o" D% G1 f7 q7 H& [5 ?- _: @0 E& N
/*************定时器0初始化程序***************/
. g6 n7 B2 `" Ivoid time_init() 4 F/ s) Q; W& a) m/ ~) M7 X, I
{1 h! V" w/ ^" L! K$ i
EA = 1; //开总中断
4 S# g0 \6 x" o7 x( O TMOD = 0X01; //定时器0、定时器1工作方式12 c5 E. Q6 L+ i. Y9 u% Z& }5 T
ET0 = 1; //开定时器0中断 % z2 ~( T2 t6 I* r% ^
TR0 = 1; //允许定时器0定时
$ b& Q/ A4 W2 }' K1 p) m# k; J}
" ]+ e7 u$ M0 X* ^* B+ b& e! m- k& A& @# I7 z: S7 [) ]' E
& T" }7 y$ Y- T" F
3 M6 g* j* J7 z2 ? _5 r' a' e
/****************报警函数***************/
3 X7 W" ^4 Q- u3 k) ~void clock_h_l()6 G0 @& P7 r) X' L" c
{) T8 f5 p& ]3 Z+ ]. @9 V
static uchar value;2 }" \; S" J$ @$ F3 X
if((dengji >= s_dengji)) //报警0 c2 K X' i7 P# A6 N% j/ ^! c4 e
{$ j! S6 O- C7 D- } b
value ++;
- D* K7 Z' p7 s- H! J# t2 e& f1 f if(value >= 2)
5 }) |7 h0 U2 @) U4 G% O {% O# e$ n- M+ z; {% O6 H1 b c1 J
value = 10;
) f+ x- [# }# p& _2 b x* M beep = ~beep; //蜂鸣器报警* w" d' O9 O: U& ?% E6 ^1 w
} V2 V( A# W8 l: L9 T3 e
}else
( T$ J* s% P5 f& ?8 s2 [' l& Q {& }" q2 u5 [+ L% F. B: ~
if((dengji < s_dengji)) //取消报警% @. h; q' o' g# }
{% k, q$ Z6 V- B2 q8 F& N
value = 0;0 [6 G8 {# A( ]7 J) e
beep = 1;; s u" P9 [" r# Y9 v1 l; f$ ~ t
}
) w7 ^: |5 G8 h2 e {; l }' {4 u0 `1 n' n% m, ^, I l4 l: Z$ u
( v6 @. _. I, ^$ _* ~* x- h' o}% x; w4 H$ p* D4 C
* ~0 J% j, M D8 S
/****************主函数***************/
" ~7 x! j$ Y/ i3 ]; svoid main()
R9 b+ ^# | Z& w% A{
/ ?7 y3 Z( [' X5 @* c7 @. e9 T beep = 0; //开机叫一声 * W' ]0 Q! e" e3 e3 I2 p x
delay_1ms(150);
) x) M. J: a [% ~ P0 = P1 = P2 = P3 = 0xff; //单片机IO口初始化为1
9 a0 _8 W# P3 |% R) V! A: X) U1 x time_init(); //初始化定时器 1 f7 D* E" Q1 b6 K2 C
init_eeprom(); //开始初始化保存的数据8 p- Z- q" X, R# _/ }
while(1)
: ^% E/ S* `$ v; V4 d {
, M: ]- L( X) p. S key(); //独立按键程序
2 b1 q# G( [, u! T9 A0 a: B0 e if(key_can < 10)
# ^" a/ ?0 h* X* J( c% Q) Z {( q" u: W$ L1 l& D, C
key_with(); //按键按下要执行的程序
i" t$ R0 L6 K# C8 U5 ~ }
2 ?, L9 _2 g* \% L9 {: t; Z if(flag_300ms == 1)6 P& u# T, n4 j0 T9 _, `
{
1 u- W. a& _& Y( J- I flag_300ms = 0;) G3 Z$ G/ q8 F- p) J# Y8 Z
clock_h_l();
) l" ]) H7 f' t6 b0 B8 o dengji = ad0832read(1,0); # J) V" t; ~+ k* c3 _$ C$ G4 ]( [
dengji = dengji * 450 / 255.0;
4 |4 S: c% Q: b1 u dengji = dengji - 100; //首先减去零点漂移,一般是100mV8 D w% O8 q2 i( i$ p
if(dengji < 0) * D, ~7 I6 W2 T
dengji = 0; ( M- f' D4 \3 y. b3 V; E
dengji = dengji * 2; //将mV转变成mg/L,系数需要校准
t/ y, n, m7 W) E0 Q- ]) ? //电压每升高0.1V,实际被测气体的浓度增加20ppm
$ N; Q" Q( P! S8 G6 D //1ppm=1mg/kg=1mg/L=1×10-6 常用来表示气体浓度,或者溶液浓度。
" H" M# k. W+ q6 q if(menu_1 == 0)
1 N! c, m2 x1 L {
% ~' G {1 |7 W+ x if(dengji >= 1000)
& m. f1 {# o2 M/ e' ~ smg_i = 4;5 e) `# q" }' r7 L
else
) Z1 P9 y! I$ o- }9 v smg_i = 3;9 [! P) J: {1 N, j
dis_smg[3]=smg_du[dengji/1000%10]; //千位
1 z( b( g. c. l& e5 ~( R4 j dis_smg[2]=smg_du[dengji/100%10]; //百位
6 _7 n- a2 O: f u; J& y; r dis_smg[1]=smg_du[dengji/10%10]; //十位 O: w; S2 Y, K- c) {/ p
dis_smg[0]=smg_du[dengji%10]; //个位 ADC0832为8位ADC,数值为0~255,我们将其分开放入l_tmpdate数组中显示7 P, B+ b. L* X7 R( S) M. E
}
" e8 S% P3 s' S. I' {7 |7 @ }
3 z+ E7 r3 I# s6 J }
# m( p- w6 v8 ?/ _9 p- I% O9 X- z* P}
% t, \# s2 r6 C, k# n+ M, J* g! [, p
! G5 m: M# m" ^( V/*************定时器0中断服务程序***************/
; d+ |1 I. w E+ O. b, C+ k- pvoid time0_int() interrupt 1
1 v# T8 r9 }- Y1 y# Z/ S6 A/ u{ + ^$ q, x. K' X7 A6 x5 _
static uchar value;
& g8 F7 { k/ C" g: W" D% }5 m0 C1 j+ d* H
1 c# |& X( K& P/ g
…………限于本文篇幅 余下代码请从论坛下载附件…………
8 T1 D/ I: i+ L2 y; h- m9 j/ Q4 v: L( y' V5 V) y
1 \0 z: ?1 q* {3 t+ C
5 b" ]5 j9 q% I- q# A; a
0 D5 Z4 S/ O. K: S |
|