蓝桥杯单片机|蓝桥杯单片机-ADC-A/D转换-测量PCF8591中AIN1通道(光敏电阻RD1)的电压


文章目录

  • 前言
  • 实例程序:
    • 题目
    • main.c
    • iic.c
    • iic.h

前言 蓝桥杯单片机开发板CT107D中的板载A/D转换芯片PCF8591可进行ADC和DAC的转换,该芯片有4个输入通道;
蓝桥杯单片机|蓝桥杯单片机-ADC-A/D转换-测量PCF8591中AIN1通道(光敏电阻RD1)的电压
文章图片

在该开发板中,PCF8591芯片的AIN3引脚接滑动变阻器Rb2,通过旋转滑动变阻器Rb2,则可改变AIN3引脚的输入电压。
PCF8591芯片的AIN1引脚接光敏电阻RD1,通过改变光敏电阻RD1的进光量,则可改变AIN1引脚的输入电压。
蓝桥杯单片机|蓝桥杯单片机-ADC-A/D转换-测量PCF8591中AIN1通道(光敏电阻RD1)的电压
文章图片

PCF8591芯片通过IIC通信协议与单片机进行数据传输
该芯片的地址为 1001000,若单片机进行写操作,则发送的地址为0x90;若单片机进行读操作,则发送的地址为0x91。
滑动变阻器和光敏电阻两部分的代码基本一样, 唯一的不同就是单片机在给芯片发送指令时,滑动变阻器为0x43,光敏电阻为0x41。

实例程序: 题目 【蓝桥杯单片机|蓝桥杯单片机-ADC-A/D转换-测量PCF8591中AIN1通道(光敏电阻RD1)的电压】1.改变光敏电阻RD1的进光量,读出PCF8591上AIN1引脚所输入的电压值
2.其中数码管前两位显示电压值,后三位显示从PCF8591上读到的数据
3.改变光敏电阻RD1的进光量,数码管显示数字也会发生变化
main.c
//@mzw //改变光敏电阻RD1的进光量,读出PCF8591上AIN1引脚所输入的电压值 //其中数码管前两位显示电压值,后三位显示从PCF8591上读到的数据 //改变光敏电阻RD1的进光量,数码管显示数字也会发生变化 #include #include #include #includesbit hc138_A=P2^5; sbit hc138_B=P2^6; sbit hc138_C=P2^7; unsigned char shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9 unsigned char shuzi1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //0-9//含小数点unsigned char RD1 = 0; //从8591芯片中读出的数据,范围0-256 int V = 0; //由RD1转换后的电压值*10 范围:0-50v /*****配置138译码器*****/ void HC138(unsigned int n) { switch(n) { case 4: hc138_A=0 ; hc138_B=0 ; hc138_C=1; break; case 5: hc138_A=1 ; hc138_B=0 ; hc138_C=1; break; case 6: hc138_A=0 ; hc138_B=1 ; hc138_C=1; break; case 7: hc138_A=1 ; hc138_B=1 ; hc138_C=1; break; } } /*****延时函数*****/ void delay(unsigned int k) { while(k--); }/*****数码管显示函数*****/ void Display() { char x = 0x01; int i = 0; for(i = 1; i<=8 ; i++) { HC138(6); P0 = x; x = _crol_(x,1); HC138(7); P0 = 0xff; delay(20); //数码管消隐放到这个地方好一点 switch (i) { case 1 :P0 = shuzi1[V/10]; break; case 2 :P0 = shuzi[V%10]; break; case 3 :P0 = 0xff; break; case 4 :P0 = 0xff; break; case 5 :P0 = 0xff; break; case 6 :P0 = shuzi[RD1/100]; break; case 7 :P0 = shuzi[RD1/10%10]; break; case 8 :P0 = shuzi[RD1%10]; break; } delay(500); P0 = 0xff; } }/***** ADC相关 *****/ //向PCF8591发送信号,准备读取0x41的数据 void init_pcf8591(void) { IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(0x41); //PCF8591的通道1,接光敏电阻RD1,若是滑动变阻器则为0x43 IIC_WaitAck(); IIC_Stop(); } //读取数据 unsigned char adc_pcf8591(void) { unsigned char temp; IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); temp = IIC_RecByte(); IIC_Ack(0); IIC_Stop(); return temp; }void main() { while(1) { init_pcf8591(); //向PCF8591发送信号,准备读取0x03的数据 RD1 = adc_pcf8591(); //读取数据 V = RD1 * 5 * 10 / 255 ; //电压转换 Display(); //显示函数 } }

iic.c
/* 程序说明: IIC总线驱动程序 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台 8051,12MHz 日期: 2011-8-9 该程序为蓝桥杯单片机比赛官方所提供的参考代码 */#include "reg52.h" #include "intrins.h"#define somenop {_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); }#define SlaveAddrW 0xA0 #define SlaveAddrR 0xA1//总线引脚定义 sbit SDA = P2^1; /* 数据线 */ sbit SCL = P2^0; /* 时钟线 *///总线启动条件 void IIC_Start(void) { SDA = 1; SCL = 1; somenop; SDA = 0; somenop; SCL = 0; }//总线停止条件 void IIC_Stop(void) { SDA = 0; SCL = 1; somenop; SDA = 1; }//应答位控制 void IIC_Ack(bit ackbit) { if(ackbit) { SDA = 0; } else { SDA = 1; } somenop; SCL = 1; somenop; SCL = 0; SDA = 1; somenop; }//等待应答 bit IIC_WaitAck(void) { SDA = 1; somenop; SCL = 1; somenop; if(SDA) { SCL = 0; IIC_Stop(); return 0; } else { SCL = 0; return 1; } }//通过I2C总线发送数据 void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0; i<8; i++) { if(byt&0x80) { SDA = 1; } else { SDA = 0; } somenop; SCL = 1; byt <<= 1; somenop; SCL = 0; } }//从I2C总线上接收数据 unsigned char IIC_RecByte(void) { unsigned char da; unsigned char i; for(i=0; i<8; i++) { SCL = 1; somenop; da <<= 1; if(SDA) da |= 0x01; SCL = 0; somenop; } return da; }

iic.h
#ifndef _IIC_H #define _IIC_H//函数声明 void IIC_Start(void); void IIC_Stop(void); void IIC_Ack(bit ackbit); void IIC_SendByte(unsigned char byt); bit IIC_WaitAck(void); unsigned char IIC_RecByte(void); #endif

程序中iic.c 和 iic.h文件为蓝桥杯单片机比赛所提供的的参考程序

    推荐阅读