蓝桥杯单片机(五) PCF8591

蓝桥杯单片机(五) PCF8591

例子:读取Rb2的电压值并显示在数码管上,范围0.00~5.00V.通过改变滑动变阻器Rb2的阻值可改变电压值。

iic.c:

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include "reg52.h"
#include "intrins.h"
#include "iic.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
		
		//加入
		IIC_WaitAck(); //直接将等待应答函数写到此处
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
		
		//加入
		IIC_WaitAck(); //直接将等待应答函数写到此处
		
    return da;    
}

//加入
unsigned char read_adc(unsigned char add)
{
	unsigned char val;
	
	IIC_Start();
	IIC_SendByte(0x90);  //MCU向PCF8591发送写设备命令
	IIC_SendByte(add);
	
	IIC_Start();
	IIC_SendByte(0x91);  //MCU向PCF8591发送读设备命令
	val=IIC_RecByte();   //读取A/D转换值
	IIC_Stop();
	
	return val;
}

main:

#include

extern uchar count_adc;
uint value;
extern uchar dsp_show[];
extern uchar dsp_code[];


void main()
{
	char i=0;
	system_init();
		
	for(i=0;i<10;i++)  //待ADC读取稳定后再显示
	{
		value=read_adc(0x03)*1.96+0.5;
	}
		
	while(1)
	{
		if(count_adc>199)  //200ms刷新一次A/D值
		{
			count_adc=0;
			EA=0;
			
			//读取光敏电阻RD1     value_adc=read_adc(0x01);
			
			value=read_adc(0x03)*1.96+0.5;  //	读取电压RB2
			//题目要求显示电压0~5.00,而直接从该地址读取的数值范围为0~255
			//因此先把数值范围处理成0~500(乘1.96+0.5),小数点直接通过操作数码管显示出来
			
			EA=1;
		}
			
		dsp_show[5]=dsp_code[value/100]&0x7f;
		dsp_show[6]=dsp_code[value/10%10];
	  dsp_show[7]=dsp_code[value%10];
		
	}
}

你可能感兴趣的:(单片机)