【换取手持数字示波器】+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,所以测量结果与预想的有一些出入,但与万用表实际测量的电压值是匹配的。