蓝桥杯单片机记录_第八篇_ADC(模数转换)

驱动

驱动用的是IIC

#include <iic.h>
#include "intrins.h"

//这里需要在原有驱动的基础上复制7次
#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_();_nop_();_nop_();_nop_();_nop_();_nop_();}

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

//总线启动条件
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;
}

//等待应答
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) 
  { 
   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;
}

寄存器

这个是控制读或者写操作,在寄存器的最后一位是控制读还是写,1是读,0是写
前4位是固定的,当为1001时是选中PCF8591

在这里插入图片描述 这个选执行那个通道,一般就考两个,一个是光敏电阻,一个是滑动变阻器
在这里插入图片描述

光敏电阻:

在这里插入图片描述

滑动变阻器:

在这里插入图片描述
可以看出一个是通道1,一个是通道3

读函数代码


/**
* @Function       adc_read
* @Description:   adc转换
* @param          void 
* @return         dat
*/

unsigned char adc_read(void)
{
 unsigned char dat=0IIC_Start();         //启动
 IIC_SendByte(0X90);  //调用PCF8591,并且为写操作
 IIC_WaitAck();       //等待
 IIC_SendByte(0X03);  //0X03是滑动变阻器,0X01是光敏电阻
 IIC_WaitAck();       //等待
 
 IIC_Start();         //再次启动
 IIC_SendByte(0X91);  //调用PCF8591,并且执行读操作
 IIC_WaitAck();       //等待
 dat=IIC_RecByte();   //把读出来的数据给dat
 
 IIC_Stop();          //停止
 
 return dat;         //返回          
}

main.c

1. 正常读值 范围:0~255 (8位)

unsigned char adc_dat;

adc_dat=adc_read();

/******数码管显示******/
dspbuf[0]=adc_dat/100;
dspbuf[1]=adc_dat%100/10;
dspbuf[2]=adc_dat%10;

2. 转换为过千

long adc_dat;
unsigned int v;

adc_dat=adc_read();
v=(unsigned int)(adc_dat*10000/255);

/******数码管显示******/
dspbuf[0]=v/10000;
dspbuf[1]=v%10000/1000;
dspbuf[2]=v%1000/100;
dspbuf[3]=v%100/10;
dspbuf[4]=v%10;

3. 转换为0~5V电压,保留两位小数

long adc_dat;
unsigned int v;


adc_dat=adc_read();
v=(unsigned int)(adc_dat*500/255);


/******数码管显示******/
dspbuf[0]=v/100+10;
dspbuf[1]=v%100/10;
dspbuf[2]=v%10;

如果读数据读的太快会导致数码管显示不佳,可以用定时器让其200ms读一次数据即可

  • 17
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值