找回密码
 注册
关于网站域名变更的通知
查看: 719|回复: 2
打印 上一主题 下一主题

单片机酒精检测仪源程序+仿真 

[复制链接]
  • TA的每日心情
    开心
    2019-11-20 15:00
  • 签到天数: 2 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2018-11-19 09:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    单片机酒精检测仪源程序+仿真 DXP格式用            altium designer Summer 软件打开
    ! w/ {% G( P: _) s5 sprotel99格式用       protel99SE 软件打开
    0 r* G5 `: X, h# dPDF格式用            PDF 软件打开 . S  j3 X( ^6 J% G$ I& T% J
    Word格式用           Word 或用WPS 软件打开 % Z4 g! s' e- j% s! ~
    2 C. e2 H  J- Y1 M
    4种格式的原理图都内容是一样的  只是打开方式不同
    5 s2 Z1 @9 u6 O9 f  W# w$ M- ?; J" O- M1 a6 c" T
    请看原理图焊接,不要看仿真图焊接。( Y1 ~4 J. C: u6 G
    . U) z9 Y$ z1 J1 T7 ^
    wrod格式里面的原理图是复制出来的,有一点点变行变形,麻烦大家注意一下,尽量看其他三种格式的图焊接,6 Y9 R0 o0 L6 M6 S( J

    ! P, P& y# }- o( g& B  Z如果论文里面的原理图和原理图文件夹内的图不一样的话,请大家以原理图文件夹内的为准,原理图文件夹的图是和实物配套的,可以自己截图或复制,然后粘贴到论文里面去。
    5 R  a( Q7 Q. E+ ~9 {1 _8 l1 N* X. s, g7 J& }( Z' u
    单片机源程序:$ Z- b7 k1 M( t/ V& L; j; `
    : H$ \8 O' ]8 G4 m/ a
    #include <reg52.h>                 //调用单片机头文件
    4 P6 r7 a5 R, j4 @9 E" x& C#define uchar unsigned char  //无符号字符型 宏定义        变量范围0~2553 V* L' J% y) S
    #define uint  unsigned int         //无符号整型 宏定义        变量范围0~655351 r# U* U: B0 C) c: k, ~: o& b& S
    uchar a_a;
    * ^5 ]* [2 ^7 {  ?+ r" w/ i#include <intrins.h>
    # m- ~. F; {# K: J5 g/ E
    $ T5 o9 v8 j' l. p- w- H) \/ ~, O$ d( n0 {- G* W
    //数码管段选定义      0     1    2    3    4    5         6         7          8           9        & l% b# \" B; U# u# N% J& W! Y
    uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x04,0x14,0 I% H) A  R2 d  Z. \
                                               0x0c,0xa4,0x27,0xc4,0x26,0x2e,0xff};         //断码
    / k" d# `) I  d0 [; \+ e4 k4 m* h2 e0 t* |% ^' A% A2 ]3 J& J
    //数码管位选定义+ _- O  z+ _* j9 ]% g% Q
    uchar code smg_we[]={0x7f,0xbf,0xdf,0xef};" ^; H5 G7 O8 y
    uchar dis_smg[8]  = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};        
    4 y' S  W' K$ H0 wuchar smg_i = 4;    //显示数码管的个位数  J1 M3 r% _3 u7 [- G3 S
    2 p; J- B  d6 Y6 j- E+ [
    sbit CS=P3^2;                //CS定义为P1口的第4位脚,连接ADC0832CS脚
    + H* J5 g/ a' Gsbit SCL=P3^3;                //SCL定义为P1口的第3位脚,连接ADC0832SCL脚
    ! Z' @; g, Q, W4 O/ R3 Jsbit DO=P3^4;                //DO定义为P1口的第4位脚,连接ADC0832DO脚
    8 V; L! G5 ~7 q) g# @- q
    9 t& K! g; Z7 R& \" @4 M+ Rsbit beep = P3^6;   //蜂鸣器IO口定义
    $ C9 y' }3 C! F! glong dengji,s_dengji = 50;     //酒精等级/ c% _+ [; ?" U  V

    7 d: J  _  A/ K& _bit flag_300ms = 1;! `7 F2 e7 f+ a( t& c, Y+ e
    uchar menu_1;        //菜单设计的变量
    0 H/ `9 Y  T% s2 w
    9 [7 O$ ?- ~# n$ G#define RdCommand 0x01 //定义ISP的操作命令
    , A, z# o  f1 @2 [7 s0 ?/ x2 F4 g#define PrgCommand 0x02
    % c+ B+ K9 w- a* q4 b& a+ H  `#define EraseCommand 0x03
    9 G4 h% E1 z( |& S* K" A- y9 N#define Error 1
    ; ^. q$ h- ]3 U& r+ T; k#define Ok 0
    $ m6 h1 y) C& G' m6 j3 \  v- X#define WaitTime 0x01 //定义CPU的等待时间
    + I2 d9 G5 X- o+ [sfr ISP_DATA=0xe2;  //寄存器申明
    2 N+ o; v' V; _$ H) W& P) c/ \sfr ISP_ADDRH=0xe3;
    . T1 |! R9 S: _- C2 E: @sfr ISP_ADDRL=0xe4;0 n8 z  [! U, ?; w5 l+ _
    sfr ISP_CMD=0xe7;/ B; L+ P5 b* z& i+ u$ D- D7 m
    sfr ISP_TRIG=0xe6;
    0 L1 `8 G5 N; M! L( p, rsfr ISP_CONTR=0xe5;% T- M1 ~6 C: A* I+ M+ `, I
    7 t% ^7 f/ w9 S" @
    /* ================ 打开 ISP,IAP 功能 ================= */
    6 Z; ]; Q1 P; zvoid ISP_IAP_enable(void)8 d- }1 R: x/ g+ x
    {
    3 p/ U+ k7 \) x9 ]4 ]. E; V         EA = 0;       /* 关中断   */9 ^5 o7 d/ }1 y2 b" u$ D
             ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */3 i/ q8 `$ A7 j9 h
             ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */+ F8 i+ ~9 d8 G  E8 e7 X  c0 M
             ISP_CONTR = ISP_CONTR | 0x80;       /* ISPEN=1  */
    ) B. |$ C  W% M' _: l8 v! V* g}2 H4 N$ b! l/ {1 w1 _
    /* =============== 关闭 ISP,IAP 功能 ================== */1 {. E0 w5 N$ \% f  y
    void ISP_IAP_disable(void), s! p8 T& J& `, B( \% ~  V/ l
    {
      o( w+ g/ l4 |- z" G         ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
    9 k1 a4 k: X' Y         ISP_TRIG = 0x00;
    1 W& n" ]  b; a' V1 M, n3 i2 i         EA   =   1;   /* 开中断 */' M4 ]- }  ]- `. r; j4 {7 b6 _
    }; [1 i: ^# u% h0 t8 ?
    /* ================ 公用的触发代码 ==================== */
    ! v: w# ~) ]3 ~1 Y4 b0 ivoid ISPgoon(void)
    5 q5 X# ?$ Z$ @{; F7 S- w# L6 E) W, e1 I
             ISP_IAP_enable();   /* 打开 ISP,IAP 功能 */8 m# v& X! p2 ~7 c6 o, ~
             ISP_TRIG = 0x46;  /* 触发ISP_IAP命令字节1 */% ^3 B$ ^% c! N) S6 X0 H+ Y
             ISP_TRIG = 0xb9;  /* 触发ISP_IAP命令字节2 */+ a8 r/ m$ r1 F
             _nop_();
    * |( M4 C* P1 }: i- G6 Z7 C}
    % A  R* h; k- |. K6 O% l' J4 `3 M9 p/* ==================== 字节读 ======================== */
    ! @( q2 K: \* f% dunsigned char byte_read(unsigned int byte_addr)' |# I# M) R4 e, [) d- @
    {
    ' U6 N3 b9 M7 `3 K1 a        EA = 0;5 y$ v5 D+ t( ]1 i8 B
             ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */
    ( r8 z3 ^7 T3 u5 S7 \5 {         ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
    ! d0 I4 H3 @& `5 D' G6 y         ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */, b$ {3 f; O) `2 e0 W- h
             ISP_CMD   = ISP_CMD | RdCommand; /* 写入读命令 */0 u0 B' R; {1 {* H' _) w
             ISPgoon();       /* 触发执行  *// j! r9 L. }3 i, X, _, `
             ISP_IAP_disable();    /* 关闭ISP,IAP功能 */
    1 H4 t# s/ x: f- P         EA  = 1;9 t7 G  V7 E- F/ d6 I# U9 t
             return (ISP_DATA);    /* 返回读到的数据 */; s* `" ?/ W: a1 H; Y% ]
    }* b8 `  K, S! o0 U. ^+ ^
    /* ================== 扇区擦除 ======================== */
    - m1 D$ n% j. b( S( V$ Xvoid SectorErase(unsigned int sector_addr)  A# g7 a+ ]. `( B5 f
    {2 X5 _  ?/ k" F! l+ f2 `
             unsigned int iSectorAddr;" U) d' }! Y+ N# P" p- c
             iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
      Y4 ~' [7 p/ K' y# E$ s" J2 U         ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
    ) n9 _8 }$ p8 A1 ^+ N         ISP_ADDRL = 0x00;" Y: ^6 }# D" b
             ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */4 \, K( s6 c( N* m, r
             ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
    7 Y1 r% M, Y  J2 B' K! x% P- G         ISPgoon();       /* 触发执行  */
    2 u& D# Q. b& t2 ?" w         ISP_IAP_disable();    /* 关闭ISP,IAP功能 */
    1 R. \, G8 F9 ]6 S+ h}
    / v% S/ c" |6 R: F/* ==================== 字节写 ======================== */
    . L8 ]3 F, a5 W* nvoid byte_write(unsigned int byte_addr, unsigned char original_data)
      ]8 I$ B# E. ^7 J{% D0 p* V6 C  ^. X; r
             EA  = 0;$ V/ B: i( J8 I% h2 R
             SectorErase(byte_addr);
    % m9 u1 \2 P9 |         ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */4 F! n8 `' \5 m. R
             ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
    ' I( Y$ G" A1 ?         ISP_CMD  = ISP_CMD | PrgCommand;  /* 写命令2 */
    5 b4 K0 }) j( Y2 B) ]4 M5 B         ISP_DATA = original_data;   /* 写入数据准备 *// r% [6 a! O8 L! a' Z! g
             ISPgoon();       /* 触发执行  */2 h. M$ x) R" r; _
             ISP_IAP_disable();     /* 关闭IAP功能 */
    1 F6 T6 m# c: h+ M  E         EA =1;9 l/ Z; e; A  x6 Z$ i6 f$ }$ A
    }' {8 \- f6 z% Q, q0 r9 Q
    5 S4 f9 s7 T1 N% c. ^
    + u, v/ o$ R5 c- J  ]+ @
    /***********************1ms延时函数*****************************/1 p9 C8 T! T# P: g7 o( p. T) o2 e+ Z
    void delay_1ms(uint q)
    . i( l5 g4 @" l1 k: A. }1 R{. [) s5 V! u( h( A& ?' }- p# s
            uint i,j;
      s8 K4 x+ c8 V$ s# a+ R        for(i=0;i<q;i++)
      N) |7 K0 v2 k! I& y7 C                for(j=0;j<120;j++);
    5 d% F/ j( ^& d7 m$ A5 X: N}
    ) f* N; K2 H. b- G; Y" ~/ k2 w) m5 E9 i
    /******************把数据从单片机内部eeprom中读出来*****************// r2 r# H0 q1 x9 C! W9 d
    void read_eeprom()         //读出保存数据
    ! ?5 E$ ]2 R0 z8 E% m; d# E  j{
    ' F1 e3 D+ n5 @$ n: J6 k        s_dengji  = byte_read(0x2001);$ J, u) v; r$ Z) Z3 J7 B  O2 G
            s_dengji <<= 8;) j+ d, _6 ~; V5 C5 T. N, O
            s_dengji  |= byte_read(0x2000);
    2 K, F1 M' n5 J# H& n% d        a_a      = byte_read(0x2058);
    % I# d& H8 W1 ~; [- u}
    % {4 ?9 ~& N" M8 a9 ~; P9 `% ^4 z5 N. @$ ~
    /******************把数据保存到单片机内部eeprom中******************/. w2 o. Z) y: k) L/ }
    void write_eeprom()        //保存数据
    " U0 o) N. Z; w4 V* B{5 M3 w$ W" P6 ~+ c9 o0 e1 Z
            SectorErase(0x2000);& X8 l! @! z5 K9 z
            byte_write(0x2000, s_dengji % 256);
    7 X0 _% Q0 N; X% s, _        byte_write(0x2001, s_dengji / 256);
    4 p! u4 h$ t: S7 V        byte_write(0x2058,a_a);        2 Y# G& Z. M# V" @- Z4 Z/ @
    }
    4 R3 q$ I- {2 r
    4 R5 ]! M3 {" W7 A" a% b3 U/**************开机自检eeprom初始化*****************/
    5 t0 Q6 v% a4 ^, u" lvoid init_eeprom()         ////开始初始化保存的数据. f% ~! j( U6 m5 l2 D4 r. G
    {
    8 j9 D; \7 d: c+ Q; r1 w0 v: U        read_eeprom();           //读出保存数据
    7 l' `' g: ^7 J  D7 _        if(a_a != 33)2 B* I% j' H+ Z# ^0 `3 _$ |
            {, p0 S* Q/ D& J- Z8 j
                    a_a = 33;
    2 c. f% H5 q- A/ Y# e                s_dengji = 80;
    ' T  l% J) p5 Z7 d- z2 `0 o                write_eeprom();                 //保存数据, e6 Q% e# g% C
            }
    + [  }' |$ I  D3 u% a1 s6 J1 a' r}
    " \1 u2 [2 k+ g! U; @! z7 k! Z: x; q6 k3 j  q! y
    /***********读数模转换数据********************************************************/        ) z/ f# V" y8 l# }9 k, X. d& J& f
    //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的+ g+ y7 r. z' u) z. \: x
                                                    //  1  0  0 通道
    ; O# X/ j. M+ k( M# C! L% v                                                //  1  1  1 通道 7 J5 n* b: ?4 w. f
    unsigned char ad0832read(bit SGL,bit ODD)2 i; ]0 Y: w& G3 c1 _6 Z/ L* }
    {  I9 w$ W, T3 ?0 w9 \
            unsigned char i=0,value=0,value1=0;                . u% Q0 v" f8 f* g5 B
                    SCL=0;
    0 h7 U" t; L3 z: }4 a                DO=1;
    & j7 K7 f( b. r3 D" ?                CS=0;                //开始
    $ C3 ~( {& D3 B- d9 v" B                SCL=0;                //第一个上升沿        2 s- w+ `- W) ?6 ]( R8 A5 R& i
                    SCL=1;
    + C$ _( q: Y& C. k2 O                DO=SGL;+ E# L; f4 {  J! M: Y/ q
                    SCL=1;          //第二个上升沿
    4 |# E$ p! P1 }4 i* q3 |8 F5 l+ a                SCL=0;, d0 n5 |" h6 X# I) `& O
                    DO=ODD;
    0 ]" |/ B: b% Q7 T6 S                SCL=1;            //第三个上升沿
    ! c4 N8 b. X. y+ \                SCL=0;            //第三个下降沿8 z4 C) c4 i1 }4 z9 M+ Q
                    DO=1;
    + l! F$ P# J0 Z9 y+ U0 n1 F                for(i=0;i<8;i++)6 C4 }7 q" V$ T0 B
                    {' k, P0 [) L' b. q. `# T2 s9 E* o
                            SCL=0;
    / O, W' A# [# Q5 ?                        SCL=1; //开始从第四个下降沿接收数据
    ) K9 F+ W5 }% Q; Q* |( k2 Q7 A                        value<<=1;" d5 s* a. A$ c: L4 E/ V7 y  b
                            if(DO)) b% ?% N: @! ?3 }; z/ w: z/ F7 q
                                    value++;                                                / m1 a7 u/ S. Z4 x8 {3 u! S, ]0 p
                    }& |: l1 K' c" f- w, [6 Z0 \
                    for(i=0;i<8;i++)
    ! F. O7 s- ?* ^. U) ^                {                        //接收校验数据
    ) J# `8 e6 N' p9 t$ F  l8 i                        value1>>=1;. {4 M0 f" f- A% y3 v
                            if(DO)
    7 e! b* c( y6 {, C                                value1+=0x80;2 M/ L, Y0 E- s: b/ _3 j2 B
                            SCL=0;: y: Z; S. C1 y7 L
                            SCL=1;3 j( p3 ^+ K6 K0 w' `; T: t" x' [
                    }3 n& j; K4 G$ }: G) N
                    CS=1;. R' \* E! w" J; |& w6 S
                    SCL=1;        9 g0 o) b$ O; v' J6 S9 L+ }' g
                    if(value==value1)                                //与校验数据比较,正确就返回数据,否则返回0        ( r% L/ i0 W0 I% I" I) W
                            return value;
    ! L9 r3 ^0 L$ |/ r5 v! T        return 0;$ Y( X- J# r$ D6 M0 u! P% M  y
    }, n# f0 Q6 R/ B5 T

    % Q  B% H" `5 v# Y$ {( o/********************独立按键程序*****************/2 D1 [% }% G# N( G) ?$ J6 z
    uchar key_can;         //按键值
    - B- C2 g5 c6 h# g/ ]  _
    3 O0 m- p0 t" W' R6 Yvoid key()         //独立按键程序
    2 @# h& e' o" }. p{. x, p* Q0 ]8 @
            static uchar key_new;+ N0 c5 s/ K& c# U# Y
            key_can = 20;                   //按键值还原
    ( N  I  r! O8 j        P2 |= 0x0f;                                        //把按键的IO口输出为高电平# r7 m$ K; R% m. J% x
            if((P2 & 0x0f) != 0x0f)                //按键按下6 y) Y3 s4 Z6 m* ^! E+ a
            {, Z9 d8 S1 G& K! \2 s0 k, j2 Q1 S
                    delay_1ms(1);                     //按键消抖动
    ) P7 u* a4 f* ^- |) x3 z- q* i  `                if(((P2 & 0x0f) != 0x0f) && (key_new == 1))5 Z% W+ b8 H$ A8 y' H) n, T
                    {                                                //确认是按键按下
    ; @) z9 {4 ~8 j6 h% D' o                        key_new = 0;
    # b4 f7 @/ V* K  n                        switch(P2 & 0x0f)4 O& O( b' T; L* u8 T, R7 g' x
                            {
    , c8 d* c; U# l+ Y& p6 }                                case 0x0e: key_can = 3; break;           //得到k1键值' Z1 d5 |9 t; B" K5 ^1 f
                                    case 0x0d: key_can = 2; break;           //得到k2键值. K4 b9 m; G$ a
                                    case 0x0b: key_can = 1; break;           //得到k3键值+ P5 P: {' m  m% @7 ]
    //                                case 0x07: key_can = 1; break;           //得到k4键值3 m3 `9 W8 k3 @" q% Y. D
                            }
    7 ^3 w$ a' ?$ L: E8 e1 a7 P                }                          I2 y4 H7 t* B# w# j
            }
    9 s7 ^. n" O- h+ D        else
    9 \2 |6 n& t4 j8 f8 w1 v0 k                key_new = 1;        . N/ h' y  Z; e! g9 m
    }
    " W/ @& y+ }& ^& D, y0 ^3 y: ], n1 Z0 ^. K+ |5 q

    9 Z& s4 V4 P6 U6 k& \( h$ [0 V6 ?  o4 R* ?
    /****************按键处理数码管显示函数***************/
    $ V; u9 [* j& c6 c( c8 _/ _void key_with()$ ]3 \' p% T) V+ L$ a: l. P
    {) b) ^, j$ x% G# r6 n. N) x( N- H8 u
            if(key_can == 1)                   //设置键
    $ g, c8 }. G8 s' n        {
    ( |4 G) j' c. [* a% w4 w                menu_1 ++;
    6 `8 D0 Q5 N1 W, O1 y- z' `                if(menu_1 >= 2)3 c) y6 b* u9 s' u8 g
                    {, `) z' ]& Z( F6 a. o
                            menu_1 = 0;+ ~; i1 E# Z7 J; k! C4 u
                    }9 Z9 d- N. O  F7 U  S* ?% q
            }& F. K% ]0 d5 b+ v7 ^0 f
            if(menu_1 == 1)                        //设置酒精报警值' i* N( K; A+ _) D
            {$ ?* J, `" E) y, A& w
                    smg_i = 4;                    //显示4位数码管
    % x  \' [  b8 S3 b                if(key_can == 2)
    9 \0 ]4 ?" y. u$ S* G( [' j% P0 d                {
    5 l# x4 {+ q2 v. d                        s_dengji ++ ;                 //加1
    6 i4 o' @; Z6 v3 g+ S( U0 [                        if(s_dengji > 500)9 k# U: t  R1 U5 }! N% A' J
                                    s_dengji = 500;2 b# ~& ?# ?1 f& f9 o8 ^
                    }  i" A7 j2 u( \7 P( w; x9 A
                    if(key_can == 3)
    # p; |) n# a3 _( [; r( [! L                {0 s8 [5 B7 M& l8 C2 X3 y% V
                            s_dengji -- ;                //减1        6 B, n1 t& P5 z5 a; X4 z, z
                            if(s_dengji <= 1)
    % @+ t: ]% [8 F  f- Y! A2 g& i- F                                s_dengji = 1;. i3 b+ }4 y1 \$ C- G
                    }- T0 O( H" z* H  d8 c" u
                    dis_smg[0] = smg_du[s_dengji % 10];                   //取个位显示
    6 A& E, z' [& h& ~0 P: Q                dis_smg[1] = smg_du[s_dengji / 10 % 10] ;      //取十位显示3 J* e7 }  B4 W% f: z4 L5 X
                    dis_smg[2] = smg_du[s_dengji / 100 % 10] ;           //
    * x0 o( B5 W' g5 t, u( B6 H, I% q                dis_smg[3] = 0x0c;         //a, @4 ], U( B/ Q
                    write_eeprom();        //保存数据
    2 `9 r6 N* ?- o  O" X+ @% `! C        }        & G5 ^% j0 l7 _/ q) Y6 P
    }  0 T1 }* M: ^' L" q. P$ h8 d# ?  h

    # k* l7 O  f& p2 |/ v$ X- T% a
    ; l5 n" ]0 U2 H  \. L4 }3 k. P/***********************数码显示函数*****************************/
    * i. N! r. X3 q0 F# I4 |void display()
    ( L. @7 C% D# a4 v+ P( |  N; r# h5 D{+ T. _6 }$ N0 @
            static uchar i;        & l( T3 F. h9 F# X" z5 e6 R5 E
            P1 = 0xff;                         //消隐                                          
    5 A& f  d; e3 \) A' V% M        P2 = smg_we;                          //位选. n% r; q. u5 B+ T
            P1 = dis_smg;                 //段选           + l* |3 J! q0 ?) y  I" {; u+ T+ S
            i ++;9 C! y& x5 F% ^
            if(i >= smg_i)
    2 ?+ {3 f) _0 Z' F) s                i = 0;          # ^/ v8 x" H4 D6 a
    }+ G% O3 q, }( z/ U

    0 E3 h; D4 H/ f3 V- |5 h: A5 |3 k" b; W1 ?$ M( m3 t8 U
    /*************定时器0初始化程序***************/
    ) N8 ~% r' s* h$ X* w8 svoid time_init()         
    8 v( B. R% r, n1 F' ]5 |/ C; H" P{
    + @/ n) n: F2 a  O" e6 r3 L        EA   = 1;                   //开总中断
    2 S; t% O6 l9 y! @% v4 _        TMOD = 0X01;          //定时器0、定时器1工作方式1
    * c, [  w9 ^2 f. a        ET0  = 1;                  //开定时器0中断 * |- I1 u2 b+ p- r
            TR0  = 1;                  //允许定时器0定时
    3 D* T/ q, I! d! h$ l6 S) n  G}
    : h" n7 @/ M$ ?' k* s/ q
    * E/ m2 J/ N8 Y  E& s+ R* ~, T! j* ^$ y- {

    $ L2 V( v; s5 e7 d8 f/****************报警函数***************/) ]: J0 r6 ?, m' @# m2 O) `
    void clock_h_l()
    & C4 D( `$ r: O{
    % p0 B- O4 P6 I& g0 H        static uchar value;# H% C2 \3 t/ K' D  o5 v) n
            if((dengji >= s_dengji))                //报警
    9 l8 }) Q5 l3 ^! M8 O7 g' R        {
    / @7 c1 T4 j& }1 @4 J* n                value ++;. p- B+ S5 @, t  N. ~2 I
                    if(value >= 2)$ F, S, V0 t; I1 k8 X
                    {4 i' ^; n$ l, K5 E8 ?6 D7 ?
                            value = 10;
    . \5 A! u' p; ]! h. l0 ~                        beep = ~beep;          //蜂鸣器报警* _' Q1 w; m& f6 t* _
                    }
    $ {6 X1 m! x$ D! o, p* r        }else
    4 Y) |: z0 I& M2 r1 n! f% T: B, C" T        {$ M4 S) b  n% p
                    if((dengji < s_dengji))          //取消报警) N! h2 r; D, _* o% p" a* a, `+ r0 ^
                    {4 h8 T5 }) f1 m% t, G3 ?
                            value = 0;
    ( U# Z& [8 _1 Q2 k' M6 l; e( U; w8 Q3 b                        beep = 1;$ b3 o; A( [  f  P2 Q, r
                    }        % D" O5 ?( }4 h) _
            }
    # i; Q6 x: f" M/ e5 _0 v3 k4 |! [5 U0 ^8 y4 P3 x
    }( J9 X: M8 n! u( m
    9 e5 W9 `$ o7 {- w: L: X5 q* |
    /****************主函数***************/
    " z5 f4 N+ R- J" k- v! Tvoid main()
      n7 b3 b' f: f3 m4 A( h{
    . k: a$ [! d" E0 B) q4 A4 K: L        beep = 0;                                //开机叫一声   
    5 ]& ?  W' H' O5 ?5 y+ d5 x        delay_1ms(150);
    & [$ o2 u" h8 \) d6 h2 P$ q        P0 = P1 = P2 = P3 = 0xff;                //单片机IO口初始化为1
    3 G4 P) W1 B$ l1 z        time_init();                                //初始化定时器
    # u" x/ S. u6 y8 Q2 S# t! D" H        init_eeprom();              //开始初始化保存的数据! f: v8 w6 m/ {# C$ I
            while(1)( M1 w: I, {  d) y: z1 h
            {
    " o: G7 V4 H8 ^" \9 i$ E                key();                                        //独立按键程序
    % v0 L4 x" _6 |0 I                if(key_can < 10)7 z. W( ~5 K1 b# w1 y5 M
                    {
    : [" v! p, l# a$ N                        key_with();                        //按键按下要执行的程序* s8 t' O. S  d
                    }
    % s# ], q- e/ _% h1 ^- Z                if(flag_300ms == 1)' l5 B0 [+ s  ^" @) ~
                    {                  ?, N* X" }0 s# J5 e& V. s
                            flag_300ms = 0;  b+ z8 r: E: k' H5 u4 B2 C4 U
                            clock_h_l();* q6 E2 x: `! k0 ?& ^* q
                            dengji = ad0832read(1,0);        ( L3 L$ g. C$ o% ~9 m
                            dengji = dengji * 450 / 255.0;
    9 W* x# _4 s, ?6 ?1 A* r- M0 i                    dengji = dengji - 100;              //首先减去零点漂移,一般是100mV* F& ]( u; s) x1 b& |5 w2 u. y5 N
                            if(dengji < 0)
      f' c: Q  Q4 G9 T, t* p  Z                                dengji = 0;        
    ' Z& S0 b# t3 p  K& l                        dengji = dengji * 2;             //将mV转变成mg/L,系数需要校准   - @$ M5 q+ j. |6 `# q+ o# H
                                                                      //电压每升高0.1V,实际被测气体的浓度增加20ppm 4 N+ i0 L- b% W$ @2 p
                                                                      //1ppm=1mg/kg=1mg/L=1×10-6 常用来表示气体浓度,或者溶液浓度。       ( o$ `8 W2 @  w. M
                            if(menu_1 == 0)8 l7 u1 J1 G) W
                            {
    1 W! ^  y! I. x$ S: k# g                                if(dengji >= 1000)6 ]3 J7 E/ c1 K" S" p
                                            smg_i = 4;
    " j2 }. v) H, ~9 X                                else
    , a4 u* A2 Y( J3 Y                                        smg_i = 3;
    - k0 q7 ~: `; Q3 V0 q                                dis_smg[3]=smg_du[dengji/1000%10];        //千位
    8 j1 N8 _: r  C' @4 t$ W                                dis_smg[2]=smg_du[dengji/100%10];        //百位
    & T3 M. Y  t8 m$ f                                dis_smg[1]=smg_du[dengji/10%10];        //十位3 C& f, p) o1 ?3 d( I2 h" P! E8 |$ `0 y
                                    dis_smg[0]=smg_du[dengji%10];            //个位        ADC0832为8位ADC,数值为0~255,我们将其分开放入l_tmpdate数组中显示
    ; p) R# W& z5 `( e) ]& f                        }8 _" J! `! }6 {
                    }
    ' O; l9 G& M) g9 s9 `1 E) g) J        }9 R3 u( o# i/ H; t' l3 B% d
    }
    ; A! G( _* Y" B
    ' y7 e& @! J5 I6 j/*************定时器0中断服务程序***************/
      ~& M  b. E! qvoid time0_int() interrupt 1
    4 N3 Y9 m" i6 |+ n8 Y4 x1 D{        
    . \$ ?% P- M8 ~7 Z' T7 z        static uchar value;
    + p) u/ v& }  S. g& F- k  @* d, _6 @& o' n- a9 e

    , p3 X/ C9 o9 G: \* |…………限于本文篇幅 余下代码请从论坛下载附件…………$ z9 ]: L2 Y7 \8 @: t/ ^7 n3 ~
    ( ]  A( Q# p8 q) o
    游客,如果您要查看本帖隐藏内容请回复
      ?  W0 e1 d" J6 @" V* x5 @
    ' z9 l  C" e% @! Z

    / C7 ^  F0 O& ~0 u% L2 A8 j

    该用户从未签到

    3#
    发表于 2019-1-24 15:26 | 只看该作者
    看看楼主的代码,谢谢分享
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-8-1 15:25 , Processed in 0.140625 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表