PCF8591 AD的问题一个
本帖最后由 angrybulb 于 2012-8-4 20:13 编辑小弟新来,刚学单片机,现在遇到个问题,我想实现PCF8591芯片的AD转换,先用通道4,然后再LCD上显示电压值,可是我烧进单片机后,无论怎样旋转电位器,显示的值都不会变,麻烦各位指点,O(∩_∩)O谢谢。
//----------------I2C.h--------#ifndef _I2C_H_
#define _I2C_H_
#define uchar unsigned char
#define uintunsigned int
//bit bdata I2C_ERROR;
sbit SCL = P2^0; //数据线
sbit SDA = P2^1; //时钟线
extern void I2C_Start();
extern void I2C_Stop();
extern void Slave_ACK();
extern void Slave_NOACK();
extern void I2C_SendByte(uchar wd);
extern uchar I2C_ReceiveByte();
#endif//-----------------delay.h---------------
#ifndef _DEALY_H_
#define _DEALY_H_
#define uchar unsigned char
#define uintunsigned int
//#define Delay4us() { _nop_();_nop_();_nop_();_nop_();}
externvoid delay(uint z);
extern void delay4us();
#endif
//-----------------LCD1602.h------------#ifndef _LCD1602_H_
#define _LCD1602_H_
#define uchar unsigned char
#define uintunsigned int
sbitRS = P1^0; //LCD复位端
sbitRW = P1^1; //LCD读写位
sbitEN = P2^5; //LCD使能端
extern bit LCD_Busy();
extern void LCD_Pos(uchar pos);
extern void LCD_Wcmd(uchar cmd);
extern void LCD_Wdat(uchar str);
extern void LCD_Init();
extern void Display_String(uchar Line_Addr, uchar s[]);
#endif//-----------------这是main.c-----------#include<reg51.h>
#include<intrins.h>
#include"delay.h"
#include"I2C.h"
#include"LCD1602.h"
//------------------------------------------
uchar FirstLine={" . V "};
uchar TempData;
bit ADFlag;
//------------------------------------------
void Init_Timer1();
uchar ReadADC(uchar Chl);
void disp();
//------------------------------------------
void Init_Timer1()
{
TMOD |= 0x10;
TH1=0xff;
TL1=0x00;
EA=1;
ET1=1;
TR1=1;
}
uchar ReadADC(uchar Chl)
{
uchar Data;
I2C_Start(); //写入芯片地址
I2C_SendByte(0x90);
Slave_ACK();
I2C_SendByte(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加
//Chl的值分别为0、1、2、3,分别代表1-4通道
Slave_ACK();
I2C_Start();
I2C_SendByte(0x91); //读入地址
Slave_ACK();
Data=I2C_ReceiveByte(); //读数据
SCL=0;
Slave_NOACK();
I2C_Stop();
return Data; //返回值
}
void disp()
{
FirstLine='0'+TempData;
FirstLine='0'+TempData;
Display_String(0x00,FirstLine);
}
void main()
{
uchar ADtemp; //定义中间变量
LCD_Init();
Init_Timer1();
while(1)
{
if(ADFlag) //定时采集输入模拟量
{
ADFlag=0;
/* ADtemp=ReadADC(0);
TempData=(ReadADC(0))/50;//处理0通道电压显示
TempData=((ReadADC(0))%50)/10;
ADtemp=ReadADC(1);
TempData=(ReadADC(1))/50;//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData=((ReadADC(1))%50)/10;
ADtemp=ReadADC(2);
TempData=(ReadADC(2))/50;//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData=((ReadADC(2))%50)/10; */
ADtemp=ReadADC(3);
TempData=(ReadADC(3))/50;//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData=((ReadADC(3))%50)/10;
disp();
}
}
}
void Timer1_isr() interrupt 3 using 1//定时器1执行数码管动态扫描
{
static uint j;
TH1=0xfb; //重新赋值
TL1=0x00;
j++;
if(j==200)
{j=0;ADFlag=1;} //定时置位AD采样标志位
}
//------------------------------------------
//--------------------这是I2C.c---------------------#include<reg51.h>
#include"delay.h"
#include"I2C.h"
void I2C_Start()
{
SDA = 0;
SCL = 1;
delay4us();
SDA = 0;
delay4us();
SCL = 0;
}
void I2C_Stop()
{
SDA = 0;
SCL = 1;
delay4us();
SDA = 1;
delay4us();
SCL = 0;
}
void Slave_ACK()
{
SDA = 0;
SCL = 1;
delay4us();
SCL = 0;
SDA = 1;
}
void Slave_NOACK()
{
SDA = 1;
SCL = 1;
delay4us();
SCL = 0;
SDA = 0;
}
//----------------写一个字节 -------------------
void I2C_SendByte(uchar wd)
{
uchar i,Temp;
Temp = wd;
for(i = 0;i < 8;i++)
{
Temp = Temp << 1;
SCL = 0;
delay4us();
SDA = CY;
delay4us();
SCL = 1;
delay4us();
}
SCL = 0;
delay4us();
SDA = 1;
delay4us();
}
//----------------读取一个字节------------------
uchar I2C_ReceiveByte()
{
uchar i,k;
SCL = 0;
delay4us();
SDA = 1;
delay4us();
for(i = 0;i < 8; i++)
{
SCL = 1;
delay4us();
k = ( k<<1 ) | SDA;
SCL = 0;
delay4us();
}
return k;
}
//----------------------------------------------//--------------这是LCD1602.c----------#include<reg51.h>
#include<delay.h>
#include<LCD1602.h>
//----------------------------------------------
//LCD初始化
//----------------------------------------------
void LCD_Init()
{
LCD_Wcmd(0x38); //8位数据长度 5X7像素字体
delay(1);
LCD_Wcmd(0x01); //清屏
delay(1);
LCD_Wcmd(0x06); //字符进入模式:屏幕不动,字符后移
delay(1);
LCD_Wcmd(0x0c); //显示开,关光标
delay(1);
}
//----------------------------------------------
//LCD忙检查
//----------------------------------------------
bit LCD_Busy()
{
bit LCD_Status;
RS = 0;
RW = 1;
EN = 1;
delay(1);
LCD_Status = P0;
EN = 0;
return LCD_Status;
}
//----------------------------------------------
//LCD写命令
//----------------------------------------------
void LCD_Wcmd(uchar cmd)
{
while((LCD_Busy() & 0x80) == 0x80);
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
EN = 1;
delay(1);
EN = 0;
}
//---------------------------------------------
//设置液晶显示位置
//---------------------------------------------
void LCD_Pos(uchar pos)
{
LCD_Wcmd(pos | 0x80);
}
//----------------------------------------------
//LCD写入数据
//----------------------------------------------
void LCD_Wdat(uchar str)
{
while((LCD_Busy() & 0x80) == 0x80);
RS = 1;
RW = 0;
EN = 0;
P0 = str;
EN = 1;
delay(1);
EN = 0;
}
//--------------------------------------------------------
//在LCD指定的行上显示字符串
//---------------------------------------------------------
void Display_String(uchar Line_Addr, uchar s[])
{
uchar k;
LCD_Pos(Line_Addr);
for(k = 0; k < 16; k++)
{
LCD_Wdat(s);
}
}
//----------------------------------------------//--------------------------这是delay.c---------------#include<reg51.h>
#include<intrins.h>
#include"delay.h"
void delay(uint z)
{
uint x,y;
for(x = z;x>0;x--)
for(y = 110;y>0;y--);
}
void delay4us()
{
_nop_();
_nop_();
_nop_();
_nop_();
} {:sweat:}亲,第一次发帖给点面子啊 现象描述不清楚。。LCD上显示什么值, 全00? 最好首次写测试模块的测试,在程序里插入一个1S一闪的指示灯,万一程序跑死机了,还可以看出来是否是程序跑飞了。 读AD先0x90后0x91 再看下手册吧 Bungy 发表于 2012-8-4 18:11 static/image/common/back.gif
读AD先0x90后0x91 再看下手册吧
哦,发现了,修改下试试看 slzm40 发表于 2012-8-4 16:55 static/image/common/back.gif
现象描述不清楚。。LCD上显示什么值, 全00? 最好首次写测试模块的测试,在程序里插入一个1S一闪的指示 ...
嗯,我没说清楚,显示是5.0V;
测试模块的程序是写在main函数里面吗? 看下SDA和SCL有没有接反,查一下硬件、
页:
[1]