找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1573|回复: 0
收起左侧

AT89C51单片机PCF8591AD转A换应用设计 Proteus仿真程序视频

[复制链接]
ID:623141 发表于 2020-6-23 17:05 | 显示全部楼层 |阅读模式
一、设计目的
1、学习并掌握IIC总线的工作原理
2、学习并掌握AD转换器工作原理;
3、学习并掌握AD转换程序设计方法;
4、学习并掌握串行通信程序设计;
二、实验设备
1、计算机;
2、单片机开发板;
3、Keil C51编程软件;
4、Proteus仿真软件;
三、设计内容
1、功能
(1)检测通道0电位器的模拟电压并显示(X.XX伏),
(2)将电压值通过串口发送到上位机串口调试助手显示,
(3)上位机串口调试助手显示(文本形式显示):“V:X.XX”回车(X.XX是电压值,逐行显示)
(4)上位机可以通过发送不同命令控制采集并显示哪个通道:通道0、通道1、通道2的模拟电压;
2、硬件电路原理图
3、设计程序(5号、宋体、单倍行距、分两栏,要求程序设计规范化,添加必要的说明和注释)

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

单片机源程序如下:
main.c中
/***************************************************************
* 实 验 名 :PCF8591AD转换串口实验
* 实验说明 :采用AD转换器采集模拟电压、转换为数字量、显示数字量。
* 连接方式 :
(1)P0口连接数码管的段控制:
CN3接CN16,A接P00,B接P01,C接P02,D接P03,E接P04,F接P05,G接P06,DP接P07
(2)P2.4-P2.7连接数码管的位控制:
CN1接CN17,PUT1接P24,PUT2接P25,PUT3接P26,PUT4接P27
(3)P1口连接矩阵按键:
CN16接CN14,KEY1到KEY8分别对应P10到P17
(3)PCF8591的SDA、SCL连接P2.1、P2.0:
PCF8591的IIC数据脚SDA连接P2.1;
PCF8591的IIC时钟脚SCL连接P2.0;
PCF8591的VCC连接开发板VCC;
PCF8591的GND连接开发板GND。
****************************************************************/
//包含文件
#include <reg51.h>
#include <intrins.h>            
#include <IIC.h>
//宏定义
#define BAUD 9600        //波特率设置,bps
#define FOSC 11059200L //晶振设置,默认使用11.0592M Hz
//#define FOSC 12000000L //晶振设置,使用12M Hz
//#define FOSC 24000000L //晶振设置,使用24M Hz

#define AddWr 0x90   //写数据地址
#define AddRd 0x91   //读数据地址

//IO接口定义
#define KEY_PORT P1
#define LED_PORT P0
sbit wela_1 = P2^4;
sbit wela_2 = P2^5;
sbit wela_3 = P2^6;
sbit wela_4 = P2^7;

