LQB,手打,PCF8591,ADDA转换,AD1是光敏电阻,AD3是电位器,DA输出
创始人
2024-05-28 19:22:45
0

在这里插入图片描述
在上述at24c02de 基础上,添加三个函数
一个是读取通道1光敏电阻的数据;
一个是读取通道3的电压;
一个是输出DA的数据。。

5V的AD DA。
如果读入的电压是5V,输入AD,就是255;
如果是0V,就是00000000;
如果是2.5V,就是125.
有个比例。

步骤,注意是
pcf8591A/D转换时:可以将连接在芯片上的AIN0,AIN1,AIN3,AIN2通道等的模拟量转换为数字量。

而且PCF8591芯片是一个8位的,通道上的电压取值范围是0-5v,相当于0-255一共256个刻度把5v平均分成了255份,那么1v电压对应的数字量就是51。所以我们在进行ad转换的时候不能简单的把读取到的量显示在数码管显示上,比如现在某个通道是3.1v的,那么它通过pcf8591芯片读取转换之后,我们实际上读取到的是3.1*51=158.1,但是如果题目要求显示电压值的话,我们就需要再把读取出来的数字量给处理一下,比如除以一个51.0。

从机等待应答部分的代码(即留下空格的部分)可省略。

PCF8591芯片D/A转换时(即把数字量转换为模拟量)在这里插入代码片

unsigned char read_in1()
{unsigned char dat;IIC_Start();		 //总线起始信号IIC_SendByte(0x90); //字节写地址IIC_WaitAck();		 //等待应答IIC_SendByte(0x01); //发送控制字IIC_WaitAck();IIC_Start(); IIC_SendByte(0x91); //字节读地址IIC_WaitAck();dat=IIC_RecByte();IIC_SendAck(1); IIC_Stop(); return   dat;                  //处理读到的AIN的量
}
unsigned char read_in3()
{unsigned char dat;IIC_Start();		 //总线起始信号IIC_SendByte(0x90); //字节写地址IIC_WaitAck();		 //等待应答IIC_SendByte(0x03); //发送控制字IIC_WaitAck();IIC_Start(); IIC_SendByte(0x91); //字节读地址IIC_WaitAck();dat=IIC_RecByte();IIC_SendAck(1); IIC_Stop(); return   dat;                  //处理读到的AIN的量
}void write_dac(unsigned int dat)
{IIC_Start();IIC_SendByte(0x90);  //pcf8591写操作地址IIC_SendByte(0x40);  //选择dac输出通道,第6位为1打开D/AIIC_SendByte(dat);	  //选择要给pcf8591芯片的数字量IIC_WaitAck();	    IIC_Stop();   	      //停止通讯
}

全部代码啊

主函数的代码

