|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
PCF8591 AD采集单片机程序 LCD1602显示
3 ?9 E' `3 z1 Z/ N8 o, ?& N#include<reg52.h>5 W5 K' q2 x" O# j9 J3 D' Y7 S
#include<intrins.h>
7 g* p. ?6 G7 C#define uchar unsigned char
2 @+ F) j) f, I! b1 w) C#define uint unsigned int2 L3 `( {& [* z: [8 h4 e- h3 Z, R
#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}" |6 _( C. A) y1 Z& x( J, B& K) f
sbit LCD_RS=P2^2;
% H# `& E# i4 v8 \7 P! ssbit LCD_RW=P2^1;" t7 q0 {# B4 z ]/ t
sbit LCD_EN=P2^0;
: a, t9 H4 C2 @3 C8 J+ l2 tsbit SCL=P1^0; //I2C时钟引脚, C4 [1 n7 G/ \, s7 S/ _
sbit SDA=P1^1; //I2C数据输入输出引脚
& L# |9 l; R1 a0 ], quchar Recv_Buffer[4]; //数据接收缓冲
2 X5 D; G0 Y/ F7 n$ E" Kuint Voltage[]={'0','0','0','0','0','0'}; //数据分解为电压x.xx
& i6 X7 @* [8 o' Z6 n, dbit bdata IIC_ERROR; //I2C错误标志位
& \5 ~# | Q! ~, E4 iuchar LCD_Line_1[]={"DQ . ppm "};
) _& d b8 |' K' s//延时
0 U" }7 A5 F* Evoid delay(int ms)
4 B) Q G0 X) [$ A4 k) d3 f{
& f) A e u1 |1 tuchar i;
. G% {& k; u: }while(ms--) for(i=0;i<250;i++) Delay4us();
- U' o$ p" E" t y. v+ F}
4 |% S2 t: I1 ?$ C//LCD忙检测
! z$ G( Y$ s1 v/ d' tbit LCD_Busy_Check()
5 i. i; n" f7 P; i- O9 \{
- h% b/ C; d( R+ `3 {bit Result;1 T4 U) R/ ?; Z6 i# n0 k# n
LCD_RS=0;LCD_RW=1;$ T2 @/ S, a7 ~+ F1 ?
LCD_EN=1;Delay4us();Result=(bit)(P0&0x80);, b" I# p) U7 O1 B/ r) A& U
LCD_EN=0;$ @) b& t( M7 Y; P0 P
return Result; x5 T( a& S! y( x& i& ~
}
0 Y% R0 {, H; [# ~# m- I//写指令
! Q% y5 N* n9 O/ [4 B& nvoid LCD_Write_Command(uchar cmd)# o+ d) j/ c' e4 Z) \
{6 K/ {5 S/ Y- [) {! Z2 Q7 w% z
while(LCD_Busy_Check());* J! t5 z* A( ^! ]* i
LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();3 Q+ B2 o% _$ U! f$ y% ~0 x
P0=cmd;Delay4us();
, ~( ~) X3 x s* Q+ u! LLCD_EN=1;Delay4us();LCD_EN=0;1 _# M u w8 D% y2 s6 }5 I/ a0 L
}
( D) ?1 D# b! d9 s// 写数据
2 G) v2 D# _3 L( K* x, k: [void LCD_Write_Data(uchar dat)
" ]* U) _! m- n{
+ i4 `0 s0 l; y0 g+ }6 Q0 Wwhile(LCD_Busy_Check());. S* H2 Q! }3 U& M2 }
LCD_RS=1;LCD_RW=0;LCD_EN=0 0=dat;Delay4us();
# B) n8 n+ m/ q6 A# T' HLCD_EN=1;Delay4us();LCD_EN=0;
' g( n2 H% P/ g) z* [}
0 S/ F4 f+ s; f3 |+ f//初始化# x) U. @# x) [. G. x6 \+ `
void LCD_Initialise()
6 q, w* b& p [{; f$ u# v, z* h% V B
LCD_Write_Command(0x38);delay(5);. A% O) A6 Z5 f5 s# j) T8 n
LCD_Write_Command(0x0c);delay(5);
" e7 C" Z& R3 P' ~$ |' d4 U3 NLCD_Write_Command(0x06);delay(5);
% T6 p6 D. l5 @+ R+ g6 XLCD_Write_Command(0x01);delay(5);
* Z1 ]6 T" q. v& `7 i. m8 L4 V- aLCD_Write_Command(0x03);delay(5);/ r/ G! \- Q: ?8 w) e; R
LCD_Write_Command(0x02);delay(5);
1 Y( n Y- F7 h, g. |4 D: O* N. ^}
, f2 e+ X; x9 s+ {8 e+ m//设置显示位置5 v& ]1 b$ b. m1 g
void LCD_Set_Position(uchar pos)
4 ]6 O+ t3 D4 p* e) P, N4 U{9 B7 i* B! a% W- W9 \$ f
LCD_Write_Command(pos|0x80);7 T7 P- @. H, A8 r8 A8 H* i" V# ?5 q% H8 D
}
5 P9 P: X1 N: S, G q3 N//显示一行: o1 t2 @3 B$ H: w0 |2 L" ~
void LCD_Display_A_Line(uchar Line_Addr,uchar s[])
U' [/ v) h/ E{
3 I h6 ]: B [# ]. r; Z$ c. Ruchar i;
* H" B5 t8 j, o) U, x- r( rLCD_Set_Position(Line_Addr);
$ h8 x9 S! O2 D* C3 Efor(i=0;i<16;i++)LCD_Write_Data(s);5 A4 h' Z& q% Y3 h& {1 r
}# u7 ^& q9 s4 f2 l) b3 ]
// 将模数转换后得到的值分解存入缓存5 Z# a9 N6 |7 P# \; C2 e
void Convert_To_Voltage(uchar val)
3 r2 U4 a1 {' m3 W4 r' g6 U4 R{2 @0 V1 w8 _% Z
uchar Tmp; //最大值为255,对应5V$ |. K8 j0 B- ^; }( A+ L8 g
Voltage[2]=val/100+'0'; //整数部分1 @; E ~8 ^: ^7 m3 m4 Y
Voltage[3]=val/10%10+'0' ;
5 R$ o* [/ F" m9 h- V" x& AVoltage[4]=val%10+'0' ;
( h3 I, f9 A( d$ p0 S( Q- XTmp=val*10; // 第一位小数! _+ V) F% m! i" D! e
Voltage[1]=Tmp%10+'0';
+ p, _ \9 R5 xTmp=Tmp*10;
9 ?1 i4 f) l# @Voltage[0]=Tmp%10+'0';
) B- f7 D$ D% z; a/ y1 K& Y}
1 f4 A, [$ Y; U* Y. C; i//启动I2C总线
c) }$ t( C! \1 n% b+ t" ~void IIC_Start()
% J3 H8 |2 C& I/ J: _: Q{
* Q' V. o* p- ZSDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;; }! V% v; F& Y$ u$ S, z
}
( y! A L4 V4 @: s3 I: m8 p1 I//停止I2C总线4 w7 `3 E2 G9 R0 z9 k
void IIC_Stop()3 H4 U; V K( D- s7 G8 B. E
{" E$ P( O+ y2 _* v! p: ]( N w
SDA=0;SCL=1;Delay4us();SDA=1; Delay4us();SCL=0;3 o( ~( \2 p9 S* @/ [! R- ]7 G
}8 I8 k9 J! p& b
// 从机发送应答位" ]+ K1 D; o; W* g8 m& Q" c
void Slave_ACK()% R0 E/ O( ?2 T N# q$ T8 z/ |& w
{
6 K0 L } T) }* @SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;/ U1 }& J. l/ v3 c) ^, v. U5 P
}
3 f1 I: [. R+ x$ U- b// 从机发送非应答位1 w: P* K8 r0 c
void Slave_NOACK()
b+ g( E( \& l, l$ D0 E$ e' q$ \{
2 t; l( `5 g# dSDA=1;SCL=1;Delay4us();SCL=0;SDA=0;
! M5 T/ u) `* r( |}
3 [" o& I; V' K. q ^% d1 ~//发送一字节. r" ~4 m& A& Q" D
void IIC_SendByte(uchar wd)
- o1 p! o3 f' v# A9 o" S{5 t7 u3 u% l4 I0 S y
uchar i;
# v6 G2 n2 e4 Q& x" R+ u. N; E* E! {+ jfor(i=0;i<8;i++) //循环移入8位5 d0 Z/ x: d1 ]; M6 d
{0 u+ j' }$ U; g$ J
SDA=(bit)(wd&0x80);_nop_();_nop_();1 @5 J8 r7 c& w
SCL=1;Delay4us();SCL=0;wd<<=1;
% [$ v$ p D# g) A" @" r}; b% i ~- Z. M) t9 v
Delay4us();' F/ N8 _) {6 _- I+ ]: |
SDA=1; //释放总线并准备读取应答
. f( ]% V y# a) P) LSCL=1;
# p3 K9 Z r. y- j1 H- n- JDelay4us();
! }. w" W# J, @3 E5 h$ Z% e5 ^IIC_ERROR=SDA; //IIC_ERROR=1表示无应答
; Z. j$ J( q* E a% QSCL=0;
, `4 E8 A, E4 I4 A' nDelay4us();
; H1 c9 m7 q4 r! A6 S; T2 i: @/ C}+ \- B" p5 U% @- ]( J
//接收一字节" i; d$ t: j9 a4 x, y5 [
uchar IIC_ReceiveByte()
! l. B% K& U) V{
' k8 |2 |1 B8 o4 E3 c, Z tuchar i,rd=0x00;
0 Y+ `6 I3 f* ]/ C1 ~) Wfor(i=0;i<8;i++)1 @9 v1 Y- D6 b
{
+ Q7 I$ [0 z6 ]1 tSCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();' H, g) ]1 N, L. I
}
" ?& h+ j1 g# t7 S2 [- q; J; rSCL=0;Delay4us();: e) o' G9 b. A# p: R* m# w
return rd;
- \7 G( N, W2 }' d3 N* g' u! \}& |' D! z6 p. s: O
//连续读入4路通道的A/D转换结果并保存到Recv_Buffer3 T/ R6 @* J# J/ A, j( J* |3 {
void ADC_PCF8591(uchar CtrlByte)
4 a: T/ A6 l- i{
) V' S& d5 U# i6 |0 n! ?3 fuchar i;
4 T d+ E# a1 d5 x! V; VIIC_Start();( I* G# l; f% X3 n
IIC_SendByte(0x90); // 发送写地址
% a4 E o0 H9 D/ I! Y3 @/ ^if(IIC_ERROR==1)return;
6 Z2 z8 p1 X& ~% J7 v' F: P; _" s! s// IIC_SendByte(CtrlByte); //发送控制字节$ @2 q6 d) W* N, B5 Y/ g
//if(IIC_ERROR==1)return;
& P9 y3 V: C( V; C" c6 e2 HIIC_Start(); //重新发送开始命令- K* Y; ^( u4 O+ q
IIC_SendByte(0x91); // 发送读地址& i7 `9 R- O9 ?+ J8 m
if(IIC_ERROR==1)return;
4 a" v! o; T5 p% OIIC_ReceiveByte(); //空读一次,调整读顺序' a2 R$ U: r5 e
Slave_ACK(); //收到一字节后发送一个应答位1 O+ X. }4 L9 G
for(i=0;i<4;i++): M: l, d! H; {* q
{
9 ]- k5 }! r$ `' [% p2 Y" LRecv_Buffer[i++]=IIC_ReceiveByte();9 t" J9 U* H W# O. ]! ]1 G. c; @/ Q
Slave_ACK(); //收到一个字节后发送一个应答位
/ B! `: l ?& |. ?3 ~- J! U}) }+ P. t$ l) b& e% x
Slave_NOACK();
' X% r3 t! n' ]$ O* j) J1 ~IIC_Stop(); //收到一个字节后发送一个非应答位
* H" m! p1 K" B2 W- E1 u3 W9 \}3 g9 O3 Q3 Y D8 U. g8 h6 S% j n ~
$ V) G& {& D+ m) O9 K
& U) ~1 {5 g2 l: i b…………限于本文篇幅 余下代码请从论坛下载附件…………
B+ |) C% l* c: ~7 i! F& M# j
" L( n: B% B: [& [! h 6 I, D( _4 @- g3 L
+ W7 C. z0 F. c X/ W
|
|