蓝桥杯单片机(五) 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; }

【蓝桥杯单片机(五) PCF8591】main:
#includeextern 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=https://www.it610.com/article/read_adc(0x03)*1.96+0.5; } while(1) { if(count_adc>199)//200ms刷新一次A/D值 { count_adc=0; EA=0; //读取光敏电阻RD1value_adc=read_adc(0x01); value=https://www.it610.com/article/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]; } }

    推荐阅读