蓝桥杯突击8-PCF8591AD转化器(使用蓝桥杯官方库文件)

本次学习PCF8591.

PCF8591是一个ADC转化器, 可以将板子上采集的模拟量转化为数字量.

使用蓝桥杯官方提供的IIC驱动代码, 我们只需要写PCF8591的初始化和读取数据的代码就好.

多说无益,贴上代码:


iic.c:
 

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

#include "iic.h"

//总线启动条件
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(unsigned char 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)              //如果byte最高位是0,那么成立
		{	
			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;
}

void PCF8591Init(uchar channel)
{
	//时序:开始-发送主机地址-发送通道数-停止(期间有等待应答)
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(channel);
	IIC_WaitAck();
	IIC_Stop();
}
uchar PCF8591ReadData()
{
	//时序:开始-发送主机地址-返回数据-停止(期间有等待应带)
	uchar dat;
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_Ack(0);
	IIC_Stop();
	
	return dat;
}

 

iic.h:

#ifndef _IIC_H
#define _IIC_H

#include "regx52.h"
#include "intrins.h"

#define somenop {\
_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1


typedef unsigned int uint;
typedef unsigned char uchar;

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

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 

void PCF8591Init(uchar channel);
uchar PCF8591ReadData();


#endif

 

main.c:

/*
实现的效果为旋转板子上的第一个电位器,数码管会显示当前电位器的值
*/
#include "iic.h"

sbit BUZZ = P0^6;
sbit RELAY = P0^4;

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,	0xff};
uchar DisplayData[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uchar ADCValue=0;
uint n=0;

void CloseBUZZ();
void CloseLED();
void ChooseNixie(uchar site,uchar num);
void Display();
void Delay(uint i);

void main()
{
	TMOD |= 0x01; TH0=0xFF; TL0=0x9C; EA=1; ET0=1; TR0=1;
	CloseBUZZ(); CloseLED(); 
	PCF8591Init(0x03);
	while (1)
	{
		Display();
	}
}
void Timer0() interrupt 1
{
	n++; TH0=0xFF; TL0=0x9C;
	if (n==100)
	{
		//每隔时间采集一次AD值
		ADCValue = PCF8591ReadData();
		n=0;
	}
}

void Display()
{
	uchar displayNum=0;
	DisplayData[7] = table[ADCValue%10];
	DisplayData[6] = table[ADCValue%100/10];
	DisplayData[5] = table[ADCValue/100];
	
	for (displayNum=5;displayNum<8;displayNum++)
	{
		ChooseNixie(displayNum,DisplayData[displayNum]);
		Delay(60);
	}
}
//搬砖代码
void ChooseNixie(uchar site,uchar num)
{
	P0=0xff; P2=(P2&0x1f)|0xe0; P2&=0x1f;
	P0=1<<site; P2=(P2&0x1f)|0xc0; P2&=0x1f;
	P0=num; P2=(P2&0x1f)|0xe0; P2&=0x1f;
}
void CloseBUZZ()
{
	BUZZ=0; RELAY=0; P2=(P2&0x1f)|0xa0;P2&=0x1f;
}
void CloseLED()
{
	P0=0xff; P2=(P2&0x1f)|0x80; P2&=0x1f;
}
void Delay(uint i)
{
	while (i--);
}

 

                                  蓝桥杯突击8-PCF8591AD转化器(使用蓝桥杯官方库文件)

显示的效果为旋转第一个电位器会在数码管上显示当前电位器的值.