//全局变量定义
extern bit ack;     //应答标志位
unsigned char key_value;
unsigned char qian,bai,shi,ge;
unsigned char CHX;     //作为通道选择
unsigned long readadc; //AD转换结果
unsigned char state;
//LED显示字模 0-F 共阳模式
unsigned code table[]={0Xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
/*******************************************************************************
* 函 数 名 :Delayms
* 函数功能 :实现 ms级的延时
* 输   入 :ms
* 输   出 :无
*******************************************************************************/
void Delayms(unsigned int ms)
{
    unsigned int i,j;
    for(i=0;i<ms;i++)
    #if FOSC == 11059200L
        for(j=0;j<114;j++);
    #elif FOSC == 12000000L
     for(j=0;j<123;j++);
    #elif FOSC == 24000000L
        for(j=0;j<249;j++);
    #else
        for(j=0;j<114;j++);
    #endif
}
/*******************************************************************************
* 函 数 名 :delay
* 函数功能 :延时子函数,短暂延时
* 输   入 :timer
* 输   出 :无
*******************************************************************************/
void delay(unsigned int timer)
{      
    while(timer--);
}
/*******************************************************************************
* 函 数 名 :ReadADC
* 函数功能 :读AD转值程序 输入参数 Chl 表示需要转换的通道,范围从0-3 返回值范围0-255
* 输   入 :Chl
* 输   出 :Val
*******************************************************************************/
unsigned char ReadADC(unsigned char Chl)
{
    unsignedchar Val;
    IIC_start();               //启动总线
    IIC_write(AddWr);          //发送器件地址,准备写
    if(ack==0) return(0);            
    IIC_write(0x40|Chl);       //发送器件子地址,Chl表示需要转换的通道
    if(ack==0) return(0);      
    IIC_start();      
    IIC_write(AddRd);         //发送器件地址,准备读
    if(ack==0) return(0);
    Val=IIC_read();             //读取AD转换结果
    IIC_ACK(1);                 //发送非应答位  
    IIC_stop();                 //结束总线   
    return(Val);               //返回AD转换结果
}
/*******************************************************************************
* 函 数 名 :WriteDAC
* 函数功能 :往DAC通道写数据,进行DA转换
* 输   入 :dat
* 输   出 :
*******************************************************************************/
bit WriteDAC(unsigned char dat)
{
    IIC_start();           //启动总线
    IIC_write(AddWr);      //发送器件地址,准备写
    if(ack==0)
        return(0);
    IIC_write(0x40);       //发送器件子地址
    if(ack==0)
        return(0);
    IIC_write(dat);        //发送数据,进行DA转换
    if(ack==0)
        return(0);
    IIC_stop();  
}
/*******************************************************************************
* 函 数 名 :LEDdisplay
* 函数功能 :循环显示各个位上的数据
* 输   入 :num要显示的数据
* 输   出 :无
*******************************************************************************/
void LEDdisplay()
{
    wela_1 = 1;   //关闭所有数码管
    wela_2 = 1;
    wela_3 = 1;
    wela_4 = 1;

    wela_4=0;  //显示千位
    LED_PORT=table[qian];
    Delayms(1);
    LED_PORT = 0xff;
    wela_4=1;
   
    wela_3=0;  //显示百位
    LED_PORT=table[bai] & 0x7f;
    Delayms(1);
    LED_PORT = 0xff;
    wela_3=1;
   
    wela_2=0;  //显示十位
    LED_PORT=table[shi];
    Delayms(1);
    LED_PORT = 0xff;
    wela_2=1;
   
    wela_1=0;  //显示个位
    LED_PORT=table[ge];
    Delayms(1);
    LED_PORT = 0xff;
}
/*******************************************************************************
* 函 数 名 :KeyScan
* 函数功能 :4*4键盘扫描
* 输   入 :无
* 输   出 :num 获取的键值,若没有键值则返回0xff
*******************************************************************************/
unsigned char KeyScan()
{
    unsigned char temp,num;
    num = 0xff;
    KEY_PORT=0xfe;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xee:num=1;
                   break;
                case 0xde:num=2;
                   break;
                case 0xbe:num=3;
                   break;
                case 0x7e:num=4;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xfd;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xed:num=5;
                   break;
                case 0xdd:num=6;
                   break;
                case 0xbd:num=7;
                   break;
                case 0x7d:num=8;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xfb;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xeb:num=9;
                   break;
                case 0xdb:num=10;
                   break;
                case 0xbb:num=11;
                   break;
                case 0x7b:num=12;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xf7;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xe7:num=13;
                   break;
                case 0xd7:num=14;
                   break;
                case 0xb7:num=15;
                   break;
                case 0x77:num=16;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }
    return num;
}

/*******************************************************************************
* 函 数 名 :UsartConfiguration
* 函数功能 :串口设置
* 输   入 :无
* 输   出 :无
*******************************************************************************/
void UsartConfiguration()
{
    SCON = 0X50;    //设置为工作方式1:10位异步收发器
    TMOD |= 0x20;   //设置计数器工作方式2:8位自动重装计数器   
    PCON = 0X80;    //波特率加倍:SMOD =1
    TH1 = 256-(FOSC/12/32/(BAUD/2)); //计算定时器1初值
    TL1 = 256-(FOSC/12/32/(BAUD/2));
    TR1 = 1;//启动定时器T1
    ES=1;   //开串口中断
    EA = 1; //开总中断
}

