STM32F103 и 1-Wire

Добрый день.

Перешел с AVR на STM32F103 и столкнулся с проблемой работы шины 1-wire. Подключаю iButton и DS18B20, не погу подключиться к датчикам. Судя по всему не хватает питания. Есть опыт подключения таких датчиков к STM32?

Если пин контроллера сконфигурирован то питание падает до 1.7В

Так быть не должно, ищите ошибку.
Чтобы вам можно было помочь, покажите код и схему

схему подключения давайте

Программа

#include <OneWireSTM.h>

#define TM PB4                //iButton
OneWire iBt(TM);

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// Based on version by PJRC
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(PC15);  // on pin 10 (a 4.7K resistor is necessary)

byte iBtAddr[8];                             // для считывания идентификатора ключа

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");

  //========================================================================================
  // Обработка Touch Memory
  //========================================================================================
  if (iBt.reset()) {
    Serial.println("Yes iBt");
    iBt.write(0x33);
    delay(1);
    for (int i = 0; i < 8; i++)
    {
      iBtAddr[i] = iBt.read(); // Считываем
    }
    Serial.print("HEX card =");         
    for (i = 0; i < 8; i++)      // Цикл для вывода 8 байт в терминал
    {
      Serial.write(' ');             // Выводим пробел для визуального удобства
      Serial.print(iBtAddr[i], HEX); // Выводим данные из массива в формате HEX
      Serial.println(' ');
    }
  }
  //========================================================================================  
}

До этого собирал все на ардуино, но там банально не хватило памяти для работы с SIM800L. Перешел на STM32, все прям круто, но не могу шину 1-wire запустить никак.

теперь поясните эту фразу. На каком пине падает питание до 1.7В ?

И еще вопрос - прошиваете чип как, через Ст-линк?

Можете показать вывод в Сериал монитор - что ваш код печатает?

15:32:42.822 -> 
15:32:43.047 -> No more addresses.
15:32:43.047 -> 
15:32:43.317 -> No more addresses.
15:32:43.317 -> 
15:32:43.542 -> No more addresses.
15:32:43.542 -> 
15:32:43.812 -> No more addresses.
15:32:43.812 -> 
15:32:44.037 -> No more addresses.

Измеряю между контактами iButton. Если порт сконфигурирован на чтение библиотекой напряжение падает, если в скетче указать что порт вход и подтянуть резистор то напряжение будет 3.3В.

Создается впечатление что порт имеет низкое внутреннее сопротивление. Пробовал подключать к разным портам.

Прошиваю через USB из Arduino IDE, в контроллере прошит загрузчик boot20.

Оригинально ))
Если честно, я схему так и не понял. Зачем к DS18B20 подключать кнопку?

Это не кнопка, просто так изобразил считыватель iButton ключей (это ключи для домофонов в виде таблетки).

Суть вопроса от этого не изменилась: Зачем это подключать к DS18B20?

====

А, прошу прощения, не разглядел что там GND.

Полагаю, что падение напряжения из-за резистора 47к.

Это 4.7 там просто запятую плоховато видно

Это 2 разных устройства, оба работают по шине 1-wire. И на STM32 не могу ни одно из них запустить. И собственно возникает вопрос работает кто то с этой шиной на STM, и если работает то как?

Поищите другую библиотеку.

Добавьте, так же конденсатор по питанию ~100uF

Запускаете по отдельности или сразу всю кучу пытаетесь переварить?

По разному пробовал, по отдельности, выводы контроллера менял, номинал подтягивающего резистора. Меньше 1к не делал, побаиваюсь сжечь порт.

Попробуй напрямую вычитать температуру.

int DSPIN = PС15;

void setup() {
  Serial.begin(9600);
}
 
void loop() {
  double temp = TempRead();
  temp  = temp * 0.0625;              // conversion accuracy is 0.0625 / LSB
  Serial.print("Temperature: ");
  Serial.print(temp);
  Serial.println(" °C");
  Serial.println("");
  delay(500);
}
 
boolean DS18B20_Init() {
  pinMode(DSPIN, OUTPUT);
  digitalWrite(DSPIN, HIGH);
  delayMicroseconds(5);
  digitalWrite(DSPIN, LOW);
  delayMicroseconds(750);//480-960
  digitalWrite(DSPIN, HIGH);
  pinMode(DSPIN, INPUT);
  int t = 0;
  while (digitalRead(DSPIN)) {
    t++;
    if (t > 60) return false;
    delayMicroseconds(1);
  }
  t = 480 - t;
  pinMode(DSPIN, OUTPUT);
  delayMicroseconds(t);
  digitalWrite(DSPIN, HIGH);
  return true;
}
 
void DS18B20_Write(byte data) {
  pinMode(DSPIN, OUTPUT);
  for (int i = 0; i < 8; i++) {
    digitalWrite(DSPIN, LOW);
    delayMicroseconds(10);
    if (data & 1) {
      digitalWrite(DSPIN, HIGH);
    }
    else {
      digitalWrite(DSPIN, LOW);
    }
    data >>= 1;
    delayMicroseconds(50);
    digitalWrite(DSPIN, HIGH);
  }
}
 
byte DS18B20_Read() {
  pinMode(DSPIN, OUTPUT);
  digitalWrite(DSPIN, HIGH);
  delayMicroseconds(2);
  byte data = 0;
  for (int i = 0; i < 8; i++) {
    digitalWrite(DSPIN, LOW);
    delayMicroseconds(1);
    digitalWrite(DSPIN, HIGH);
    pinMode(DSPIN, INPUT);
    delayMicroseconds(5);
    data >>= 1;
    if (digitalRead(DSPIN)) {
      data |= 0x80;
    }
    delayMicroseconds(55);
    pinMode(DSPIN, OUTPUT);
    digitalWrite(DSPIN, HIGH);
  }
  return data;
}
 
int TempRead() {
  if (!DS18B20_Init()) {
    return 0;
  }
  DS18B20_Write (0xCC);           // Send skip ROM command
  DS18B20_Write (0x44);           // Send reading start conversion command
  if (!DS18B20_Init()) {
    return 0;
  }
  DS18B20_Write (0xCC);           // Send skip ROM command
  DS18B20_Write (0xBE);           // Read the register, a total of nine bytes, the first two bytes are the conversion value
  int temp = DS18B20_Read ();     // Low byte
  temp |= DS18B20_Read () << 8;   // High byte
  return temp;
}

Библиотека Arduino Dallas и библиотека OneWire не поддерживаются DS18B20. По этой причине нам приходится писать код без использования этих библиотек.

ЗЫ: И удали из ключевых слов темы слово ‘esp32’, причем тут есп - если тема про STM32?