#include 
#include 
#include //接口
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
//宏定义
#define     LED       4   //定义主时钟
#define     ULN       5   //定义主时钟
#define     COM       6   //定义主时钟
#define     ABC       7   //定义主时钟
typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;
//-----------------------------------------------#define FOSC 11059200L#define T1MS (65536-FOSC/1000)      //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式//全局变量
u8 LEDbuf=0xFF;
u8 ULNbuf=0x00;
u8 SMGbuf[20];
u8 SMGdat[8];//8个数码管,所以8个元素u32 tim1ms=0;//u32类型,几十天才溢出
/*************  本地常量声明   ,这是共阴的 **************/
u8 code table[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
//函数声明
void delayms(u16 tms);
void Delay1ms();		//@11.0592MHz
void sel(u8 x); //选择四个分支哪一个?
void sysinit();//系统初始化,关闭所有的外部设备
void disp();
//主函数
void main()
{//main局部变量u8 num1=25;u8 num2=0;int num3=1289;int num4=0;int num4H,num4L;//低位和高位u8 in1dat;u8 in3dat;//外设初始化sysinit();//系统定时器初始化AUXR |= 0x40;                   //定时器1为1T模式TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)TL1 = T1MS;                     //初始化计时值TH1 = T1MS >> 8;TR1 = 1;                        //定时器1开始计时ET1 = 1;                        //使能定时器0中断EA = 1;//大循环//这里,可以加一点测试代码,测试是不是每个外设都成功;SMGdat[0]=0x77;SMGdat[1]= table[num1/10];SMGdat[2]= table[num1%10];SMGdat[3]=0x40;SMGdat[4]=0x40;SMGdat[5]= 0x7C;		SMGdat[6]= table[0];SMGdat[7]= table[0];while(1){if(S7==0){delayms(10);if(S7==0){write24byte(0x00,num1);delayms(5);  //等待5ms,等待写入完成}while(S7==0);}else  if(S6==0){delayms(10);if(S6==0){num2=read24byte(0x00)+20;delayms(5);}while(S6==0);SMGdat[0]=0x77;SMGdat[1]= table[num1/10];SMGdat[2]= table[num1%10];SMGdat[3]=0x40;SMGdat[4]=0x40;SMGdat[5]= 0x7C;		SMGdat[6]= table[num2/10];SMGdat[7]= table[num2%10];}if(S5==0){delayms(10);if(S5==0){write24byte(0x03,num3>>8); //写高8位到0x03delayms(5);  //等待5ms,等待写入完成write24byte(0x04,num3);//写低八位到0x04delayms(5);  //等待5ms,等待写入完成}while(S5==0);//松开按键}else	if(S4==0){delayms(10);if(S4==0){//读取int类型数据,读取高位,乘以256,再读取低位	num4H=read24byte(0x03);delayms(5);num4L=read24byte(0x04);delayms(5);num4=num4H*256+num4L;//将低位和高位合并起来}while(S4==0);//松开按键//分解出个位,十位,百位,千位的方法SMGdat[0]= table[num3/1000%10];SMGdat[1]= table[num3/100%10];SMGdat[2]= table[num3/10%10];SMGdat[3]=table[num3%10];SMGdat[4]=table[num4/1000%10];;SMGdat[5]=table[num4/100%10];;SMGdat[6]= table[num4/10%10];;SMGdat[7]= table[num4%10];}	if(tim1ms%500==0)  //500ms读取一次数据,刷新数据{in1dat=read_in1();in3dat=read_in3();}SMGdat[0]= 0x00;SMGdat[1]= table[in1dat/100%10];SMGdat[2]= table[in1dat/10%10];SMGdat[3]=table[in1dat%10];SMGdat[4]=0x00;SMGdat[5]=table[in3dat/100%10];SMGdat[6]= table[in3dat/10%10];SMGdat[7]= table[in3dat%10];}}//函数定义
//-----------------------------------------------/* Timer1 interrupt routine */
void tm1_isr() interrupt 3 using 1
{tim1ms++;disp();//1ms显示一次数码管
}
void Delay1ms()		//@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}void delayms(u16 tms)
{u16 i=0;for(i=0;iDelay1ms();}
}void sel(u8 x)  //选择四个分支哪一个?
{//背下来了吗?switch(x){case 0:P2=P2&0x1F;break;case LED:P2=P2&0x1F|0x80;break;case ULN:P2=P2&0x1F|0xA0;break;case COM:P2=P2&0x1F|0xC0;break;case ABC:P2=P2&0x1F|0xE0;break;}
}
void sysinit()//系统初始化,关闭所有的外部设备
{sel(LED);LEDbuf=0xFF;P0=LEDbuf;sel(0);sel(ULN);ULNbuf=0x00;P0=ULNbuf;sel(0);sel(COM);P0=0x00;sel(0);sel(ABC);P0=0xFF;sel(0);
}void disp()
{//背下来static u8 i=0;//消隐sel(COM);P0=0x00;sel(0);sel(ABC);P0=0xFF;sel(0);
//显示sel(COM);P0=T_COM[i];sel(0);sel(ABC);P0=~SMGdat[i];sel(0);i++;if(i>=8)i=0;
}

iic.c

/*程序说明: IIC总线驱动程序软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台 8051,12MHz日    期: 2011-8-9
*/#include "stc15.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;  
}//从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);}return da;    
}unsigned char read24byte(unsigned char addrtemp)
{unsigned char temp;IIC_Start();IIC_SendByte(SlaveAddrW); //是地址IIC_WaitAck();IIC_SendByte(addrtemp);IIC_WaitAck();IIC_Start();IIC_SendByte(SlaveAddrR); //读地址IIC_WaitAck();temp = IIC_RecByte();IIC_SendAck(1);          //send no ACKIIC_Stop();return temp;
}
void write24byte(unsigned char addrtemp,unsigned char datatemp)
{IIC_Start();IIC_SendByte(SlaveAddrW);IIC_WaitAck();IIC_SendByte(addrtemp);IIC_WaitAck();IIC_SendByte(datatemp);    IIC_WaitAck();IIC_Stop();
}unsigned char read_in1()
{unsigned char dat;IIC_Start();		 //总线起始信号IIC_SendByte(0x90); //字节写地址IIC_WaitAck();		 //等待应答IIC_SendByte(0x01); //发送控制字IIC_WaitAck();IIC_Start(); IIC_SendByte(0x91); //字节读地址IIC_WaitAck();dat=IIC_RecByte();IIC_SendAck(1); IIC_Stop(); return   dat;                  //处理读到的AIN的量
}
unsigned char read_in3()
{unsigned char dat;IIC_Start();		 //总线起始信号IIC_SendByte(0x90); //字节写地址IIC_WaitAck();		 //等待应答IIC_SendByte(0x03); //发送控制字IIC_WaitAck();IIC_Start(); IIC_SendByte(0x91); //字节读地址IIC_WaitAck();dat=IIC_RecByte();IIC_SendAck(1); IIC_Stop(); return   dat;                  //处理读到的AIN的量
}void write_dac(unsigned int dat)
{IIC_Start();IIC_SendByte(0x90);  //pcf8591写操作地址IIC_SendByte(0x40);  //选择dac输出通道,第6位为1打开D/AIIC_SendByte(dat);	  //选择要给pcf8591芯片的数字量IIC_WaitAck();	    IIC_Stop();   	      //停止通讯
}

iic.h

#define __IIC_Hvoid IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); unsigned char read24byte(unsigned char addrtemp);
void write24byte(unsigned char addrtemp,unsigned char datatemp);unsigned char read_in1();
unsigned char read_in3();
void write_dac(unsigned int dat);#endif

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...