蓝桥杯单片机组-19 AD转换

要求

在单片机综合训练平台上,实现以下功能:

1.IIC总线底层驱动引入文件

2.光敏电阻rd1接到PCF8591的AIN1通道,可调电阻rb2接到PCF8591的AIN3通道

3.系统上电后,循环采样AIN1和AIN3通道的电压,并将A/D转换结果读出换算成对应的实际电压值,保留2位小数,单位为V

4.数码管显示采样的实时电压

代码

题目

    系统上电后,循环采样AIN1和AIN3通道的电压,并将A/D转换结果读出,换算成对应的实际电压值,保留2位小数,单位为V 

    一共3个步骤:采样数据 + 换算电压 + 显示电压

   所以需要定义3个变量:

//-----------------------------------------------
unsigned char adc1_value = 0;    //AIN1的采样数据
float adc1_volt = 0;            //AIN1的换算电压
unsigned int smg1_volt = 0;      //AIN1的显示电压

unsigned char adc3_value = 0;    //AIN3的采样数据
float adc3_volt = 0;            //AIN3的换算电压
unsigned int smg3_volt = 0;      //AIN3的显示电压

它们的相关函数为:

//=============采样光敏电阻和可调电阻的电压=============
void Read_AIN1_AIN3()
{
  adc1_value = Read_PCF8591_ADC(1);
  adc1_volt = adc1_value * (5.0 / 255);
  smg1_volt = adc1_volt * 100;
  
  adc3_value = Read_PCF8591_ADC(3);
  adc3_volt = adc3_value * (5.0 / 255);
  smg3_volt = adc3_volt * 100;
}

 最重要的是电压采样处理函数!!!

    涉及A/D转换!!!

    ain指的是在哪个通道

//===============PCF8591电压采样处理函数===============
unsigned char Read_PCF8591_ADC(unsigned char ain)
{
  unsigned char tmp;
  IIC_Start();          
  IIC_SendByte(0x90);    //PCF8591的写设备地址 
  IIC_WaitAck();        
  if(ain == 1)
  {
    IIC_SendByte(0x01); //通道1,光敏电阻电压
  }
  else if(ain == 3)
  {
    IIC_SendByte(0x03); //通道3,可调电阻电压
  }    
  IIC_WaitAck();              
  IIC_Stop(); 
  
  DisplaySMG_ADC();      //等待电压转换完成
  
  IIC_Start();                  
  IIC_SendByte(0x91);   //PCF8591的读设备地址
  IIC_WaitAck();                 
  tmp = IIC_RecByte();   //读出AD采样数据
  IIC_SendAck(1);         //产生非应答信号                 
  IIC_Stop();
  return tmp;
}

完整代码

