这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+51单片机使用ADS1115实现ADC转换

共3条 1/1 1 跳转至

【换取手持数字示波器】+51单片机使用ADS1115实现ADC转换

专家
2024-05-27 12:14:23   被打赏 45 分(兑奖)     打赏

【换取手持数字示波器】+51单片机使用ADS1115实现ADC转换

之前用的是Arduino方式实现了ADS1115实现ADC转换功能,使用的是第三方现成的库函数。这次,使用51单片机完成这个ADC转换的功能。需要自己编写处理函数。51单片机用的是STC的IAP15W4K58S4芯片,工作主频11.0592MHz,工作电压3.3V。

搭建的电路原理图:

图片1.png

主程序如下:


////////////////////////////////////////////////////////////////////////////////// 
//测试硬件:STC51
//1.3寸TFT_ST7735液晶驱动 SPI 屏
// 工作主频:11.0592MHz 
// 工作电压:3.3V
//********************************************************************************
#include <stc15.h>
#include<intrins.h>
#include<string.h>
//#include <delay.h>     //延时模块
#include <debug.h>     //
#include <lcd.h>
#include <ads1115.h>
main() {
    int result = 0;
    float v=0.0;
    char buff[32] = {'\0'};
    unsigned char cnt=0;
    
    // P0口准双向,弱拉
    P0M0 = 0x00;
    P0M1 = 0x00;
    // P1口准双向,弱拉
    P1M0 = 0x00;
    P1M1 = 0x00;
    
    UartInit();
lcd_initial();
//bl=1;
    
    LCD_Clear(BLACK); //清屏
    Show_Font24(0,  8, WHITE, BLACK,(uchar *)"  测试ADS1115  ");
    Show_Font24(0,  36, WHITE, BLACK,(uchar *)"---------------");
    
    Show_Font24(10,  70, WHITE, BLACK,(uchar *)"参考电压:4.096");
    Show_Font24(10,  110, WHITE, BLACK,(uchar *)"ADC上限:32767");
    
    Show_Font24(10,  150, WHITE, BLACK,(uchar *)"AIN0:");
    Show_Font24(10,  190, WHITE, BLACK,	(uchar *)"电 压:");
    while(1)  {
        result = ADS1115(1);
        // 显示测试结果
        lcd_printfLongFont24(90, 150, WHITE, BLACK, result); 
        // 转换为电压值
        
        v = 4.096 * result / 32767;
        result = v;
        Show_Font24_Char(90,  190, WHITE, BLACK, (result%1000)+'0'); 
        Show_Font24_Char(106, 190, WHITE, BLACK, '.'); 
        result = v*1000-result*1000;
        lcd_printfLongFont24(122, 190, WHITE, BLACK, result%1000); 
        
        delay_ms(2000);
        
            
    }
 }


ADS1115的处理程序:


#include "ads1115.h"
#include "lcd.h"
// 传送数据的缓存区
unsigned char Writebuff[4];
//char VCC = 4.78;                   //VCC,电压参考值
//int D_ADS;                         //转换的数字量
/****************************开始ADC通信信号*************************/
void StartADcom() {
    SDA =0;
    SCL=1;
    delay_us(100);
    SDA =1;
    delay_us(20);
    SDA =0;
    SCL=0;  
    delay_us(10);
}
/***********************************停止ADC通信信号**************************************/
void StopADcom() {
    SDA=0;
    delay_us(10);
    SCL=1;
    delay_us(20);
    SDA=1;
    delay_us(10);
}
/********************************单字节I2C传输**************************************/
void Send_Byte(unsigned char byte) {
    unsigned char i;
    
    // 逐位传送
    for(i=0;i<8;i++) {
        if((byte<<i)&0x80)
            SDA=1;
        else
            SDA=0;
        delay_us(5);
        SCL=1;
        delay_us(10);
        SCL=0;       
        delay_us(10);             
    }
    delay_us(5);
    SDA=1;
    delay_us(5);
    SCL=1;
    delay_us(10);
    SCL=0;
    delay_us(10);  
}
/*************************读取一个字节*****************************/
unsigned char Read_Byte() {
    unsigned char temp=0;
    unsigned char i;
    for(i=0;i<8;i++) {
        temp=temp<<1;           //shift left to receive next bit
        SCL=0;                        //set clock high
        delay_us(10);
        SCL=1;
        _nop_();
        delay_us(5);
        if(SDA==1)                //check if Data=high
        temp|=0x01;            //yes - set bit high
        _nop_();
        delay_us(10);               
    }
    SCL=0;
    delay_us(5);
    SDA=0;
    delay_us(5);
    SCL=1;
    delay_us(20);
    SCL=0;
    delay_us(5);
    SDA=1;
    return temp;
}
/**************************配置ADC转换芯片*************************************/
// channel_x : 通道
void Confige1115(unsigned char channel_x) { 
    unsigned char i=0;
    unsigned char a_channel;
    switch(channel_x) {
        case 1:              
            a_channel=0x42;               
            break;       
        case 2:              
            a_channel=0x52;               
            break;
        case 3:              
            a_channel=0x62;               
            break;
        case 4:              
            a_channel=0x72;               
            break;
        default:
            break;       
    }
    Writebuff[0] =ADDRESS_0;        // AIN0的地址    
    Writebuff[1] =0x01;             // Pointer
    Writebuff[2]=a_channel;         // COMP_QUE_2 + DR
    Writebuff[3] =0x83;             // PGA_1 + MODE_1;  4.096V 
    SCL=1;
    StartADcom();
    for(i=0;i<4;i++) {
    Send_Byte(Writebuff[i]);
    delay_us(20);
    }
    StopADcom();
}
/********指向转换结果寄存器**************************/
void Pointregister(void) {
    unsigned char i=0;
    Writebuff[0] =ADDRESS_0;        // AIN0的地址    
    Writebuff[1] =0x00;            
    SCL=1;
    StartADcom();
    for(i=0;i<2;i++) {
        Send_Byte(Writebuff[i]);
        delay_us(20);
    }
    StopADcom();
    delay_us(10);
}
/*****************读取ADC转换结果*******************/
unsigned int Read1115(void) {
    unsigned char   ResultL,ResultH;
    unsigned int    Result;
    Writebuff[0] =0x91;      
    SCL=1;
    StartADcom();
    delay_us(10);
    Send_Byte(Writebuff[0]);
    delay_us(20);
    ResultH=Read_Byte();
    delay_us(10);
    ResultL=Read_Byte();        
    StopADcom();
    Result=ResultH*256+ResultL;   
    return   Result;
}
/*****ADC模拟量采集转化为数字量*********/
// 使用的配置:参考电压:4.096V, 转换范围:0~0x7FFF(32767)
// 参数:channel_Ad:通道编号(1 ~ 4,对应 AIN0 ~ AIN3)
unsigned int ADS1115(unsigned char channel_Ad) {
    unsigned int adc_value;
    Confige1115(channel_Ad);
    delay_ms(1);
    Pointregister();               
    delay_us(10);
    adc_value=Read1115();               
    return   adc_value;
}


实测图:

图片2.png由于导线电阻的存在,ADS1115的实际工作电压不是3.3V,所以测量结果与预想的有一些出入,但与万用表实际测量的电压值是匹配的。


高工
2024-05-27 14:17:06     打赏
2楼

谢谢分享


高工
2024-05-31 04:53:34     打赏
3楼

感谢楼主分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]