TA的每日心情 | 开心 2019-11-20 15:00 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机酒精检测仪源程序+仿真 DXP格式用 altium designer Summer 软件打开
2 B& R) ^4 P7 m6 U9 m2 jprotel99格式用 protel99SE 软件打开 $ ~2 W. I" U! S1 B% B; G: N( g1 x
PDF格式用 PDF 软件打开 : M. @9 e0 D/ ~" _2 d/ T0 \: X
Word格式用 Word 或用WPS 软件打开
8 g; y" r M: m. L+ w
; j4 _1 ], Q' c+ J; S) f7 {1 N4种格式的原理图都内容是一样的 只是打开方式不同
# P& V3 R7 Q: ]$ U
: P6 i; V& ?' v- G请看原理图焊接,不要看仿真图焊接。
' s/ R0 ^% j U
) y F# U+ P$ hwrod格式里面的原理图是复制出来的,有一点点变行变形,麻烦大家注意一下,尽量看其他三种格式的图焊接,7 C8 I. H, y% P# g# i) _$ P
% T! P( [3 Y! Y, l如果论文里面的原理图和原理图文件夹内的图不一样的话,请大家以原理图文件夹内的为准,原理图文件夹的图是和实物配套的,可以自己截图或复制,然后粘贴到论文里面去。# l* q9 Y/ L# N. h3 r& d1 i; V
, P: n6 P" F) V P: v& |- L h
单片机源程序:
: b- A% T q4 _- @% h8 P. e7 s; z+ S3 Q3 E9 b0 o1 C! ^, ]
#include <reg52.h> //调用单片机头文件
0 e9 L. w' t7 W' X z#define uchar unsigned char //无符号字符型 宏定义 变量范围0~2559 Y! b0 k: H; u5 ]0 I- [& U
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535" g4 Z2 ` B" c. p6 F `1 Y8 M
uchar a_a;
4 h6 ~1 \1 `7 z#include <intrins.h># G5 }5 N% ]" `7 Z
! M' W4 V( n/ W( }
7 v9 A$ j l6 X. J//数码管段选定义 0 1 2 3 4 5 6 7 8 9 + S6 c+ Z1 L( g" Y/ L2 {
uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x04,0x14,( W5 `" X" q+ ^& p1 Q7 x
0x0c,0xa4,0x27,0xc4,0x26,0x2e,0xff}; //断码) E2 Y! H6 n# k; j0 o! Q
7 A' p6 O" C# g//数码管位选定义: n2 ^+ W- T) o- r+ |1 p: `. {! v: |
uchar code smg_we[]={0x7f,0xbf,0xdf,0xef};
/ ?" F( H6 u2 L/ k7 kuchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
7 a9 \% L e0 ~5 O8 L- Fuchar smg_i = 4; //显示数码管的个位数
. p3 H* Q/ ?2 @2 l9 v h4 V+ ~0 c$ i) ]3 ^& @8 x3 x: H
sbit CS=P3^2; //CS定义为P1口的第4位脚,连接ADC0832CS脚
. n" b2 L, }5 Q' S% y5 X- P" C# Lsbit SCL=P3^3; //SCL定义为P1口的第3位脚,连接ADC0832SCL脚2 m- s! e3 H8 b
sbit DO=P3^4; //DO定义为P1口的第4位脚,连接ADC0832DO脚
. |( e' T- E6 a2 e6 R$ c" Q/ P% l4 V* b9 U( d
sbit beep = P3^6; //蜂鸣器IO口定义0 d8 U w- F+ `
long dengji,s_dengji = 50; //酒精等级
4 d* Y1 e8 g# P, x; l, H
4 H" U8 u( S. t tbit flag_300ms = 1;
2 D: P- [8 S5 P$ U8 ?, Huchar menu_1; //菜单设计的变量4 ]3 `5 A* ]4 {6 u3 Q2 X
6 d& D9 P) B V
#define RdCommand 0x01 //定义ISP的操作命令0 j3 o- b2 B# w G# D% T$ Z
#define PrgCommand 0x02
, q3 y) N& v& n' T#define EraseCommand 0x03
" |! E- \; x3 L/ V4 Z, z: E% B#define Error 1
! a, G& L$ u) b: r#define Ok 0
2 z0 {3 l; v; e. \" r1 @#define WaitTime 0x01 //定义CPU的等待时间
1 P9 r, A3 |" [. T' A! o4 ssfr ISP_DATA=0xe2; //寄存器申明
0 a. x" ^& I" _6 ysfr ISP_ADDRH=0xe3;3 T8 X% u+ R( r6 p8 o d3 r2 Q
sfr ISP_ADDRL=0xe4;
) {: S: A: }2 o" @' B( Hsfr ISP_CMD=0xe7;
& @9 E2 N, ?8 G6 D) H- @6 W# }# F# wsfr ISP_TRIG=0xe6;
$ h' H, U2 p$ |0 p8 rsfr ISP_CONTR=0xe5;: [' e/ J: M( v' o" O+ P
: t) n9 f7 n: c+ @- `& z8 d! Z/* ================ 打开 ISP,IAP 功能 ================= */! R$ e- L- F4 o7 X0 {
void ISP_IAP_enable(void)
, A T0 Y7 |7 I* Y5 P# V{
0 O0 f* `. w! D3 d) D EA = 0; /* 关中断 */
- J; i2 q4 X: N ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
0 g K. K1 B; J# a5 a ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */
, ~7 p5 A# M$ s ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */- z6 v5 T( C! a2 a# D3 b' D" K
}' Q: r" y. g0 Q, E6 F: P! }
/* =============== 关闭 ISP,IAP 功能 ================== */1 `' n% C: N" d7 q
void ISP_IAP_disable(void); _4 F5 F+ {9 v
{
) h7 y% c3 ~ E/ S' ? ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */1 e5 i ?0 B6 ?( A: X
ISP_TRIG = 0x00;
/ m; b- ?7 ]4 }1 Y) |/ I8 } EA = 1; /* 开中断 */# v! J8 f2 S7 d1 t* E
}
# q, g+ m% t' H% F/* ================ 公用的触发代码 ==================== */4 r9 b& j' o" o9 s1 t2 D; z
void ISPgoon(void)
6 e4 u* r: `& @8 o9 [{
" H+ h" N/ n/ S" y6 ?* }/ ~' x ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */
& G% p! h1 w& E: Q3 ^ ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */2 c: A @. ]7 s% o
ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */1 R0 {8 F; \2 c" ~
_nop_();/ f# R+ M# |/ q0 z, h
}
+ A# ^# D* c, ?4 n. o" D5 E! I6 A/* ==================== 字节读 ======================== */
3 [$ v) x4 v) E2 ]unsigned char byte_read(unsigned int byte_addr)
1 L5 y2 i; ^& ~8 N' G& {7 _{
) i, Y/ t' T5 p EA = 0;
5 Q }) ^$ T t9 h, N ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */- g- b6 y2 P' d7 K/ `, ^! G3 }
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);* G+ w2 ?$ ^3 Q4 L
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
7 E- k9 J' q+ n* P% E7 u% ^: |4 K ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */
+ a* h' f) @6 Y5 i ISPgoon(); /* 触发执行 */
% }" l2 ~" K& P0 s7 i! h6 A ISP_IAP_disable(); /* 关闭ISP,IAP功能 */% S" K' ~* w' ~" r* r0 s
EA = 1;
, P. ]" I! T3 s return (ISP_DATA); /* 返回读到的数据 */
9 G, c \% R9 I1 `* T}- Y' N- A5 x; v' ^0 x2 f3 K7 Z' W2 K
/* ================== 扇区擦除 ======================== */ E j* l4 |9 P: E8 ?1 w' y- T+ Q
void SectorErase(unsigned int sector_addr)
2 T# m# p+ E' [9 W# ?{
' j7 i* v% d, N; q/ z* P unsigned int iSectorAddr;" {5 R( K b1 N
iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
8 t( |( ]# B' ~/ d: Q ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);, Z7 Y( Z& g4 g5 f
ISP_ADDRL = 0x00;
- r' g* L& E. Y" y# T$ t ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */% q+ L. r% k9 ^8 {
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
, [$ q: `( p3 U' x) Z# y9 ^6 m: _ ISPgoon(); /* 触发执行 */
( V5 w3 j3 Q1 u7 d" B* ^# w" X8 h3 f ISP_IAP_disable(); /* 关闭ISP,IAP功能 */) f& Z- u3 p. x! p3 ]
}
6 z; X* @: } A1 J7 Q* v! C0 g/* ==================== 字节写 ======================== */$ n7 t) C2 d6 A
void byte_write(unsigned int byte_addr, unsigned char original_data)( |+ S2 N, k* S! v; y4 k! w: A
{) K3 Y& { ~" n# ]8 O
EA = 0;' L$ P! l! R( ^4 ~
SectorErase(byte_addr);
) K/ g7 d3 I4 i/ Q: A. R) [5 U ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
* _7 `) I6 j0 l" r% m ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
+ `1 K( b1 U/ L; e0 a$ F) ^7 X ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */
9 w+ {. H1 [9 C0 H ISP_DATA = original_data; /* 写入数据准备 */+ k: I# L* n9 |3 D# |- i, ~
ISPgoon(); /* 触发执行 */
2 Y8 ~" S' N4 C0 j' S ISP_IAP_disable(); /* 关闭IAP功能 */
6 L$ l$ \% y4 y8 s" q EA =1;
3 R2 a0 k: R g" b( y8 J& W}6 ~8 Q* l4 u5 }+ s& @9 Q
9 ]4 r/ t$ n1 x$ `8 `8 ]! Y
9 A( X. Q* \' d/ q% v5 A
/***********************1ms延时函数*****************************/; B6 ]* J9 T* a/ M4 k0 f" ^
void delay_1ms(uint q)
# \7 b) O w4 ?& q3 j7 N& I{! ^2 A8 P4 S6 k: ~) q; \" A4 t
uint i,j;+ W3 z6 N/ \+ Q# e/ @$ A
for(i=0;i<q;i++): x7 Z$ C( g1 Y- |6 h ~
for(j=0;j<120;j++);5 `0 p* G2 E( j! r7 D6 K# _ X- M; T
}
2 c' o' ?3 n8 Z
! o! `! n3 L+ S. G/******************把数据从单片机内部eeprom中读出来*****************/
) D4 M, v& Q9 q+ |7 {; ?6 Mvoid read_eeprom() //读出保存数据# B6 Q& _- j% E! a0 o
{
4 e3 Q, [$ U8 l% s6 G0 A s_dengji = byte_read(0x2001);- I$ _9 \# _6 d6 N+ E3 v
s_dengji <<= 8; _* n: [0 m1 a4 _$ D% P+ F! P
s_dengji |= byte_read(0x2000);$ F$ b2 d/ X. q, G1 s( j
a_a = byte_read(0x2058);) `, |4 `" W( \6 a. x
}
% v. A8 |: |" @2 [9 A' l k9 t5 c: ^
/******************把数据保存到单片机内部eeprom中******************/
, ^7 ]: L7 v& S0 |- ~" l& _0 zvoid write_eeprom() //保存数据5 m' T. I, c Z
{: P6 m. @& V! v8 I* Q8 c- }! Y! B
SectorErase(0x2000);
% \- B$ C( B. ~) n( c1 j* h byte_write(0x2000, s_dengji % 256);; U* w! W5 S, I9 i+ M% d2 Q4 _
byte_write(0x2001, s_dengji / 256);
* D! k: V, G2 p; U byte_write(0x2058,a_a);
5 T% F- K+ ^/ P( M: m/ m' m}
2 g; f$ W) p6 G: P- d# f! r. S; ~, d, v
/**************开机自检eeprom初始化*****************/% c* e% W$ N( T( H
void init_eeprom() ////开始初始化保存的数据2 H5 a L5 p5 t, F' `7 P/ m9 R
{3 I6 ?9 z. X6 z1 `$ f
read_eeprom(); //读出保存数据3 I0 b+ h2 A3 w
if(a_a != 33)
" U& M8 j* Z$ b* E- e* T# u$ a$ V0 g {' {) L' i. d5 Q: E/ v" j7 S# ?3 o1 |
a_a = 33;
+ Q1 x8 L3 n+ U( H s_dengji = 80;
! C& }3 S& T& O0 S7 D% T. U2 L write_eeprom(); //保存数据
" S+ x% m$ R y. p% Z, [ }0 H) N# P6 A9 s& A' Y
}
; L I( U# z! s& N: p
( ^7 ?1 o' z# ?9 h4 p; [0 @& P/***********读数模转换数据********************************************************/ $ X5 O9 h$ k* E
//请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
5 [& }# v9 `$ W4 F7 i // 1 0 0 通道 p; P" l2 s) }* \% Q; y
// 1 1 1 通道 5 V7 P8 b9 ~1 @1 \
unsigned char ad0832read(bit SGL,bit ODD)
0 L" H9 r* h, o/ V( Z( {* `0 S{
9 [9 O, E X5 Q7 O X* o. V6 v2 g0 W unsigned char i=0,value=0,value1=0; ( E3 C; @ m4 }- O
SCL=0;8 a/ @3 ^6 N8 W9 J1 M
DO=1;
7 _' i6 h B0 v7 z" k- l5 ? CS=0; //开始: U5 o! `: |; t+ g6 J
SCL=0; //第一个上升沿
+ X1 o& o% _/ u8 c, k+ {/ Z SCL=1;9 u3 H" }. h) T
DO=SGL;
4 H5 f) s% J' {* u+ R0 u& O: E SCL=1; //第二个上升沿
( J( K3 m! Q7 q, B/ e% i) B SCL=0;# @; C' ^- O2 K! J. F0 d9 z
DO=ODD;
# [3 u, X6 \8 f$ p @" W0 I- Q SCL=1; //第三个上升沿
: [/ X: [2 y- ]' o+ a3 v6 V SCL=0; //第三个下降沿
3 `- d/ D( ^ i I2 F+ w DO=1;2 d9 i$ L8 @6 i. Y" m$ `0 \# ?, k
for(i=0;i<8;i++)
' m1 c7 Z' v! { {5 k; n. R( L6 k, V
SCL=0;( m# P: A# A( V/ h* G
SCL=1; //开始从第四个下降沿接收数据
! X1 J* ~0 g' |1 m6 Z; r value<<=1;
1 T4 T, ~0 Q4 j& B if(DO)
8 T& M( v4 t+ r value++; ; g7 O4 a, P8 w: x1 s& X( Z% X
}0 F9 }& m7 g( \
for(i=0;i<8;i++)4 E5 p* B9 i I
{ //接收校验数据) t8 ^+ {0 U# n
value1>>=1;8 u! w1 G) P& q0 W/ K+ m2 y
if(DO)
8 ]" [, ~0 I+ U( z5 i) x) @' S value1+=0x80;
$ [, G6 Q: h1 D! { SCL=0;# ~( E5 C4 w" B$ k5 q
SCL=1;
! @1 C" l9 M* ^' N6 u }
0 a! U3 S. L& c% m CS=1;% u% F0 h. `+ [' H5 ?- H% g& v7 L: _+ H8 r
SCL=1;
0 D2 S9 \. |4 w9 w A- q, Q& U if(value==value1) //与校验数据比较,正确就返回数据,否则返回0
5 \ H7 `" q: B8 t3 E. P }5 c) M return value;
3 ~' u2 ^( K6 Z, w$ h return 0;. g4 l# G! Z$ S# d) Z: M
}
4 B6 ?; [" |0 R( m0 X2 u/ ^' z+ @" e- N& B7 y6 C* {0 P) F
/********************独立按键程序*****************/
5 G K" }" U- x0 E. E' \3 m8 auchar key_can; //按键值( K- L6 @4 K: N$ G: S
$ H7 N4 w9 `; B
void key() //独立按键程序; U, `! u2 M+ x( v; j' d3 m# e: i4 R
{( y* I' V! I& ~1 S$ i# Y) E
static uchar key_new;
$ W5 n' K! ~! H: ^/ i key_can = 20; //按键值还原
: `, w* r$ z7 t, B5 X+ v! D6 ~% ] P2 |= 0x0f; //把按键的IO口输出为高电平
: Q" I( k$ ?% l7 w( G. s$ w if((P2 & 0x0f) != 0x0f) //按键按下
, I+ `3 A8 D; x- b9 {4 i' C {" M/ v Z8 z/ Z- ]/ y
delay_1ms(1); //按键消抖动
5 ^( T9 l( K: n5 V3 q' k if(((P2 & 0x0f) != 0x0f) && (key_new == 1))4 D9 _' `0 q1 _8 X* N3 Q
{ //确认是按键按下
7 e4 y6 e2 q9 M key_new = 0;
$ I7 ?0 [, V" Y. @" s4 Q" w5 n switch(P2 & 0x0f)- o, ?2 y% T; K7 s, d# a
{. t0 \5 c4 z. K# [% l2 E
case 0x0e: key_can = 3; break; //得到k1键值: ~4 \* v1 u* B2 I
case 0x0d: key_can = 2; break; //得到k2键值
* g% f, A+ j. G6 S0 E case 0x0b: key_can = 1; break; //得到k3键值# z, R0 D. f3 O% l7 d
// case 0x07: key_can = 1; break; //得到k4键值
/ U$ Z: S: t) N1 h8 n+ T }
2 _1 ]6 z3 `3 p3 i }
) p4 ^$ H3 e# e# T$ i5 a( q } Q, f$ c8 R$ [+ ~- d
else
" o L; t) T* I/ m3 t5 F( l. A key_new = 1;
; v. T2 Z: ^6 j8 ^}
( h4 @, W ^+ b- A
) N! i0 v2 Z0 [0 X# a! n3 i, z
( V: {; `: n8 R# k! o
" F' k% U" G+ W K; c/****************按键处理数码管显示函数***************/2 F4 g" o: x7 H+ O! r0 i6 q$ R
void key_with()
b8 W r$ z/ R; ]{7 u! a# L! J+ U2 A
if(key_can == 1) //设置键
. u5 q% d/ E R& ]/ o/ L {
. K1 E+ l Y) }# i, C menu_1 ++;
- J' E: k Z4 ?& g4 n( c if(menu_1 >= 2). b+ V3 a. b9 I2 S* }0 t
{
1 u& l: v2 s9 }( ~) y# F! `8 z5 H% L2 { menu_1 = 0;- @, V5 v- m" r) ~! M$ _, p
}
" a% w& T+ m$ A7 H2 k9 @ }
( @3 M% U" u o1 [6 ~/ Q if(menu_1 == 1) //设置酒精报警值$ o) z+ R( T8 C) ?* u
{% R: m" Z( t, e, A+ q! i! b
smg_i = 4; //显示4位数码管/ L7 ]8 _* m+ D( O: o6 s$ }
if(key_can == 2)
" d. ?/ [2 i7 J {
3 [) v+ d/ P2 z" k' l0 c s_dengji ++ ; //加1
8 A2 x' Z2 T( u( R8 T if(s_dengji > 500)9 T& s1 o* {% [+ l0 k0 v. t
s_dengji = 500;& |- r" {+ S) V3 i7 f7 u, @
}" B1 Q! A( g+ z% o7 g
if(key_can == 3)- R5 `& J1 T |2 M* e' q: e' ^
{
$ `* f3 j% D/ Y& R0 g' Y* I2 ? s_dengji -- ; //减1 5 y6 w/ U7 N4 @$ W) I' U
if(s_dengji <= 1)0 X0 {8 K( d* K: i
s_dengji = 1;: t1 R7 s) i ]7 q5 k
}
0 N' e9 T8 O5 L/ |, M9 S, p dis_smg[0] = smg_du[s_dengji % 10]; //取个位显示 B8 y! Z: V# ^* J" D! u( F
dis_smg[1] = smg_du[s_dengji / 10 % 10] ; //取十位显示
: i X# M# m% ^5 _ dis_smg[2] = smg_du[s_dengji / 100 % 10] ; //
x0 U$ a" g8 r- L# D% r dis_smg[3] = 0x0c; //a7 ? w6 R- E- x- I
write_eeprom(); //保存数据& n- R5 g" {9 t$ x/ Q9 g1 X: ^1 S
}
6 D9 u: ~( I9 z1 x}
1 r% v+ t) k) d6 G# S8 [& i( m* V# _# q8 p' r* m U
4 i/ L1 H) a- [ |; A/***********************数码显示函数*****************************/
4 b4 m& a& o: q. @" @# B6 Ivoid display()- \$ k ~ B6 r0 c
{& p+ w; U' {3 [7 w
static uchar i; + X5 `. M: e3 j# h' j+ |
P1 = 0xff; //消隐 2 y& i! _( K. Q) x0 A7 i8 l- c. E
P2 = smg_we; //位选
6 Z5 v {* [ Z k9 y! V P1 = dis_smg; //段选
6 U7 b7 X: R/ x( x, P2 ^& q0 ^1 D i ++;3 T" Z- B6 e1 r! k* A8 m
if(i >= smg_i)
0 v) ^3 [6 W+ I% S: @ i = 0;
( v# x6 d- s: s# a2 Z5 f}
8 x7 L" _+ j1 a
. _. | k K8 U v5 ^
( Z* }# }$ E& `/*************定时器0初始化程序***************/
4 P+ s( @" @9 Gvoid time_init() 4 \0 a; L; D1 y" `; h a. k
{! G; q; I" Y$ h# w/ V; h- j
EA = 1; //开总中断
; d/ H9 i% l2 ^# a' r& y V8 k TMOD = 0X01; //定时器0、定时器1工作方式1
) h$ V: D. c D- r' e ET0 = 1; //开定时器0中断
0 Y1 q# P1 I, A3 L; J TR0 = 1; //允许定时器0定时
1 ?( \4 W9 N6 A. A}
) S$ H" r$ z. v8 h: J: ?& R9 N) B0 y
+ `; s/ G, L7 Q7 c1 @7 {" Z- `, M
b$ L; S' o. B# U5 e: q" E# i, ]/****************报警函数***************/
7 W9 U! X T/ l# U1 w7 i) Y( v) ~7 Jvoid clock_h_l()
7 r+ u! K# z$ A( P{* \5 e ~- G* t8 y. d P% p
static uchar value;
6 e" N, X% J" v8 p _ if((dengji >= s_dengji)) //报警
* x7 q \8 S6 F0 c4 ~ E' w {
% j6 T3 U8 Q! M" G7 r value ++;+ P J# a' I$ ^* Z& V5 U- m9 N0 X
if(value >= 2)
O* `7 K& Q" V7 ^ {5 u- t& q7 W, f% U! L
value = 10;
7 S( {/ a2 @: z. O4 z1 i. n beep = ~beep; //蜂鸣器报警
6 {4 W3 @) z' m0 c" c/ o* \ }8 M4 T* M! `* u& U1 r1 }
}else . _4 x* q4 Y4 ]# n# ?
{
: U- {$ _* o; S& T1 [) D1 n if((dengji < s_dengji)) //取消报警
& l2 Z, C4 \, R {
5 X. R3 m! ]- U& P value = 0;
8 j' A. X; L- \( _, k beep = 1;
! W( P4 i* C; x, X9 ~/ [ }
8 q0 t' O) w4 ?! Y }+ O M$ s! C2 ^6 t# l! }4 l
+ v" l) ~) B' U3 F
}
, d$ I8 r# H: j8 X) ?; L
+ x+ F/ d, W$ W9 h/****************主函数***************/
$ q" d& Z- ]( ?# D" o7 ^5 K8 ovoid main()
\1 ~: b8 a3 d" } C5 h{; }, j9 [9 b& R9 D
beep = 0; //开机叫一声
! O N% i) a& y; R) K) h$ _ delay_1ms(150);
8 Q' i( o! G3 l0 t: s+ P% z P0 = P1 = P2 = P3 = 0xff; //单片机IO口初始化为1
, z; \8 w4 m0 e% u* J) H2 Q time_init(); //初始化定时器
* D. _3 U, r8 {+ R/ a( M' d init_eeprom(); //开始初始化保存的数据
+ {0 K! T! Q2 s7 w% { while(1)
- N' P0 p- Q; z {
4 u" K) F# ?- U key(); //独立按键程序
- \' n4 U6 x- |1 r; ?$ d if(key_can < 10)
6 \ E: b. I% X3 x( Z& b {* y) t1 {% \7 [5 V q
key_with(); //按键按下要执行的程序8 I( H/ @9 C+ O; ?& ]" ^
}
* H% Z5 l( J9 x5 j: r6 N if(flag_300ms == 1)
4 ^: b+ ]5 I/ B$ Y% v# g. G- b { , u: V9 k7 Z0 @# S& v
flag_300ms = 0;% w( a& u! Y) U( E, g& ?
clock_h_l();
$ k' N/ g) v! ~( e dengji = ad0832read(1,0); - n! O4 c9 ?3 Q2 Z5 a/ k$ T
dengji = dengji * 450 / 255.0;% _0 _0 H. W; m3 F( k2 P: U0 ~
dengji = dengji - 100; //首先减去零点漂移,一般是100mV' ~' J8 Z) I( M' @) C
if(dengji < 0) * T* D( q% f- \/ j, ?/ t% M
dengji = 0;
8 k; P# ]0 v2 Q dengji = dengji * 2; //将mV转变成mg/L,系数需要校准 1 Z# U& ~- n% Q; p
//电压每升高0.1V,实际被测气体的浓度增加20ppm 6 C0 Q4 B* J. t! Y) S' K
//1ppm=1mg/kg=1mg/L=1×10-6 常用来表示气体浓度,或者溶液浓度。 6 I: b9 J/ z \ M' e8 B' w. r
if(menu_1 == 0)
3 Y" D) W+ m: J- w" E8 x {+ c1 w1 {( A z6 E6 \5 z
if(dengji >= 1000): C4 H! K4 W6 j* D
smg_i = 4;
1 C5 L8 ]2 x6 L' R4 U else
* J) F9 Q6 {; Q! d1 a' G9 d$ G smg_i = 3;
0 \- |$ ~8 ]3 c4 i& A dis_smg[3]=smg_du[dengji/1000%10]; //千位1 L$ A' o. ~: l; b
dis_smg[2]=smg_du[dengji/100%10]; //百位& u* J/ A, |; i7 E$ Q
dis_smg[1]=smg_du[dengji/10%10]; //十位
7 P: V0 e4 M: @4 ?, t8 Q dis_smg[0]=smg_du[dengji%10]; //个位 ADC0832为8位ADC,数值为0~255,我们将其分开放入l_tmpdate数组中显示" r2 o, v2 h/ L; H* ~& o8 K- k5 b
}5 ?- o# V/ b7 D
} 6 O' I8 X I- Q. b
}
6 Y# g+ _. U E6 q2 I- y}2 a" T! h4 }: j
4 _3 @4 D' t9 L( D" M5 p/*************定时器0中断服务程序***************/) n$ R* f9 ~. e: M' l1 W
void time0_int() interrupt 1
1 V- k. N7 E5 b! z2 r# ?{ " t3 P2 Z& z% B5 u; u( b0 I8 k8 u
static uchar value;& s: c( F0 f7 L. o8 M( t
2 J, E! }1 V8 D2 z8 v4 U
, e! V. W8 P8 B7 ^( g: y- i" G
…………限于本文篇幅 余下代码请从论坛下载附件…………% S0 T2 w h" I6 H$ Z9 |6 O( I
) t6 x4 r0 D0 U( M9 p. F2 j f/ H/ e5 s- g6 E
5 z0 l7 f" g7 J' _2 K% y0 M
7 B& J1 u7 @: z8 G! t |
|