登录
|
立即注册
|
使用QQ帐号登录
论坛
>
51单片机
发帖
|
LCD1602显示PCF8591 AD值 51单片机
看3932
|
回2
|
收藏
楼主
ID:122251
只看他
2016-5-20 21:15
LCD1602显示AD值 51单片机
所有资料下载:
LCD1602显示AD值.rar
(1.47 MB)
(下载次数: 94, 2016-5-20 21:14 上传)
下载积分: 黑币 -5
代码:
/*******************************************************************************
*
--------------------------------------------------------------------------------
* 实 验 名 : AD显示试验
* 实验说明 : 使用LCD1602显示AD读取到的各个数值
* 连接方式 : 见连接图
* 注 意 :
*******************************************************************************/
#include<reg51.h>
#include"i2c.h"
#include"lcd.h"
//--定义PCF8591的读写地址--//
#define WRITEADDR 0x90 //写地址
#define READADDR 0x91 //读地址
//--声明全局函数--//
void Pcf8591SendByte(unsigned char channel);
unsigned char Pcf8591ReadByte();
void Pcf8591DaConversion(unsigned char value);
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
unsigned int adNum[5];
float value0;
LcdInit();
while(1)
{
//--显示电位器电压--//
Pcf8591SendByte(0); //发送电位器转换命令
//--由于8591在第一次读取的时候是读取到的上次转换的结果--//
//--所以我们先读一次,只是读到的数据不做处理--//
adNum[0]= Pcf8591ReadByte()*2;//将前一次转换结果读走
//--在读走上一次转换结果之后,才开始启动下一次转换,需要一点时间--//
//--为了不浪费单片机的资源,让单片机空着,我们直接发送给我们下次--//
//--要读取的命令,做一些数据处理和显示当做延时--//
LcdWriteCom(0x80+0x46); //发送显示坐标
LcdWriteData('0'+adNum[3]/1000); //发送显示数据
LcdWriteData('0'+adNum[3]%1000/100);
LcdWriteData('0'+adNum[3]%100/10);
LcdWriteData('0'+adNum[3]%10);
Pcf8591SendByte(1); //发送热敏转换命令
adNum[0]= Pcf8591ReadByte()*2;//读取电位器转换结果
//--读取走了,上一次转换结果就是电位器的转换结果之后,热敏的转换开始--//
//--我们继续做一些处理当延时。--//
//--我们8591每读取到一个1就表示5/256V,所以要知道电压值就乘以0.01953--//
value0=adNum[0]/2*0.01953; //转为电压值
adNum[0]=value0*100; //保留两位小数
LcdWriteCom(0x80);
LcdWriteData('0'+adNum[0]%1000/100);
LcdWriteData('.');
LcdWriteData('0'+adNum[0]%100/10);
LcdWriteData('0'+adNum[0]%10);
LcdWriteData('V');
Pcf8591SendByte(2); //发送光敏转换命令
adNum[1]=Pcf8591ReadByte()*2; //ADC1读取热敏
//--一下读取的方式跟上面一样处理--//
//--读光敏--//
LcdWriteCom(0x86);
LcdWriteData('0'+adNum[1]/1000);
LcdWriteData('0'+adNum[1]%1000/100);
LcdWriteData('0'+adNum[1]%100/10);
LcdWriteData('0'+adNum[1]%10);
Pcf8591SendByte(3); //发送外部输入电压转换命令
adNum[2]=Pcf8591ReadByte()*2; //ADC2读取光敏
//--读取外部输入电压--//
LcdWriteCom(0x80+0x40);
LcdWriteData('0');
LcdWriteData('0'+adNum[2]/1000);
LcdWriteData('0'+adNum[2]%1000/100);
LcdWriteData('0'+adNum[2]%100/10);
LcdWriteData('0'+adNum[2]%10);
adNum[3]=Pcf8591ReadByte()*2; //ADC3读取外部输入电压
//--DA输出--//
adNum[4]=adNum[0];
Pcf8591DaConversion(adNum[4]/2); //DAC 数模转换
}
}
/*******************************************************************************
* 函 数 名 : Pcf8591SendByte
* 函数功能 : 写入一个控制命令
* 输 入 : channel(转换通道)
* 输 出 : 无
*******************************************************************************/
void Pcf8591SendByte(unsigned char channel)
{
I2C_Start();
I2C_SendByte(WRITEADDR, 1); //发送写器件地址
I2C_SendByte(0x40|channel, 0); //发送控制寄存器
I2C_Stop();
}
/*******************************************************************************
* 函 数 名 : Pcf8591ReadByte
* 函数功能 : 读取一个转换值
* 输 入 : 无
* 输 出 : dat
*******************************************************************************/
unsigned char Pcf8591ReadByte()
{
unsigned char dat;
I2C_Start();
I2C_SendByte(READADDR, 1);//发送读器件地址
dat=I2C_ReadByte(); //读取数据
I2C_Stop(); //结束总线
return dat;
}
/*******************************************************************************
* 函 数 名 : Pcf8591DaConversion
* 函数功能 : PCF8591的输出端输出模拟量
* 输 入 : value(转换的数值)
* 输 出 : 无
*******************************************************************************/
void Pcf8591DaConversion(unsigned char value)
{
I2C_Start();
I2C_SendByte(WRITEADDR, 1);//发送写器件地址
I2C_SendByte(0x40, 1); //开启DA写到控制寄存器
I2C_SendByte(value, 0); //发送转换数值
I2C_Stop();
}
代码:
#include"i2c.h"
/*******************************************************************************
* 函 数 名 : Delay1us()
* 函数功能 : 延时
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void I2C_Delay10us()
{
uchar a, b;
for(b=1; b>0; b--)
{
for(a=2; a>0; a--);
}
}
/*******************************************************************************
* 函 数 名 : I2C_Start()
* 函数功能 : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿
* 输 入 : 无
* 输 出 : 无
* 备 注 : 起始之后I2C_SDA和I2C_SCL都为0
*******************************************************************************/
void I2C_Start()
{
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
I2C_SDA = 0;
I2C_Delay10us();//保持时间是>4us
I2C_SCL = 0;
I2C_Delay10us();
}
/*******************************************************************************
* 函 数 名 : I2C_Stop()
* 函数功能 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿
* 输 入 : 无
* 输 出 : 无
* 备 注 : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲
*******************************************************************************/
void I2C_Stop()
{
I2C_SDA = 0;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立时间大于4.7us
I2C_SDA = 1;
I2C_Delay10us();
}
/*******************************************************************************
* 函 数 名 : I2cSendByte(uchar num)
* 函数功能 : 通过I2C发送一个字节。在I2C_SCL时钟信号高电平期间,
* * 保持发送信号I2C_SDA保持稳定
* 输 入 : num ,ack
* 输 出 : 0或1。发送成功返回1,发送失败返回0
* 备 注 : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
*******************************************************************************/
uchar I2C_SendByte(uchar dat, uchar ack)
{
uchar a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
for(a=0; a<8; a++)//要发送8位,从最高位开始
{
I2C_SDA = dat >> 7; //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
dat = dat << 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立时间>4.7us
I2C_SCL = 0;
I2C_Delay10us();//时间大于4us
}
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
{
b++;
if(b > 200) //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
{
I2C_SCL = 0;
I2C_Delay10us();
return 0;
}
}
I2C_SCL = 0;
I2C_Delay10us();
return 1;
}
/*******************************************************************************
* 函 数 名 : I2cReadByte()
* 函数功能 : 使用I2c读取一个字节
* 输 入 : 无
* 输 出 : dat
* 备 注 : 接收完一个字节I2C_SCL=0
*******************************************************************************/
uchar I2C_ReadByte()
{
uchar a = 0,dat = 0;
I2C_SDA = 1; //起始和发送一个字节之后I2C_SCL都是0
I2C_Delay10us();
for(a=0; a<8; a++)//接收8个字节
{
I2C_SCL = 1;
I2C_Delay10us();
dat <<= 1;
dat |= I2C_SDA;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
return dat;
}
沙发
ID:107467
只看他
2016-8-9 19:35
谢了,学习学习
板凳
ID:122133
只看他
2017-8-9 20:57
没用
显示一直不变
51黑电子论坛
Powered by
Discuz!
X3.1
首页
|
标准版
|
触屏版
|
电脑版