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