/*******************************************************************************
* 函 数 名 :UsartSend
* 函数功能 :串口发送电压
* 输   入 :无
* 输   出 :无
*******************************************************************************/
void UsartSend()
{
    //发送 V
        TI = 0;          //清除发送中断标志位TI
        SBUF='V';       //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成   
    //发送 :
        TI = 0;          //清除发送中断标志位TI
        SBUF=':';       //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
    //发送电压整数
        TI = 0;          //清除发送中断标志位TI
        SBUF=readadc%1000/100+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        //发送小数点
        TI = 0;          //清除发送中断标志位TI
        SBUF='.';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);     
    //发送电压十分位
        TI = 0;          //清除发送中断标志位TI
        SBUF=readadc%100/10+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
  //等待发送数据完成
   
    //发送电压百分位
        TI = 0;          //清除发送中断标志位TI
        SBUF=readadc%10+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        
    //发送换行符
        TI = 0;          //清除发送中断标志位TI
        SBUF='\n'; //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        TI=0;   
            
}
/*******************************************************************************
* 函 数 名 :main
* 函数功能 :主函数
* 输   入 :无
* 输   出 :无
*******************************************************************************/
void main()
{   
    int count = 0;
    state =1;
    UsartConfiguration();
    while(1)
    {
        key_value=KeyScan();
        if(key_value!=0xff)
            state=key_value;
        if(state==1)       //按键1按下,选择通道0,即电位器调节实验      
            CHX=0;         
        else if(state==2)   //按键2按下,选择通道1,即光敏电阻实验
            CHX=1;
        else if(state==3)   //按键3按下,选择通道2,即热敏电阻实验
            CHX=2;
        else if(state==4)   //按键4按下,选择通道3,接地
            CHX=3;
        if(count >= 200)    //采样周期1s
        {
            //readadc=ReadADC(CHX)/256*5*100;
            readadc=ReadADC(CHX)*5.0*100/255;   //调用ReadADC函数读取AD转换结果      
            UsartSend();//发送电压到串口
            count = 0;
        }      
        qian=readadc/1000;         //显示AD转换结果
        bai=readadc%1000/100;
        shi=readadc%100/10;
        ge=readadc%10;            
        LEDdisplay();      
        count++;
    }
}


/*******************************************************************************
* 函 数 名 :UsartInt
* 函数功能 :串口中断服务函数
* 输   入 :无
* 输   出 :无
*******************************************************************************/
void UsartInt() interrupt 4
{
    char receiveData;   //存放接收的函数
    if(RI == 1)             //RI=1说明是接收到数据产生的中断
    {
        receiveData=SBUF; //从接收SBUF中取得接收到的数据
    //判断接受值,改变读取通道     
        switch (receiveData)
        {
        case '0' :state = 1;break;
        case '1' :state = 2;break;
        case '2' :state = 3;break;
        default :break;
        }           
        RI = 0;           //清除接收中断标志位RI
    }   
}/***************************************************************
* 实 验 名 :PCF8591AD转换串口实验
* 实验说明 :采用AD转换器采集模拟电压、转换为数字量、显示数字量。
* 连接方式 :
(1)P0口连接数码管的段控制:
CN3接CN16,A接P00,B接P01,C接P02,D接P03,E接P04,F接P05,G接P06,DP接P07
(2)P2.4-P2.7连接数码管的位控制:
CN1接CN17,PUT1接P24,PUT2接P25,PUT3接P26,PUT4接P27
(3)P1口连接矩阵按键:
CN16接CN14,KEY1到KEY8分别对应P10到P17
(3)PCF8591的SDA、SCL连接P2.1、P2.0:
PCF8591的IIC数据脚SDA连接P2.1;
PCF8591的IIC时钟脚SCL连接P2.0;
PCF8591的VCC连接开发板VCC;
PCF8591的GND连接开发板GND。
****************************************************************/
//包含文件
#include <reg51.h>
#include <intrins.h>            
#include <IIC.h>
//宏定义
#define BAUD 9600        //波特率设置,bps
#define FOSC 11059200L //晶振设置,默认使用11.0592M Hz
//#define FOSC 12000000L //晶振设置,使用12M Hz
//#define FOSC 24000000L //晶振设置,使用24M Hz

#define AddWr 0x90   //写数据地址
#define AddRd 0x91   //读数据地址

//IO接口定义
#define KEY_PORT P1
#define LED_PORT P0
sbit wela_1 = P2^4;
sbit wela_2 = P2^5;
sbit wela_3 = P2^6;
sbit wela_4 = P2^7;

