Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> код с DS1990A, считывается некорректно 
V
    Опции темы
Vilandrew
Дата 26.12.2008, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



C наступающим Новым Годом!
Возникла вот какая проблема. Программа считывает код с DS1990, но как оказалось неверно, например на выходе у меня получается в 16-ричном виде F2242424FC279F27. По даташиту DS1990 выяснилось что 64-битный код состоит из 3 частей: первые 8 бит - родительский код (должен быть 01), 48 бит сам серийный номер, остальные 8 бит - CRC. Играл с задержками при чтении, результата не дало, не могу добиться 01.
Краткое описание программы: Контроллер опрашивает считыватель, как только появился сигнал присутствия, передает команду 0x33. Затем начинает считывать и заносить 0 и 1 в двухмерный массив. По окончанию вывожу массив в порт. На компьютере анализирую полученный код и передаю одну из команд на МК. Он принимает и на основании команды зажигает один из светодиодов.
Вот сама программа:
Код

#include <avr/io.h>
#include <avr/iom128.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL  // 8 MHz

//Инициализация UART
void Init_UART0(void)
{
UCSR0A = 0x0;        //    0000 0000
UBRR0H=0x0;        
UBRR0L=0x33;                // скорость 9600 при 8MHz
UCSR0B |= (1<<RXEN0) | (1<<TXEN0);
UCSR0C |= (1<<UCSZ01) | (3<<UCSZ00);
}

//Чтение из UART
char _get(void)        
{
        while ( !(UCSR0A & (1<<RXC0)) );    // Ждем пока данные не приняты
        return UDR0;   // Возвращаем содержимое UDR0

}

//Вывод символа в UART
void _put(char data)
{
        while ( !( UCSR0A & (1<<UDRE0)) );    // Ждем,если предыдущий символ не передался.
        UDR0 = data;                        // Кладем данные в регистр UDR0

}

void send_ds1990_command(unsigned char command);
void read_ds1990(void);
unsigned char tcnt, i;
char buffer[8][8];

//Вывод массива
void port_output(void)
{
for (int n = 0; n < 8; n++)
    {
        for(int n2 = 0;n2 < 8; n2++)
        {
        _put(buffer[n][n2]);
        }
    }    
}

//Функция сброса DS1990
void reset_ds1990(void)
{
DDRB|=_BV(0);        // Вывод порта настраиваем как выход
PORTB&=~_BV(0);

cli();
_delay_ms(0.680); //Устанавливаем 0 в теч. около 480 мкс

DDRB&=~_BV(0);       //Вывод порта настраиваем как вход
_delay_ms(0.07);  //Ожидание сигнала присутствия 70 мкс
   if(PINB & (1<<PINB0))  //Если 1 - нет сигнала присутствия
   {
   _delay_ms(0.41); //410 мкс
   sei();
   }   
  else
  {
  _delay_ms(0.41); //410 мкс
  sei();
  send_ds1990_command(0x33);
  read_ds1990();
  }
}

//Чтение

void read_ds1990(void)

cli(); 
  for(i = 0; i < 8; i++) // байтовый цикл
  {

    for(tcnt = 0; tcnt < 8; tcnt++)          // битовый цикл
    {
    DDRB|=_BV(0);
    PORTB&=~_BV(0);
    _delay_ms(0.006);// ждем 6 мкс
    DDRB&=~_BV(0);
    PORTB&=~_BV(0);
    _delay_ms(0.009); // ждем 9 мкс
          
            if(PINB & (1 << PINB0))
            {
            buffer[i][tcnt] = '1';
            }
            else
            {
            buffer[i][tcnt] = '0';
            }
    }
    _delay_ms(0.044);
 }
port_output();

unsigned char rec = _get(); // приходит команда от ПК
switch( rec )
    {
    case 'a': PORTC = 0x20; _delay_ms(4000); PORTC = 0x00; break; //зеленый
    case 'b': PORTC = 0x08; _delay_ms(2000); PORTC = 0x00; break; //красный
    default: break;
    }
sei();
    
}

