【换取手持数字示波器】+51单片机使用ADS1115实现ADC转换
之前用的是Arduino方式实现了ADS1115实现ADC转换功能,使用的是第三方现成的库函数。这次,使用51单片机完成这个ADC转换的功能。需要自己编写处理函数。51单片机用的是STC的IAP15W4K58S4芯片,工作主频11.0592MHz,工作电压3.3V。
搭建的电路原理图:

主程序如下:
//////////////////////////////////////////////////////////////////////////////////
//测试硬件: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;
}实测图:
由于导线电阻的存在,ADS1115的实际工作电压不是3.3V,所以测量结果与预想的有一些出入,但与万用表实际测量的电压值是匹配的。
我要赚赏金