//全局变量定义
extern bit ack;     //应答标志位
unsigned char key_value;
unsigned char qian,bai,shi,ge;
unsigned char CHX;     //作为通道选择
unsigned long readadc; //AD转换结果
unsigned char state;
//LED显示字模 0-F 共阳模式
unsigned code table[]={0Xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
/*******************************************************************************
* 函 数 名 :Delayms
* 函数功能 :实现 ms级的延时
* 输   入 :ms
* 输   出 :无
*******************************************************************************/
void Delayms(unsigned int ms)
{
    unsigned int i,j;
    for(i=0;i<ms;i++)
    #if FOSC == 11059200L
        for(j=0;j<114;j++);
    #elif FOSC == 12000000L
     for(j=0;j<123;j++);
    #elif FOSC == 24000000L
        for(j=0;j<249;j++);
    #else
        for(j=0;j<114;j++);
    #endif
}
/*******************************************************************************
* 函 数 名 :delay
* 函数功能 :延时子函数,短暂延时
* 输   入 :timer
* 输   出 :无
*******************************************************************************/
void delay(unsigned int timer)
{      
    while(timer--);
}
/*******************************************************************************
* 函 数 名 :ReadADC
* 函数功能 :读AD转值程序 输入参数 Chl 表示需要转换的通道,范围从0-3 返回值范围0-255
* 输   入 :Chl
* 输   出 :Val
*******************************************************************************/
unsigned char ReadADC(unsigned char Chl)
{
    unsignedchar Val;
    IIC_start();               //启动总线
    IIC_write(AddWr);          //发送器件地址,准备写
    if(ack==0) return(0);            
    IIC_write(0x40|Chl);       //发送器件子地址,Chl表示需要转换的通道
    if(ack==0) return(0);      
    IIC_start();      
    IIC_write(AddRd);         //发送器件地址,准备读
    if(ack==0) return(0);
    Val=IIC_read();             //读取AD转换结果
    IIC_ACK(1);                 //发送非应答位  
    IIC_stop();                 //结束总线   
    return(Val);               //返回AD转换结果
}
/*******************************************************************************
* 函 数 名 :WriteDAC
* 函数功能 :往DAC通道写数据,进行DA转换
* 输   入 :dat
* 输   出 :
*******************************************************************************/
bit WriteDAC(unsigned char dat)
{
    IIC_start();           //启动总线
    IIC_write(AddWr);      //发送器件地址,准备写
    if(ack==0)
        return(0);
    IIC_write(0x40);       //发送器件子地址
    if(ack==0)
        return(0);
    IIC_write(dat);        //发送数据,进行DA转换
    if(ack==0)
        return(0);
    IIC_stop();  
}
/*************************************
* 函 数 名 :LEDdisplay
* 函数功能 :循环显示各个位上的数据
* 输   入 :num要显示的数据
* 输   出 :无
*************************************/
void LEDdisplay()
{
    wela_1 = 1;   //关闭所有数码管
    wela_2 = 1;
    wela_3 = 1;
    wela_4 = 1;

    wela_4=0;  //显示千位
    LED_PORT=table[qian];
    Delayms(1);
    LED_PORT = 0xff;
    wela_4=1;
   
    wela_3=0;  //显示百位
    LED_PORT=table[bai] & 0x7f;
    Delayms(1);
    LED_PORT = 0xff;
    wela_3=1;
   
    wela_2=0;  //显示十位
    LED_PORT=table[shi];
    Delayms(1);
    LED_PORT = 0xff;
    wela_2=1;
   
    wela_1=0;  //显示个位
    LED_PORT=table[ge];
    Delayms(1);
    LED_PORT = 0xff;
}
/*************************************
* 函 数 名 :KeyScan
* 函数功能 :4*4键盘扫描
* 输   入 :无
* 输   出 :num 获取的键值,若没有键值则返回0xff
*************************************/
unsigned char KeyScan()
{
    unsigned char temp,num;
    num = 0xff;
    KEY_PORT=0xfe;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xee:num=1;
                   break;
                case 0xde:num=2;
                   break;
                case 0xbe:num=3;
                   break;
                case 0x7e:num=4;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xfd;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xed:num=5;
                   break;
                case 0xdd:num=6;
                   break;
                case 0xbd:num=7;
                   break;
                case 0x7d:num=8;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xfb;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xeb:num=9;
                   break;
                case 0xdb:num=10;
                   break;
                case 0xbb:num=11;
                   break;
                case 0x7b:num=12;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }

    KEY_PORT=0xf7;
    temp=KEY_PORT;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        Delayms(5); //延时消抖
        temp=KEY_PORT;
        temp=temp&0xf0;
        while(temp!=0xf0)
        {
            temp=KEY_PORT;
            switch(temp)
            {
                case 0xe7:num=13;
                   break;
                case 0xd7:num=14;
                   break;
                case 0xb7:num=15;
                   break;
                case 0x77:num=16;
                   break;
            }
            while(temp!=0xf0)
            {
                temp=KEY_PORT;
                temp=temp&0xf0;
            }
        }
    }
    return num;
}

