|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机控制温度,继电器输出程序出错高手请进来看一下- B. p: A+ z1 I
出错位置在 “按键操作子程序” gotoxy(1,1); //设置显示位置% z! g! w8 w( x& B6 e9 u6 e
7 Y2 b1 n4 t) F3 w( A7 s. K& x2 ^
/ a0 \5 o/ x4 m. R" Y( e+ N( V5 l6 j7 h+ j$ {" }
#include
$ v. @. V. e* P7 ?8 N#include
6 M2 W' P& G& u1 @! i6 h3 g+ `" }#include
4 { J& W O. H" ~4 p" n) Q3 @2 K#include
" b H2 u7 C6 i: B
, G; T- c$ R O' z' d#define uchar unsigned char/ i+ ^' [& Q, l8 ^& Y
#define uint unsigned int
6 X1 K5 W2 v" F( R! ~8 q$ {+ U) @% @ q \' I$ F
sfr DQ = 0x80; //DS18B20连接在单片机的P0口
: U1 u0 H& ^! s9 S Osbit LIGHT = P2^7; //灯报警标志P2^7口
( C: u3 H; W+ N. W$ osbit P3_6=P3^6; //引脚定义,继电器控制端 % F1 F9 ^7 |$ E, J& u! H
7 [: [' o2 K, f: r$ t5 e
uchar PLUS = 0x01;
8 m9 c+ E2 S% G! b/ Wuchar MINUS = 0xFE;5 g: Z3 h# n$ i) k+ r. \5 j
uchar temp1;' f% t+ ]7 h; ]5 [7 k8 p1 t
unsigned char xx;
# e" a+ L0 P+ D5 N( P& V bit mode=0,work=0;
& ~- J E! Z0 X0 {( U& @" Q6 ^int ALARM_TH = 0x32; //报警温度上限值,50摄氏度
2 `& |/ w: q1 c' R* Z$ o5 p6 qint ALARM_TL = 0x00; //报警温度下限值,0摄氏度
5 a: @( ?' b' ]: I6 n* jint temp_minus,temp_plus,temp,xiaoshu,xiaoshu1,xiaoshu2;" e$ u1 m7 Y1 Z
int temp_value = 0; //DS18B20 读出的温度值
+ P' ?3 V% m2 S# @# J3 s" \+ @" N/ f& t0 W6 g+ J
void Temp_write(uchar wbyte); //写DS18B20 一个字节& P! h" S( v" u9 K9 y0 Y
void Temp_bcd(void); . W' A9 {. L- \3 |0 E$ Y& R
void Temp_convert(void); //温度转换开始命令- W; @3 v& g2 S9 s& `0 A
void delay15us(uchar n); //延时15us倍数的程序
9 m, G0 {/ d$ `int Temp_read(void); //读DS18B20 一个字节
1 M7 A! }( g# g$ A, M4 gvoid read_temp(void); //读出温度值子程序
5 b" B3 G) d J* c2 [$ p# g; ovoid Temp_reset(void);
3 r- U+ U: B/ U) P% ^. V1 Xextern int abs(int val); //温度值为零下时取绝对值$ U9 a& N: @* E2 ^6 r4 r4 S; ^
void display_temperature(void);
& m) y& I. U% |* z+ ?+ qvoid send_temperature(void);6 Y. ~0 D2 _' L# V2 w! B+ a
void date_time(void);$ c; b+ c3 ^; W+ G8 n
void com_initialize(void);
3 ^; L4 p% Y7 G. v( Y, j7 L
/ X0 y: U+ @& n( F' ?void delay1ms(unsigned int x); //函数声明
/ y) s" L4 c+ A, G: X! l0 qvoid set_adj(void); //函数声明
+ z# T8 V }7 ^ nvoid inc_key(void); //函数声明
: d8 s X7 r1 a, Qvoid dec_key(void); //函数声明
6 }/ X" J3 k3 t$ _1 I6 I/ W: ?3 \$ _( y/ N3 |
//****************************************************************************
; [! E& a8 m. i! W* G" Qvoid delay1ms(unsigned int x) //delay x*1ms
( _1 E" F5 ~5 q+ U" `* y{ o8 d y6 Q0 d9 o1 P6 L; i; k/ `/ b
unsigned char j;$ F$ C4 r3 [6 n5 Q0 f& P# ]
while((x--)!=0)
^: l4 p& j% o4 G& S" Y {for(j=0;j gotoxy(1,1); //设置显示位置% k3 w: I' S- a _
display_LCD_string("Init_T: "); //显示初使温度 % E& D% ?9 j' [
display_LCD_number(10);
/ P; j, U3 c/ V write_LCD_data(223);# \" G- A+ p j/ H: _
display_LCD_string("C"); 6 R' ?! r( q, M# ]- ^
break;
, J; ^' a; Q l% W) N( T }
1 P4 ?) C# T) b4 p% E' H default:break;
0 t3 O2 `. y" `5 t' D3 C }
; C% R1 L$ L B6 t. J- T+ p } * C+ V: f$ g! `: h6 ^1 \
}. z r. C3 ~+ i$ U" r( q8 A" g% K
}7 S9 H" q8 ?1 g
//*****************************************************************************void set_adj(void) //模式设置子函数5 M6 @& {" ^, a" T
{ mode="!mode;
# ?! b( ?0 V4 T4 c" delay1ms(5000);- A8 c0 W/ |/ a
if(mode==0)
- Z' K! x% \4 c9 v# \, v* u {P3_6=0; //启动制冷
6 L: \7 G0 s! o- q! M* [ init_LCD();9 w& p7 G0 Q- s; U& y" p
gotoxy(1,1);
9 i: ?7 _6 x0 t( w8 s' o3 C7 B0 C display_LCD_string("Pre_temp:"); " _9 k# l0 z* Y$ W
display_LCD_number(temp1);9 t( v( x/ D' I( J( U1 x$ W
write_LCD_data(223);$ h. |, z& m" \# n" z
display_LCD_string("C");
0 t/ O, D4 j ? delay1ms(5000);
% E8 L- ]( ? }6 r! d8 Y }
: ^. H# S. c" l& ?% S if(mode==1)* h. a0 A1 u) `
{init_LCD();; a! p6 l: C2 L* u& J
gotoxy(1,1);' W/ u# |0 [2 U t3 G
display_LCD_string("Please Set:");
7 D5 U& {( ?* D# w: w delay1ms(5000); ; N0 \4 w( V- K, S. j
}
/ d/ U; @8 h0 e/ k% m. m" K$ t}& g+ C& e; f7 |; @( W
//****************************************************************************7 y7 L& \ K1 m# s- i2 w
void inc_key(void) //按键加法子函数* c! C( L) I1 l/ L5 X7 `
{ 6 y) l4 c, O" `' ^+ Z1 K: ?
if(mode==1)+ N/ Z! u9 \( N4 i3 E
{temp1++;
5 M4 \2 c, i5 Q; a. L init_LCD();* D9 B! i* H6 E1 W$ F
gotoxy(1,1);2 {5 K8 d3 w; D" x: [" {
display_LCD_string("Set_T: ");
+ \% E; _5 x; z display_LCD_number(temp1);
" n9 N1 h9 F0 O write_LCD_data(223);" N" T& x. X7 T6 G
display_LCD_string("C");& I; W# v0 a, K/ q, y
delay1ms(9000);
! ~* T8 u7 H7 Z
y6 Z# F( J! y }4 [0 U9 r- r. D) V& C
}
$ J4 B3 K# N# x, B {//****************************************************************************
! h: I# l s- {7 w" Nvoid dec_key(void) //按键减法子函数3 P+ H1 a4 d# {; o4 A4 k5 T/ a4 H1 `5 L
{
* i: _. I; i' o6 R0 U3 E2 F9 k if(mode==1)
z7 U: n4 P- U& E( c) l {temp1--;6 S. j; Q( E. {1 N! F6 O
init_LCD();$ t& j- {# L% Z+ Q6 O: p' H
//clear_LCD(); 9 |/ A$ l' V/ m2 D( X: I% n) r
gotoxy(1,1);3 G3 e7 y6 H& n9 a$ ~
display_LCD_string("Set_T: ");
4 E6 a1 z5 j1 X4 f display_LCD_number(temp1);" w/ k! H' Z# y6 W+ t) A
write_LCD_data(223);9 a+ T4 V' \- j
display_LCD_string("C");% k5 n5 h; \6 e- ~) g
delay1ms(9000);- g8 m8 \3 r/ O6 r& f
}0 U- V6 A( `1 `- f
: Y+ u, K% v% g0 h& c4 d. E
}
: N' Q+ |3 a" ?3 M% H5 L7 K//****************************************************************************2 K( h- w8 _+ n+ r0 Y
void delay15us(uchar n) " v& U, j2 }( r3 f$ \
{
; u z6 x& i5 m! }+ M do
4 M( m+ p5 |* B2 P3 y9 m4 s { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();: _2 @ I& d0 _0 K( L7 x( T
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
" k* z' L" Y) K. e8 ^" O --n;
; e) {7 a0 F+ }# _3 d3 d/ g# e2 N. l' | }while(n);
* ]+ D; L) r' m! J$ M return; ^- {1 U: k7 X6 S% U' Q( ?6 f. q
}
& n; \3 i% Q7 A2 h& d! c//****************************************************************************
3 C1 x- j0 p) `*温度检测子程序
+ m9 E! H4 S5 y" U" [//****************************************************************************1 ?' [9 N- e. K6 v
void Temp_reset(void): H. T E) s1 Z0 T/ L5 B
{
; q; Z% s+ g2 i: p uchar="uchar" i;9 b1 b. a: f7 Y# M
bit flag="flag" = 0; //flag为初始化完成(1)标志+ M# _# |4 Z1 |; k
while(~flag)
) v d/ b, z) G3 x7 Q: ]/ {0 p {, M' g6 @4 F% t+ v+ [7 a7 K( L$ h8 R
DQ="DQ" = MINUS; //主机拉低单线480us 2 E$ d9 N& K% Q b8 u/ L
delay15us(40); //产生复位脉冲3 S; R" P8 l7 n: S( ]! m
DQ="DQ" = PLUS; //上拉电阻拉高单线60us3 g- R4 M3 ?9 {$ m7 }$ J
delay15us(4); //延时60us/ Q: H8 \7 ]: o1 |4 |. l( H
* n- a! X# F- r- R8 i$ `# u while(DQ & PLUS) //等待DS18B20应答,拉低总线- p4 R- _3 ]- n
;
$ K4 N1 Y( {1 S4 M) ?% p& \6 W while(~(DQ | MINUS)) //DQ线被拉低以产生应答信号3 n9 X4 h7 Z6 ^2 O" K3 O
{
$ @. H" z6 b$ {8 l- S/ r flag="flag" = 1; //初始化完成
3 x" ^2 u/ e1 m Z, w" t for(i = 0; i="i" > 1); //每读一位,即右移一位,将新读的位放入最高位4 \ C; t, _: d) P
}
2 k+ _& u* e$ K9 J0 E _nop_(); //读时隙间隔至少1us" Z4 j) ~9 _! o* O
return(rbyte);
0 F9 S2 h! |5 y; p}" {6 m8 P* O2 x7 Y0 n1 ^
//*****************************************************************************
# ^1 p( d$ e7 @$ rvoid read_temp(void)' E! U% c+ i- o7 ~ V+ e3 @+ ~
{+ M: {+ r+ u' a9 s9 g
uchar temp_lsb,temp_msb;
: k4 v1 M1 _. `8 ]. }8 o# Z9 f0 c Temp_reset(); //复位DS18B20
/ K& {' P4 `- o7 O! N" K Temp_write(0xcc); //跳过读64位ROM序列号命令,用于单线接系统 [Skip ROM] [CCH]
6 o _8 U/ X; G9 E$ M; Y0 @* c' M Temp_write(0xbe); //读暂存器 [Read Scratchpad] [BEH]% J$ R% N, P" ^. k
temp_lsb = Temp_read(); //读出低字节7 {9 H# \5 c. p, T X
temp_msb = Temp_read(); //读出高字节6 H6 e3 }0 ~8 a
temp_value = (((uint)temp_msb)
; [6 U7 k" C* A#include 1 m7 E# F; U3 i( R3 ^5 T; a
char code int2charLCD[]="0123456789";+ W3 H" ?) ^# ]/ I8 n8 l, p0 v+ o
void write_LCD_command(unsigned command) //将命令写入LCM模块
# G4 t' z" }- j, o9 N{: j2 ~+ i' I: L
rw=WRITE;
4 [; x* I9 S/ u0 yrs=COMMAND;2 e; F, c/ z! g! j
enable=ENABLE;8 Y Q( O9 h X2 M
P1=command;$ g# H c5 k8 [+ e! @4 L9 Y
delay1ms(2);* p, K" b+ A' ?0 h: B* k' I& R7 x& U
enable=DISABLE;
4 t. p8 g, q. n6 p9 G a0 A* [rw=1;
/ N- d1 |6 r$ p" e; N ?& y v}2 L# E3 n- j& z$ h* |- `
void write_LCD_data(unsigned LCDdata) //将数据写入LCM模块
3 H* X! h- p* m$ L{3 @4 q9 }1 M. R2 L; J
rw=WRITE;# W2 V ^ Z/ B$ `1 i
rs=DATA;. _7 ` J. o4 [- l, Q9 [+ w
enable=ENABLE;2 S6 N- U" E7 b, y0 ]
P1=LCDdata;
0 P; W1 U. f9 ldelay1ms(2);
# `5 K0 v$ N- [, P6 Q% Fenable=DISABLE;) Q- h8 @! K3 x1 M" t
rw=1;9 S7 e# i/ L; `! e
}9 Y6 V/ [: Z6 U
void init_LCD(void) //对LCM模块进行初始化" D% f7 o/ A! L
{
9 Q% d |3 g; w& Q4 T3 M, S write_LCD_command(TwoLine_8bit); // 0x38
& e: i2 }! F6 ~, n, S. @2 d% n2 \ write_LCD_command(CURSOR_OFF); // 0x0C
4 \! Y% J6 s3 f% X4 I' l9 r write_LCD_command(CURSOR_RIGHT); // 0x06
7 F9 E" a) x# r' T4 }+ Z}' O0 [3 q& p. D0 {" y4 b
void clear_LCD() //清除LCM的显示屏" o6 m8 k. P2 L
{, D7 t+ _: ^ I' }5 }& z
write_LCD_command(CLEAR); // Ox01,清屏
5 g4 b H# x5 O% \& D, F7 X write_LCD_command(CURSOR_HOME); // ox02,光标返回原点4 T& Q4 d+ l! J r- p
} {4 E/ p5 W1 R
void display_LCD_string(char *p) //对LCM模块显示字符串
5 C/ z/ D7 n# n; b' z{9 q B# T3 k6 W/ P9 M5 ?; B
while(*p)1 w5 h! |* a1 @. ~
{" i( {; [" N8 o* _
write_LCD_data(*p);
) i5 V7 W" C( a p++;: J- u* j- J" }, J4 f
}
! B! ]: M/ P# W K: y4 S}
/ ~& M8 X3 q. Xvoid display_LCD_number(char number) //对LCM模块显示数字
$ x1 a" P( o$ Y' [! x{% W# y' U2 H) i. Y/ K
unsigned char x,y;$ V5 f) |$ x0 E! T
x=number/10;+ [* i8 P* ] {/ ?6 E: E; n
y=number%10;
! P2 q, p8 w0 S4 m' G, J write_LCD_data(int2charLCD[x]);
* V( Z8 j. o1 P3 z9 } write_LCD_data(int2charLCD[y]);4 [* m& |# f0 L1 N2 |
}
2 Z g" F7 \* N$ Evoid gotoxy(unsigned x,unsigned y) //设置光标位置
% ]7 |2 Z; B; i9 W7 @3 R' A. s{
7 f8 W! U7 G9 C if(x==1) ( \* I% {5 p+ L8 i7 K
write_LCD_command(GOTO_LINE_1+y);
4 j* k3 @) H) y8 x else
2 }+ r: O6 A, n9 o write_LCD_command(GOTO_LINE_2+y);
, C: O3 I/ [5 e s6 ]} |
 手机扫码浏览
|