Подумав об ацп и почитав что ацп в stm32f103 оставляет желать лучше и нашел ads1115. Писал в Keil.
Заказал с алиэкспреса тут за 102 руб.
Подключив на макетке,начал читать про ads1115 : Что мы имеем внутри. Ну конечно это 16 битный ацп со встроенным опорником,потом выбор каналов измерения : 4 канала относительно земли или дифференциальный ( но измерение в двоичной математике,то есть при ниже половины напряжении добавляется в самом старшем бите 1 и преобразуется уже в коде).
Что относительно измерения относительно общего провода,то код оцифровки от 0 до 7FFF .
Ну и конечно же выбор усиления входного сигнала,что дает нужную точность измерения. Но нельзя подавать на вход напряжение выше напряжения питания+0.3 B.
Исходник
Первая функция инициализация ads1115 для работы с каналом A0, предел измерения 2.048 В , непрерывное преобразование.
Вторая функция считываем значение ацп 16 битное значение.
Дополню еще что когда получаете с ацп значение и измеряя напряжение относительно нуля(общего провода),если значение больше 7FFF ,то значение равно нулю. Встретился когда измерял напряжение общего провода и было влиянение дрейфа значения.
ads1115.h
#ifndef ads1115 #define ads1115 #include "stm32f10x.h" // 10010000=0x90 - write 10010001=0x91- read #define address_ad1115_w 0x90 #define address_ad1115_r 0x91 extern void init_ads1115(void); extern unsigned int read_ads1115(void); #endif
ads1115.c
#include "ads1115.h" void init_ads1115(void) { unsigned int ui_init_ads1115=0x4483; unsigned char uc_init_MSB=0; unsigned char uc_init_LSB=0; uc_init_LSB=ui_init_ads1115&0xff; uc_init_MSB=(ui_init_ads1115>>8)&0xff; I2C1->CR1 |= I2C_CR1_START; while (!(I2C1->SR1 & I2C_SR1_SB)) { } (void) I2C1->SR1; I2C1->DR = address_ad1115_w; while (!(I2C1->SR1 & I2C_SR1_ADDR)) { } (void) I2C1->SR1; (void) I2C1->SR2; I2C1->DR=0x01; // config ads1115 while (!(I2C1->SR1 & I2C_SR1_TXE)) { } I2C1->DR=uc_init_MSB; while (!(I2C1->SR1 & I2C_SR1_BTF)) { } I2C1->DR=uc_init_LSB; while (!(I2C1->SR1 & I2C_SR1_BTF)) { } I2C1->CR1 |= I2C_CR1_STOP; } unsigned int read_ads1115(void) { unsigned char uc_t_MSB=0; unsigned char uc_t_LSB=0; unsigned int ui_azp=0; I2C1->CR1 |= I2C_CR1_ACK; I2C1->CR1 |= I2C_CR1_START; while (!(I2C1->SR1 & I2C_SR1_SB)) { } (void) I2C1->SR1; I2C1->DR = address_ad1115_w; while (!(I2C1->SR1 & I2C_SR1_ADDR)) { } (void) I2C1->SR1; (void) I2C1->SR2; I2C1->DR=00; while (!(I2C1->SR1 & I2C_SR1_TXE)){}; // Restart I2C1->CR1 |= I2C_CR1_START; while (!(I2C1->SR1 & I2C_SR1_SB)) { } (void) I2C1->SR1; I2C1->DR = address_ad1115_r; while (!(I2C1->SR1 & I2C_SR1_ADDR)) { } (void) I2C1->SR1; (void) I2C1->SR2; while (!(I2C1->SR1 & I2C_SR1_RXNE)){}; uc_t_MSB = I2C1->DR; I2C1->CR1 &= ~I2C_CR1_ACK; while (!(I2C1->SR1 & I2C_SR1_RXNE)){}; uc_t_LSB = I2C1->DR; I2C1->CR1 |= I2C_CR1_STOP; ui_azp = (uc_t_MSB<<8)| uc_t_LSB; return ui_azp; }
Подключаем в main.c
#include "ads1115.h"
Графики обмена
При чтении температуры лишний байт читается конечно,но пробовал читать как в реферансе по 103,но так и не вышло.Но как бы и датчик уже 3 байт не выдает и считывает правильно. Но если кто подскажет,как правильно то попробуем.
Отредактировано CERGEI (2018-02-27 18:03:30)