====================================================*/
#include "reg52.h"
#include "iic.h"
//定义动态显示中单个数码管点亮时长
#define TSMG  500
//-------共阳数码管的段码编码表(无小数点)--------
//0 1 2 3 4 5 6 7 8 9 A B C D E F - .
unsigned char code SMG_NoDot[18]={0xc0,0xf9,
    0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
    0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
//-------共阳数码管的段码编码表(带小数点)--------
//0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
unsigned char code SMG_Dot[10]={0x40,0x79,
    0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//-----------------------------------------------
unsigned char adc1_value = 0;    //AIN1的采样数据
float adc1_volt = 0;            //AIN1的换算电压
unsigned int smg1_volt = 0;      //AIN1的显示电压
unsigned char adc3_value = 0;    //AIN3的采样数据
float adc3_volt = 0;            //AIN3的换算电压
unsigned int smg3_volt = 0;      //AIN3的显示电压
//==============数码管动态显示专用延时函数=============
void DelaySMG(unsigned int t)
{
  while(t--);
}
//==================设置选通的锁存器===================
void Set_HC573(unsigned char channel, unsigned char dat)
{
  P0 = dat;                      //待设置数据
  switch(channel)                //选通锁存器
  {
    case 4:
      P2 = (P2 & 0x1f) | 0x80;  //Y4输出0,LED控制
    break;
    case 5:
      P2 = (P2 & 0x1f) | 0xa0;  //Y5输出0,蜂鸣器和继电器控制
    break;
    case 6:
      P2 = (P2 & 0x1f) | 0xc0;  //Y6输出0,数码管位选
    break;
    case 7:
      P2 = (P2 & 0x1f) | 0xe0;  //Y7输出0,数码管段码
    break;
    case 0:
      P2 = (P2 & 0x1f) | 0x00;  //所有锁存器不选择
    break;
  }
  P2 = (P2 & 0x1f) | 0x00;      //设置完成,关闭全部锁存器
}
//=================单个数码管动态显示=================
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
  Set_HC573(6, 0x01 << pos);    //数码管的段位
  Set_HC573(7, value);          //数码管显示内容
  DelaySMG(TSMG);                //数码管点亮时长
  Set_HC573(6, 0x01 << pos);        
  Set_HC573(7, 0xff);            //消隐
}
//=================全部数码管静态显示=================
void DisplaySMG_All(unsigned char value)
{
  Set_HC573(6, 0xff);    //使能所有数码管
  Set_HC573(7, value);  //数码管显示内容  
}
//===================电压值显示函数===================
void DisplaySMG_ADC()
{
  //数码管右起第0位
  DisplaySMG_Bit(7,SMG_NoDot[smg1_volt  % 10]);
  //数码管右起第1位
  DisplaySMG_Bit(6,SMG_NoDot[(smg1_volt / 10) % 10]);    
  //数码管右起第2位
  DisplaySMG_Bit(5,SMG_Dot[smg1_volt / 100]);        

  //数码管右起第5位
  DisplaySMG_Bit(2,SMG_NoDot[smg3_volt  % 10]);
  //数码管右起第6位
  DisplaySMG_Bit(1,SMG_NoDot[(smg3_volt / 10) % 10]);    
  //数码管右起第7位
  DisplaySMG_Bit(0,SMG_Dot[smg3_volt / 100]);    
}
//===============PCF8591电压采样处理函数===============
unsigned char Read_PCF8591_ADC(unsigned char ain)
{
  unsigned char tmp;
  IIC_Start();          
  IIC_SendByte(0x90);    //PCF8591的写设备地址 
  IIC_WaitAck();        
  if(ain == 1)
  {
    IIC_SendByte(0x01); //通道1,光敏电阻电压
  }
  else if(ain == 3)
  {
    IIC_SendByte(0x03); //通道3,可调电阻电压
  }    
  IIC_WaitAck();              
  IIC_Stop(); 
  
  DisplaySMG_ADC();      //等待电压转换完成
  
  IIC_Start();                  
  IIC_SendByte(0x91);   //PCF8591的读设备地址
  IIC_WaitAck();                 
  tmp = IIC_RecByte();   //读出AD采样数据
  IIC_SendAck(1);         //产生非应答信号                 
  IIC_Stop();
  return tmp;
}
//=============采样光敏电阻和可调电阻的电压=============
void Read_AIN1_AIN3()
{
  adc1_value = Read_PCF8591_ADC(1);
  adc1_volt = adc1_value * (5.0 / 255);
  smg1_volt = adc1_volt * 100;
  
  adc3_value = Read_PCF8591_ADC(3);
  adc3_volt = adc3_value * (5.0 / 255);
  smg3_volt = adc3_volt * 100;
}
//=====================系统初始化=====================
void Init_sys()
{
  Set_HC573(0, 0x00);        //关闭所有锁存器
  Set_HC573(5, 0x00);        //关闭蜂鸣器和继电器
  Set_HC573(4, 0xff);        //关闭全部LED灯
  DisplaySMG_All(0xff);      //关闭全部数码管
}
//=======================主函数=======================
void main()
{
  Init_sys();               //系统初始化
  while(1)
  {
    Read_AIN1_AIN3();      //循环采样电压
    DisplaySMG_ADC();      //动态刷新数码管
  }
}
//========================END=========================

总结

1.A/D转换需要定义3个变量,需要AD转换函数、采样函数

2.涉及小数,注意数码管的显示函数

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值