MSP430 и DS18S20

Обсуждаем цифровые устройства...
Ответить
Открыл глаза
Сообщения: 71
Зарегистрирован: Чт окт 28, 2010 11:20:39

Сообщение bishop-strip »

Здравствуйте товарищи! Решил связать контроллер MSP430F543x с датчиком температуры DS18s20.
Вроде все правильно делаю, датчик на момент инициализации даже отвечает "низким уровнем"
а если отправляю запрос, и начинаю считывать ответ - то ничего не выходит.
Когда пытаюсь запросить данные из памяти, он мне возвращает все "1", тоесть uint8_t scratchpad[9] все заполняются единицами... скажите В ЧЕМ ПРОБЛЕМА! УСТАЛ УЖЕ С НИМ ВОЗИТЬСЯ!
Код привожу:

main.cpp:

#include <stdio.h>
#include <stdint.h>

#include "one_wire.h" // Функции работы с 1-wire


int main()
{
one_wire ow_obj(&P1OUT, &P1IN, &P1REN, &P1DIR, BIT1);
uint8_t scratchpad[9];

while(1)
{

if( !ow_obj.lineReset() )
{
ow_obj.write_byte(0xCC);
ow_obj.write_byte(0x44);
ow_obj.lineHigh();
DELAY_US(750000);
ow_obj.lineReset();
ow_obj.write_byte(0xCC);
ow_obj.write_byte(0x33);

for (int i = 0; i < 8; i++)
scratchpad = ow_obj.read_byte();
}
}

return 0;
}


one_wire.h:

#define DELAY_US(x) __delay_cycles((x * 1))

class one_wire
{
public:
one_wire(volatile unsigned char *OUT, volatile unsigned char *IN, volatile unsigned char *REN, volatile unsigned char *DIR, uint8_t iPin);
~one_wire();

//Функции управления состоянием
uint8_t lineReset();
void lineHigh(); //Вывод МК - "1"
void lineLow(); //Вывод МК - "0"
void lineRelease(); //МК освобождает ножку

void write_bit(int byte); //Отправка бита
void write_byte(int byte); //Отправка байта
uint8_t read_bit(); //Прием бита
uint8_t read_byte(); //Прием байта


private:
uint8_t pin;
volatile uint8_t *POUT;
volatile uint8_t *PIN;
volatile uint8_t *PREN;
volatile uint8_t *PDIR;
};


one_wire.cpp
#include "one_wire.h"


//Конструктор
one_wire::one_wire(volatile unsigned char *OUT, volatile unsigned char *IN, volatile unsigned char *REN, volatile unsigned char *DIR, uint8_t iPin)
{
this->POUT = OUT;
this->PIN = IN;
this->PREN = REN;
this->PDIR = DIR;
this->pin = iPin;
}

//Деструктор
one_wire::~one_wire()
{
this->POUT = 0;
this->PIN = 0;
this->PREN = 0;
this->PDIR = 0;
}

//Инициализация
uint8_t one_wire::lineReset()
{
lineLow();
DELAY_US(500);
lineRelease();
DELAY_US(60);
if(*PREN & pin)
return 1;
DELAY_US(450);
if(! *PREN & pin)
return 2;
else
return 0;
}

//Вывод МК "1"
void one_wire::lineHigh()
{
*PDIR |= pin;
*POUT |= pin;
*PREN |= pin;
}

//Вывод МК "0"
void one_wire::lineLow()
{
*PDIR |= pin;
*POUT &= ~pin;
*PREN |= pin;
}

//МК освобождает ножку
void one_wire::lineRelease()
{
*PDIR &= ~pin;
*POUT |= pin;
*PREN &= ~pin;
}

//Отправка бита
void one_wire::write_bit(int byte)
{
DELAY_US(1);
lineLow();
if(byte)
DELAY_US(1);
else
DELAY_US(60);
lineRelease();
if(byte)
DELAY_US(119);
else
DELAY_US(60);
}

//Отправка байта
void one_wire::write_byte(int byte)
{
for(int i = 0; i < 8; i++)
{
write_bit(byte & 1);
byte >>= 1;
}
}


//Прием бита
uint8_t one_wire::read_bit()
{
uint8_t bit = 0;
DELAY_US(1);
lineLow();
DELAY_US(1);
lineRelease();
DELAY_US(5);
bit = *PIN & pin;
DELAY_US(70);
return bit;
}

//Прием байта
uint8_t one_wire::read_byte()
{
uint8_t byte = 0;
for(int i = 0; i < 8; i++)
{
byte >>= 1;
if( read_bit() )
byte |= 0x80;

}
return byte;
}
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3794
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Возможно, Вы сочтете это за "оффтоп", но почему не использовать I2C сенсор? Я понимаю, что к DS-ке надо тянуть меньше проводов, но любой современный телефонный кабель содержит 4 жилы. Она (DS-ка) может и имеет смысл в случае МК с малым числом выводов, но в Вашем-то их полно. Кроме того, у интерфейса 1-wire есть большой недостаток, который списывает на нет все его преимущества (если таковые есть) - отсутствие аппаратного драйвера. А программный драйвер отнимает слишком много ресурсов МК. Вы пробовали посмотреть дисассемблированный код - это-же тихий ужас! Хотя в Вашем МК и памяти хоть отбавляй, но зачем?

В семействе 5хх имеется нормальный аппаратный I2C модуль и также примеры его использавания на С на вебсайте. Можно будет сделать полностью контролируемую прерываниями элегантную программу с минимальным задействованием процессора. А если к тому-же добавить DMA, то процессор еще более освободится. Посмотрите, например, в сторону I2C сенсора TMP112 с аналогичными параметрами по точности.
Реклама
Открыл глаза
Сообщения: 71
Зарегистрирован: Чт окт 28, 2010 11:20:39

Сообщение bishop-strip »

Спасибо за совет, я выполнил... класс рабочий, просто я не настроил рабочую частоту процессора и он не успевал считывать данные....
А на счет I2C, спасибо за совет, вот сейчас его начинаю использовать тоже)
Ответить

Вернуться в «Цифровая техника»