//Функция пересылки команд

void send_ds1990_command(unsigned char command)
{
cli();
unsigned char data=command;
   for(i=0;i<8;i++)
   {
   data=data<<7;        //Сдвиг на i разрядов влево
   command=command>>1;  //Сдвиг передаваемого байта
     if(data==0x00)       //Передача лог.0
     {
     DDRB|=_BV(0);
     PORTB&=~_BV(0);
     _delay_ms(0.06);  //60 мкс
     DDRB&=~_BV(0);
     PORTB&=~_BV(0);          
     _delay_ms(0.01);  //10 мкс
     }
     else                 //Передача лог.1
     {
     DDRB|=_BV(0);
     PORTB|=_BV(0);     
     _delay_ms(0.006);   //Задержка примерно на 6 мкс
     DDRB&=~_BV(0);  
     PORTB&=~_BV(0);    
     _delay_ms(0.064);   //Задержка примерно на 64 мкс  
     }
   data=command;        //Новое значение для сдвига
   };
sei();
}

int main (void)
{
Init_UART0();
DDRC = 0xff;

    while (1)
    {
    reset_ds1990();
    }
}

PM MAIL WWW ICQ Jabber   Вверх
Den64
Дата 26.12.2008, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 6.4.2006
Где: Курск

Репутация: 1
Всего: 2



Отлаживать через JTAG есть возможность?

Добавлено через 26 секунд
Отлаживать через JTAG есть возможность?
--------------------
Инагда пишу звуками.
PM WWW ICQ   Вверх
Vilandrew
Дата 26.12.2008, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



Возможности отлаживать через JTAG нет.
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 26.12.2008, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



У меня идиотский вопрос - а функция _delay_ms умеет принимать double параметры? Мне почему то кажется, что она ожидает целое (увы не могу проверить, нет под рукой winavr)

PM MAIL   Вверх
Vilandrew
Дата 26.12.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



xvr, _delay_ms принимает числа в формате double.
PM MAIL WWW ICQ Jabber   Вверх
Den64
Дата 27.12.2008, 02:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 6.4.2006
Где: Курск

Репутация: 1
Всего: 2



А частоту контроллера проверяли?
И частоту UART?
Проверить правильно ли работает UART:
Код

int main (void)
{
Init_UART0();
DDRC = 0xff;
_put(_get());
    while (1)
    {
    reset_ds1990();
    }
}


--------------------
Инагда пишу звуками.
PM WWW ICQ   Вверх
Vilandrew
Дата 27.12.2008, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



Да, через fuses я уже переключил контроллер на 8Мгц. UART работает правильно, что передаю, то и получаю.
Также проверяю программу через протеус, и там почему-то тоже не выходит 01H в коде.
Если брать демонстрационный пример в протеусе (codevision) с работой 1-wire, то 01H в коде есть.
PM MAIL WWW ICQ Jabber   Вверх
Vilandrew
Дата 27.12.2008, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



Переписал программу на Codevision, все стало считываться правильно smile smile 
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 27.12.2008, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Vilandrew @ 26.12.2008,  11:45)
C наступающим Новым Годом!
Возникла вот какая проблема. Программа считывает код с DS1990, но как оказалось неверно

Специально скачал winavr и посмотрел. Вот неправильный кусок:

Код

#include <avr/io.h>
#include <avr/iom128.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL  // 8 MHz
Строка #define F_CPU 8000000UL  должна быть ДО строки #include <util/delay.h>, иначе все задержки считаются с частотой по умолчанию (1 MHz), он кстати, должен выдавать соотвествующее предупреждение


Это сообщение отредактировал(а) xvr - 27.12.2008, 22:48
PM MAIL   Вверх
Vilandrew
Дата 28.12.2008, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 2.6.2006
Где: Казань

Репутация: нет
Всего: нет



xvr, да, действительно в этом и была ошибка. Но предупреждений не было.
Задержки поставил по даташиту. Еще ошибку обнаружил что делал задержку в байтовом цикле, а надо было в битовом.
Спасибо за помощь smile
PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0870 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.