蓝桥杯单片机竞赛--PCF8591操作控制

目录

一、竞赛板PCF8591相关资料解析

1、PCF8591硬件接口

2、PCF8591模块程序

3、PCF8591芯片资料解读

(1)器件读写地址

(2)PCF8591控制字

(3)PCF8591工作时序

二、程序设计

1、完善I2C总线模块程序

(1)新建i2C.C模块同名的头文件

(2)在i2C.C文件添加对PCF8591的操作函数

2、主函数功能修改

3、数码管显示程序修改

程序包链接


一、竞赛板PCF8591相关资料解析

    PCF8591是一款I2C总线的存储器芯片,竞赛现场提供了电路接口(竞赛板的店原理图)、PCF8591芯片资料(英文版)、基础程序模块(I2C总线驱动程序)。下面从竞赛的视角地掌握这些,快速地写出应用程序。

1、PCF8591硬件接口

 

从图中可见,PCF8591的与CPU芯片接口电路用了2个I/O口线:P2.0时钟线,P2.1数据线。在编写程序时对它们进行设置。图中AIN0~AIN3为模拟量输入端,AIN0接在J3的18引脚,作为外部接入信号输入。AIN1输入光强度信号,AIN3输入电位器调压信号。模拟量输出引脚(DAC)接到J3的19引脚。

2、PCF8591模块程序

竞赛现场提供了底层驱动程序,根据I2C总线的操作时序以C语言形式编写,具体模块如下:

void i2c_delay(unsigned char i);//I2C总线中一些必要的延时函数

void i2c_start(void);//产生I2C总线启动条件

void i2c_stop(void);//产生I2C总线停止条件

void operate_delay(unsigned char t);//读写操作过程中一些必要的延时

void i2c_sendbyte(unsigned char byt);//I2C发送一个字节的数据

unsigned char i2c_waitack(void);     //等待应答

unsigned char i2c_receivebyte(void);  //I2C接收一个字节数据

void i2c_sendack(unsigned char ackbit);//发送应答

在了解PCF8591芯片资料和操作时序后就可以根据上述函数快速地编写应用程序。

3、PCF8591芯片资料解读
(1)器件读写地址

上图是从PCF8591资料上截取的器件地址格式,由8位二进制数构成,高4位是固定的1001,A2、A1、A0是芯片的引脚地址,与芯片的工作电路有关,最低位是读/写,R/W=0为写操作地址,R/W=1为读操作地址。

结合前面的硬件接口电路,竞赛板上的PCF8591的写操作地址为:90h。读操作地址为91h。

(2)PCF8591控制字

PCF8591控制字为8位二进制数,其格式及定义如下:(PCF8591资料上截取)

其中的D7、D3位为0。

D1、D0:A/D通道选择,4个组合对应4个人通道。

D2:自动增量标志,1有效,对4个A/D通道自动循环转换。

D5、D4:A/D输入模式设置位。

4个单端输入方式,即4路输入对应4个通道。

3路差分输入,AIN3作为公共端,与其它3路构成差分输入,分别对应0、1、2通道。

单端和差分混合模式,AIN0、AIN1单端输入,对应通道0、1,AIN2与AIN3构成差分输入,对应通道2。

2路差分输入,AIN0与AIN1构成差分输入,对应通道0,AIN2与AIN3构成差分输入,对应通道1。

D6:模拟量输出使能标志,1有效。

结合硬件接口电路,竞赛板上的PCF8591A/D输入模式只能是4路单端输入模式。

(3)PCF8591工作时序

上图为PCF8591D/A转换时序,时序如下:

启动—发送写地址—等待应答—发送控制字—等待应答—发送数据—等待应答—停止

上图为PCF8591A/D转换时序的再次启动读部分,前面需加上开始启动部分,本例以1个通道的A/D转换为例,具体时序如下:

启动—发送写地址—等待应答—发送控制字—等待应答—启动—发送读地址—等待应答—读字节­­—发送应答非—停止

二、程序设计

1、完善I2C总线模块程序
(1)新建i2C.C模块同名的头文件

在头文件中对C函数进行声明,程序如下:

#ifndef __I2C_H

#define __I2C_H

//函数声明

void i2c_delay(unsigned char i);//I2C总线中一些必要的延时函数

void i2c_start(void);//产生I2C总线启动条件

void i2c_stop(void);//产生I2C总线停止条件

void operate_delay(unsigned char t);//读写操作过程中一些必要的延时

void i2c_sendbyte(unsigned char byt);//I2C发送一个字节的数据

unsigned char i2c_waitack(void);     //等待应答

unsigned char i2c_receivebyte(void);  //I2C接收一个字节数据

void i2c_sendack(unsigned char ackbit);//发送应答

//新增PCF8591操作函数

//PCF8591  A/D转换

unsigned char adc_pcf8591(void);

//PCF8591  D/A转换

void dac_pcf8591(unsigned char dat);

#endif
(2)在i2C.C文件添加对PCF8591的操作函数

引用寄存器定义头文件,硬件P2.0、P2.1进行定义,本例新增加2个函数:

新增部分程序如下:

#include "stc15f2k60s2.h"

#include "intrins.h"

#include  "i2c.h"

#define DELAY_TIME 5

/** 定义I2C总线时钟线和数据线 */

sbit scl = P2^0;

sbit sda = P2^1;

//PCF8591  A/D转换  通道3

unsigned char adc_pcf8591(void)

{

       unsigned char temp;

       i2c_start();        //启动

       i2c_sendbyte(0x90);   //发送器件写地址

       i2c_waitack();       //等待应答

       i2c_sendbyte(0x03);  //ADC通道3

       i2c_waitack();       //等待应答

       i2c_stop();          //停止

       i2c_start();         //再次启动

       i2c_sendbyte(0x91);  //发送器件读地址

       i2c_waitack();       //等待应答

       temp = i2c_receivebyte(); //读A/D结果

       i2c_sendack(1);      //发送应答

       i2c_stop();           //停止

       return temp;         //返回数据

}

//PCF8591  D/A转换

void dac_pcf8591(unsigned char dat)

{

       i2c_start();         //启动

       i2c_sendbyte(0x90);   //发送器件写地址

       i2c_waitack();        //等待应答

       i2c_sendbyte(0x40);  //DAC输出模式

       i2c_waitack();       //等待应答

       i2c_sendbyte(dat);   //发送8位二进制数

       i2c_waitack();       //等待应答

       i2c_stop();          //停止

       operate_delay(10);    //延时

}
2、主函数功能修改

本例检测AIN3输入,结果在数码管上显示,结果正确的话数值在0~255之间。同时把A/D检测数据作为D/A转换的数据,用万用表检测J3的19引脚电压,调节电位器Rb2观察电压变化与数码管数据变化。程序如下:

#include "stc15f2k60s2.h"

#include "dis.h"

#include "key.h"

#include  "i2c.h"

void main()

{

       while(1)

       {

        dis();//数码管显示

        key();//键盘

        Vol=adc_pcf8591(); //A/D转换

   dac_pcf8591(Vol);  //D/A转换

       }

}
3、数码管显示程序修改

在数码管程序的开头,将测量的A/D值送显示。修改程序如下: 

Led1=10;         //灭

  Led2=10;         //灭

  Led3=10;         //灭

  Led4=10;         //灭

  Led5=10;         //灭

  Led6=Vol/100;    //百位

  Led7=Vol%100/10; //十位

  Led8=Vol%10;     //个位

程序包链接:https://download.csdn.net/download/weikangcekong/89587818

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值