/*************************************
* 函 数 名 :UsartConfiguration
* 函数功能 :串口设置
* 输   入 :无
* 输   出 :无
*************************************/
void UsartConfiguration()
{
    SCON = 0X50;    //设置为工作方式1:10位异步收发器
    TMOD |= 0x20;   //设置计数器工作方式2:8位自动重装计数器   
    PCON = 0X80;    //波特率加倍:SMOD =1
    TH1 = 256-(FOSC/12/32/(BAUD/2)); //计算定时器1初值
    TL1 = 256-(FOSC/12/32/(BAUD/2));
    TR1 = 1;//启动定时器T1
    ES=1;   //开串口中断
    EA = 1; //开总中断
}

/*************************************
* 函 数 名 :UsartSend
* 函数功能 :串口发送电压
* 输    入 :无
* 输   出 :无
*************************************/
void UsartSend()
{
    //发送 V
        TI = 0;          //清除发送中断标志位TI
        SBUF='V';       //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成   
    //发送 :
        TI = 0;          //清除发送中断标志位TI
        SBUF=':';       //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
    //发送电压整数
        TI = 0;          //清除发送中断标志位TI
        SBUF=readadc%1000/100+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        //发送小数点
        TI = 0;          //清除发送中断标志位TI
        SBUF='.';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);     
    //发送电压十分位
        TI = 0;           //清除发送中断标志位TI
        SBUF=readadc%100/10+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
  //等待发送数据完成
   
    //发送电压百分位
        TI = 0;          //清除发送中断标志位TI
        SBUF=readadc%10+'0';//收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        
    //发送换行符
        TI = 0;          //清除发送中断标志位TI
        SBUF='\n'; //收到的数据放入到发送SBUF,启动串口发送
        while(!TI);       //等待发送数据完成
        TI=0;   
            
}
/*************************************
* 函 数 名 :main
* 函数功能 :主函数
* 输   入 :无
* 输   出 :无
*************************************/
void main()
{   
    int count = 0;
    state =1;
    UsartConfiguration();
    while(1)
    {
        key_value=KeyScan();
        if(key_value!=0xff)
            state=key_value;
        if(state==1)       //按键1按下,选择通道0,即电位器调节实验      
            CHX=0;         
        else if(state==2)   //按键2按下,选择通道1,即光敏电阻实验
            CHX=1;
        else if(state==3)   //按键3按下,选择通道2,即热敏电阻实验
            CHX=2;
        else if(state==4)   //按键4按下,选择通道3,接地
            CHX=3;
        if(count >= 200)    //采样周期1s
        {
            //readadc=ReadADC(CHX)/256*5*100;
            readadc=ReadADC(CHX)*5.0*100/255;   //调用ReadADC函数读取AD转换结果      
            UsartSend();//发送电压到串口
            count = 0;
        }      
        qian=readadc/1000;         //显示AD转换结果
        bai=readadc%1000/100;
        shi=readadc%100/10;
        ge=readadc%10;            
        LEDdisplay();      
        count++;
    }
}


/*************************************
* 函 数 名 :UsartInt
* 函数功能 :串口中断服务函数
* 输   入 :无
* 输   出 :无
*************************************/
void UsartInt() interrupt 4
{
    char receiveData;   //存放接收的函数
    if(RI == 1)             //RI=1说明是接收到数据产生的中断
    {
        receiveData=SBUF; //从接收SBUF中取得接收到的数据
    //判断接受值,改变读取通道     
        switch (receiveData)
        {
        case '0' :state = 1;break;
        case '1' :state = 2;break;
        case '2' :state = 3;break;
        default :break;
        }           
        RI = 0;           //清除接收中断标志位RI
    }   
}



四、本任务中的几个功能如何实现?(说明设计思路)
设计思路:
1.       首先借助例程,实验采集电压,但例程所给为八个二进制位,不代表电压值,需要经过公式转化,小数位的显示,可以采用电压值扩大100倍,给第二位数码管后加小数点,实现了显示2个电压。
2.       串口发送电压值,移植上次课例程,实现相应ASCII的转化。
3.       用上位机发送数据来实现控制检测通道,采用中断法接受串口数据,用switch来判断接收值,并改变state状态,实现通道的切换。
51hei.png

全部资料51hei下载地址:
PCF8591AD转换应用设计.rar (10.27 MB, 下载次数: 27)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表