|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
PCF8591 AD采集单片机程序 LCD1602显示 8 P4 e+ s2 y7 i
#include<reg52.h>) z( [' |1 j: c& p
#include<intrins.h>
" L7 g+ [9 g, `) {- |#define uchar unsigned char
3 O9 ^5 x& o0 ?6 Z#define uint unsigned int
, _ Q% F& q. }( c#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}* `/ J. C' V ~1 K( Y+ o. k4 B! A
sbit LCD_RS=P2^2;' I. ]5 n& C0 F) b/ e2 I8 g
sbit LCD_RW=P2^1;
& R1 l! S: u" nsbit LCD_EN=P2^0;; B# {9 X2 K, ^8 S- q
sbit SCL=P1^0; //I2C时钟引脚
6 b E# `2 W$ y$ Isbit SDA=P1^1; //I2C数据输入输出引脚
, [2 n J4 S i1 p* h0 M- I9 Fuchar Recv_Buffer[4]; //数据接收缓冲8 v1 G( m- ^ x. U8 \% n/ `
uint Voltage[]={'0','0','0','0','0','0'}; //数据分解为电压x.xx
; \* B; I+ ^5 N, Sbit bdata IIC_ERROR; //I2C错误标志位
1 R4 G( P2 x+ j( Xuchar LCD_Line_1[]={"DQ . ppm "};% m0 u P# F2 g* d. X4 N
//延时8 I4 T+ ?( F, _
void delay(int ms)! U6 ]5 n3 J: z, X9 R4 v: X
{* Y1 K8 m: E7 w/ x4 c( |
uchar i;' B- u6 G( H$ Y& `" G: Y
while(ms--) for(i=0;i<250;i++) Delay4us();2 ~) W! L) A! V0 p5 ?, x
}
% }2 F2 {: o- T6 U//LCD忙检测$ `' G5 t5 M% d- ^$ A& }2 z
bit LCD_Busy_Check()# J- s' F! f: w! h
{
! f$ W8 q5 k, g+ u K' M0 V2 Ibit Result;4 p* ?9 ~$ f( @0 Y" U4 w+ ]( j
LCD_RS=0;LCD_RW=1;6 V! V7 A0 r t( K6 L
LCD_EN=1;Delay4us();Result=(bit)(P0&0x80);
4 F" Z% D/ e4 [. x/ oLCD_EN=0; q4 q; w' z& r; H q
return Result;' j, \; I* v9 M7 u0 A1 J
}
/ b4 k v) R- w/ B9 G3 v9 J0 B' Z) I//写指令7 J/ X/ T( k) `( m# d) {
void LCD_Write_Command(uchar cmd)
5 m, z% i0 T( J$ y2 I8 J( m{
. d4 r) n! K" W2 P$ E6 z6 b# F v* Fwhile(LCD_Busy_Check());! e. T; u, T6 G8 I) d
LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();7 y0 K( `! r5 t
P0=cmd;Delay4us();
1 T; p* e4 S) Q: H3 ]' p( jLCD_EN=1;Delay4us();LCD_EN=0;1 U/ l+ _: N4 s) x$ k/ ~
}4 ]5 I& ]& g/ B4 e
// 写数据
7 u9 m B( K: S- ^void LCD_Write_Data(uchar dat)
: `, j- |5 a5 t2 u9 j8 E{6 i/ f2 H f2 b$ Z; p% w$ z
while(LCD_Busy_Check());
: e1 y) C9 b- c5 C `LCD_RS=1;LCD_RW=0;LCD_EN=0 0=dat;Delay4us();% |# f# w# D! D* U
LCD_EN=1;Delay4us();LCD_EN=0;
# b) [9 m; B2 A}/ {& N& i0 E( i" \' @
//初始化8 C' n9 N/ }3 q, Z3 K
void LCD_Initialise()
' q1 e6 m7 S: b: B{. W( D% g+ I& W- Y0 F) }! m# f
LCD_Write_Command(0x38);delay(5);
7 T5 k0 k8 x3 I! xLCD_Write_Command(0x0c);delay(5);
* h# e7 s) L+ } L% s tLCD_Write_Command(0x06);delay(5);; \6 q u3 h1 ~- E l
LCD_Write_Command(0x01);delay(5);/ {. g: D+ o' h
LCD_Write_Command(0x03);delay(5);, z3 o0 m8 D0 e% H% r
LCD_Write_Command(0x02);delay(5);
+ L: V% L8 u' `$ u. d1 m}
& ]- p. b( l, d6 ^2 S2 E//设置显示位置0 l: K% k# O+ o: K7 ^
void LCD_Set_Position(uchar pos)% B6 i" i9 y: @0 ^
{) u$ _0 B! _# v) t; Z
LCD_Write_Command(pos|0x80);
N& ^% y& I/ a% ?3 J9 [}( R g6 Y% x1 l9 {
//显示一行
5 d" t, J* m7 Q! K# r6 Evoid LCD_Display_A_Line(uchar Line_Addr,uchar s[]); T. L" @5 n" r2 T3 y1 n+ h
{+ d p/ k- l7 F9 y
uchar i;3 h) J) z: }' f9 Y, l
LCD_Set_Position(Line_Addr);
1 c' K& v# [ D) W) o+ _; afor(i=0;i<16;i++)LCD_Write_Data(s);# J4 \" I) J' B R$ _
}
% U9 ^; s5 v( D9 Y) y1 o2 V. [5 S// 将模数转换后得到的值分解存入缓存
# |) m9 E$ i8 c3 D+ p* c) Nvoid Convert_To_Voltage(uchar val)
) h5 e, n3 _' y( s) _, b+ Q5 M{/ E' _( X+ K% W7 ]8 J( P/ b% }
uchar Tmp; //最大值为255,对应5V
9 o$ E8 i5 d% dVoltage[2]=val/100+'0'; //整数部分# d0 q, s. |) u* Y' R k
Voltage[3]=val/10%10+'0' ;
9 o- z3 M5 a( P. q! H4 T& q8 S/ fVoltage[4]=val%10+'0' ;
' a% r: ?3 b+ n- A! BTmp=val*10; // 第一位小数
6 @4 e/ a9 n2 Q" {Voltage[1]=Tmp%10+'0';
0 N8 g" e2 C8 l: Z2 W$ V+ Z: WTmp=Tmp*10;
! ?# J1 w. F6 i" U# x% W% y6 o% GVoltage[0]=Tmp%10+'0';
5 W, r6 ^2 m3 g9 `, S# J/ V}
# S- d5 I. F3 r$ ]! `5 G) h( O//启动I2C总线
& m7 _( v( J$ C6 P- c$ j$ Q0 ivoid IIC_Start(): o* b& U* Y* k1 l
{
$ v" u Q( a4 w3 d. ISDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;7 o' s' k7 R7 O/ ^9 G- J
}5 U4 i) v0 g! `/ L
//停止I2C总线# w4 Q$ X* x8 W9 N
void IIC_Stop()9 O, @7 n+ N$ ^ q; ?
{
4 `0 K, v4 B9 |+ ^! FSDA=0;SCL=1;Delay4us();SDA=1; Delay4us();SCL=0;& F& y3 Y: a: O4 m$ W& h/ p
}2 R. q- W% E3 p
// 从机发送应答位* x! H- {( d; Q6 E$ u
void Slave_ACK()5 F9 \$ k0 r9 t l% P0 S& g
{
% J2 p& {# G. G( ~SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;
7 B8 `: y, G2 {+ N! _) R2 P O}# d3 Q2 l2 ]" }0 ~( Q6 [
// 从机发送非应答位& W- c R! z* _% u* E
void Slave_NOACK()9 A& h; p$ S- T3 `
{
, k% g6 U, B' `: L! k) `; KSDA=1;SCL=1;Delay4us();SCL=0;SDA=0;( E& M. A# k* d& ?2 N
}. V: Q, L7 d: U* W8 v8 |
//发送一字节
5 j8 K G) k9 q# z$ `: v" Yvoid IIC_SendByte(uchar wd)
9 D9 [ f7 L$ W{
6 y* p4 _7 E( u' h4 T- ]uchar i;
3 G" s$ d/ G# k6 ifor(i=0;i<8;i++) //循环移入8位: z6 C* @$ Q' D! y+ U" x
{
! s8 [7 M& o. y" z; B7 \0 l3 lSDA=(bit)(wd&0x80);_nop_();_nop_();
. ~- c% D$ q# Y8 \/ kSCL=1;Delay4us();SCL=0;wd<<=1;; m( M) R+ I% Y. Q
}
9 v: g" n7 O# y# U% t+ sDelay4us(); J- ~0 N( \6 }- z3 h/ i1 X: j
SDA=1; //释放总线并准备读取应答3 q( C# [" @0 M
SCL=1;
' s A- E5 A- U% v8 TDelay4us();+ E/ ~! _1 C G/ J
IIC_ERROR=SDA; //IIC_ERROR=1表示无应答
: w6 |7 m5 m1 O5 ?& pSCL=0;+ l6 a6 \( E {% n) I/ v6 `
Delay4us();
: b* l7 c' h2 Q, \% x}3 D# A5 P1 ^+ U- W) ]7 z6 U8 v
//接收一字节# Y/ H# o' O- M" p' F, N. D
uchar IIC_ReceiveByte()6 J2 T0 c' d2 T, T
{
5 O7 [: U& Z) D9 Y: g, Cuchar i,rd=0x00;
) i* E) m% G3 n {- ffor(i=0;i<8;i++)! Y" T( n5 F2 o
{& M( N* @# ^1 A2 a, ?0 F4 H
SCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();! a! y" _0 y) o9 {
}
# l; o1 n4 Y$ q) `& x+ E8 kSCL=0;Delay4us();
' D, ?. Z; b! M, u: s1 Creturn rd;2 E& Y" C$ K" {; k
}3 d5 A+ l8 J/ _
//连续读入4路通道的A/D转换结果并保存到Recv_Buffer
/ l6 U' p0 A; P1 A" `- Bvoid ADC_PCF8591(uchar CtrlByte)
9 I0 i: y6 x0 }$ }+ E8 Y7 t7 a/ b{
9 J9 g3 Q3 R: n' }' l7 |+ Wuchar i;
* ?9 q2 {2 }/ R9 P: _IIC_Start();1 u9 B. _! L# d4 c
IIC_SendByte(0x90); // 发送写地址+ m( \; A2 ^: [3 m; z4 ]$ |: y
if(IIC_ERROR==1)return;
3 x$ V7 A2 o- \// IIC_SendByte(CtrlByte); //发送控制字节6 Y, q3 i) W# d- h$ d. d4 I# j" P
//if(IIC_ERROR==1)return;3 ]$ X& c! O* Q$ \* w: l8 _
IIC_Start(); //重新发送开始命令! d+ Y7 p4 N0 E3 p3 Q2 s
IIC_SendByte(0x91); // 发送读地址
: z2 F( ~6 {% }if(IIC_ERROR==1)return;
7 ]5 O" w; Q4 z; XIIC_ReceiveByte(); //空读一次,调整读顺序
0 v; C, E- \2 k/ w6 t2 WSlave_ACK(); //收到一字节后发送一个应答位
4 {2 k) q5 f" \' o bfor(i=0;i<4;i++)) O( n6 E% E6 U. g! k$ W# Q+ e! R
{
# M3 B' e2 j/ \! N+ mRecv_Buffer[i++]=IIC_ReceiveByte();
% @ r8 n4 C" v9 K' t9 m/ MSlave_ACK(); //收到一个字节后发送一个应答位
, P0 L1 m% r2 Q# I9 C5 Q, G}
9 \6 [( D1 t8 K& y/ [7 Z' t) V3 tSlave_NOACK();* w4 Z" Q5 x% B1 P+ n$ u
IIC_Stop(); //收到一个字节后发送一个非应答位
/ w% I( M3 M, U$ c% g: B. ]} N T7 Q. T$ v0 f1 \* i% Y
2 R1 d3 p5 g# i. s+ [
* K, M/ @. G: ^0 p* J* A…………限于本文篇幅 余下代码请从论坛下载附件…………- ~. t# G" z" P: J
8 S* T' ~% N7 ~5 u8 U% k
8 N: b& e1 k7 @6 ~& ~& s) ~
* c! @. \# l2 ^ |
|