ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
17 мая
1491156 Топик полностью
SciFi (15.01.2025 16:43, просмотров: 324) ответил jlm на DeepSeek прям поражен широтой знаний, от прогерства до медицины насколько хватило.
Во. "Напиши код на Си для чтения показаний датчика температуры DS18B20, используя только вывода 0 или 1 в порт и чтения 0 или 1 из порта." 

Для чтения данных с датчика температуры DS18B20 с использованием только операций записи и чтения битов (0 или 1) в порт, необходимо реализовать протокол 1-Wire "вручную". Это требует точного управления временем и последовательностью операций.

Ниже приведен пример кода на C для чтения температуры с DS18B20, используя только операции записи и чтения битов:

________________________________________

Код на C для чтения температуры с DS18B20


#include <avr/io.h>
#include <util/delay.h>

// Пин, к которому подключен DS18B20 #define DS18B20_PIN PB0 #define DS18B20_PORT PORTB #define DS18B20_DDR DDRB #define DS18B20_PIN_REG PINB
// Функция для установки пина в режим вывода void set_pin_output() { DS18B20_DDR |= (1 << DS18B20_PIN); }
// Функция для установки пина в режим ввода void set_pin_input() { DS18B20_DDR &= ~(1 << DS18B20_PIN); }
// Функция для записи бита в DS18B20 void write_bit(uint8_t bit) { set_pin_output(); DS18B20_PORT &= ~(1 << DS18B20_PIN); // Начало слота записи _delay_us(2); // Задержка для низкого уровня if (bit) { DS18B20_PORT |= (1 << DS18B20_PIN); // Если бит = 1, поднимаем уровень } _delay_us(60); // Задержка для завершения слота DS18B20_PORT |= (1 << DS18B20_PIN); // Возвращаем высокий уровень _delay_us(2); // Задержка для восстановления }
// Функция для чтения бита из DS18B20 uint8_t read_bit() { uint8_t bit = 0; set_pin_output(); DS18B20_PORT &= ~(1 << DS18B20_PIN); // Начало слота чтения _delay_us(2); // Задержка для низкого уровня set_pin_input(); // Переключаем пин в режим ввода _delay_us(10); // Задержка для стабилизации if (DS18B20_PIN_REG & (1 << DS18B20_PIN)) { bit = 1; // Если уровень высокий, бит = 1 } _delay_us(50); // Задержка для завершения слота return bit; }
// Функция для отправки команды в DS18B20 void send_command(uint8_t command) { for (uint8_t i = 0; i < 8; i++) { write_bit(command & 0x01); // Отправляем младший бит command >>= 1; // Сдвигаем команду вправо } }
// Функция для чтения байта из DS18B20 uint8_t read_byte() { uint8_t byte = 0; for (uint8_t i = 0; i < 8; i++) { byte >>= 1; // Сдвигаем байт вправо if (read_bit()) { byte |= 0x80; // Устанавливаем старший бит, если прочитали 1 } } return byte; }
// Функция для инициализации DS18B20 uint8_t ds18b20_init() { set_pin_output(); DS18B20_PORT &= ~(1 << DS18B20_PIN); // Начало сигнала сброса _delay_us(480); // Задержка для сигнала сброса set_pin_input(); // Переключаем пин в режим ввода _delay_us(70); // Задержка для ожидания ответа if (!(DS18B20_PIN_REG & (1 << DS18B20_PIN))) { _delay_us(410); // Задержка для завершения сигнала сброса return 1; // Успешная инициализация } return 0; // Ошибка инициализации }
// Функция для чтения температуры float read_temperature() { uint8_t temp_lsb, temp_msb; int16_t temp_raw; if (ds18b20_init()) { send_command(0xCC); // Пропуск ROM (если один датчик на шине) send_command(0x44); // Команда для начала преобразования температуры _delay_ms(750); // Ожидание завершения преобразования ds18b20_init(); send_command(0xCC); // Пропуск ROM send_command(0xBE); // Команда для чтения данных temp_lsb = read_byte(); // Чтение младшего байта температуры temp_msb = read_byte(); // Чтение старшего байта температуры temp_raw = (temp_msb << 8) | temp_lsb; // Объединение байтов return (float)temp_raw / 16.0; // Преобразование в градусы Цельсия } return -999.0; // Ошибка чтения }
int main() { float temperature; while (1) { temperature = read_temperature(); if (temperature != -999.0) { // Вывод температуры (например, на дисплей или в UART) // Здесь можно добавить код для вывода температуры } _delay_ms(1000); // Задержка между измерениями } }


Объяснение кода:

1. Управление пином:

- Функции set_pin_output() и set_pin_input() переключают пин между режимом вывода и ввода.

- Функции write_bit() и read_bit() реализуют протокол 1-Wire для записи и чтения битов.

2. Инициализация DS18B20:

- Функция ds18b20_init() отправляет сигнал сброса и проверяет ответ от датчика.

3. Чтение температуры:

- Функция read_temperature() отправляет команды для начала преобразования температуры и чтения данных.

- Температура возвращается в градусах Цельсия.

4. Основной цикл:

- В бесконечном цикле температура считывается каждую секунду.

________________________________________

Важные моменты:

• Точность временных задержек критична для работы протокола 1-Wire.

• Код написан для микроконтроллера AVR (например, ATmega328P, используемого в Arduino). Для других микроконтроллеров потребуется адаптация.

• Если используется несколько датчиков на одной шине, потребуется реализация поиска устройств (ROM-команды).

ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้