Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы
Непрочитано 27.10.2012, 15:50  
Sany81
Частый гость
 
Регистрация: 30.08.2010
Сообщений: 46
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Sany81 на пути к лучшему
По умолчанию Mega48+DS1307=ошибки при чтении

Добрый день.
при чтении времени из DS1307 периодически вместо часа, минуты и секуды получаю значения 165. Что это за сбой может быть?
Вот куски кода:
#asm
.equ __i2c_port=0x05 ;PORTB
.equ __sda_bit=1
.equ __scl_bit=2
#endasm
#include ‹i2c.h›
#include ‹ds1307.h›
unsigned char hour,min,sek;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
rtc_get_time(&hour,&min,&sek); //считать время
iBuf=min*100+sek;
//полученное значение вывожу на четырехразрядный семисегметник
}

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

TCCR0B=0x05;

i2c_init();
rtc_init(0,0,0);

TIMSK0=0x01;

#asm("sei")

while (1)
{
}

В общем как то так происходит чтение данных из DS1307
Пробовал разные часы, на всех такая байда, думается что проблема с i2c.

Знающих, просьба подсказать где моя ошибка, что я сделал не так
Реклама:
Sany81 вне форума  
Непрочитано 28.10.2012, 00:23  
Godzilla82
Почётный гражданин KAZUS.RU
 
Регистрация: 29.10.2006
Сообщений: 1,448
Сказал спасибо: 96
Сказали Спасибо 319 раз(а) в 233 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: mega48+DS1307=ошибки при чтении

А где инициализация портов? Внешний подтягивающий резистор ставили?

И где вывод на семисегментник? С какой периодичностью опрашивается время?
Godzilla82 вне форума  
Непрочитано 28.10.2012, 09:16  
Sany81
Частый гость
 
Регистрация: 30.08.2010
Сообщений: 46
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Sany81 на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

Сообщение от Godzilla82 Посмотреть сообщение
А где инициализация портов? Внешний подтягивающий резистор ставили?

И где вывод на семисегментник? С какой периодичностью опрашивается время?
это лишь кусок кода связанного с чтением данных.
инициализация портов вот:
PORTB=0x00;
DDRB=0x39;
это пока все порты что задействованы
В0 - служебный вывод на светодиод
В1,В2 - DS1307
В3,В4,В5 - семисегментник на двух сдвиговых регистрах

резисторы стоят на ногах В1,В2

Вывод на дисплей:

while (1)
{
rtc_get_time(&hour,&min,&sec);
//Пробовал и тут время читать и в прерывании по таймеру примерно раз в секунду, результат одиноковый, в 8 случаях из 10 получаю не те данные которые ожидаю получить от часов.
copy_temp = 0xff-led_buff[symbol];
for (counter = 0; counter ‹ 8; counter++)
{
DS = 1-(counter==(symbol+1));
SH_CP = 1;
SH_CP = 0;
}
for (counter = 0; counter ‹ 8; counter++)
{
DS = copy_temp & 0x01;
SH_CP = 1;
SH_CP = 0;
copy_temp = copy_temp ›› 1;
}
ST_CP = 1;
ST_CP = 0;
++symbol;
if (symbol==4){symbol=0;}
}
Вывод, например какого нибудь каунтера от 0 до 9999 проходит нормально, проблема именно с выводом часов

Последний раз редактировалось Sany81; 25.04.2013 в 10:30.
Sany81 вне форума  
Непрочитано 28.10.2012, 14:35  
Godzilla82
Почётный гражданин KAZUS.RU
 
Регистрация: 29.10.2006
Сообщений: 1,448
Сказал спасибо: 96
Сказали Спасибо 319 раз(а) в 233 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: mega48+DS1307=ошибки при чтении

Сообщение от Sany81 Посмотреть сообщение
iBuf=min*100+sek;
Получаешь iBuf = 165 или что?

Я пока не увидел всего кода. Какой источник тактирования?

Если можно, проект полность. Подтягивающие резисторы на плюс какого номинала? Правильно ли прошиты фьюзы?
Godzilla82 вне форума  
Непрочитано 28.10.2012, 15:10  
Boba_spb
Почётный гражданин KAZUS.RU
 
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
Boba_spb на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

Вот это лучше писать так
iBuf=(min&127)*100+(sek&127): Что б всякое лишнее из регистров RTC не лезло куда попало.
Boba_spb вне форума  
Непрочитано 28.10.2012, 18:41  
Sany81
Частый гость
 
Регистрация: 30.08.2010
Сообщений: 46
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Sany81 на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

Сообщение от Godzilla82 Посмотреть сообщение
Получаешь iBuf = 165 или что?

Я пока не увидел всего кода. Какой источник тактирования?

Если можно, проект полность. Подтягивающие резисторы на плюс какого номинала? Правильно ли прошиты фьюзы?
резисторы номиналом 4к7, источник тактирования внутренний на 8 МГц
Проект только начинает свою жизнь, поэтому приведу как есть, со всеми. Чтение температуры пока отключено, на дисплей выводится только время.
iBuf получается не 165 а судя по всему 165*100+165

Цитата:
Вот это лучше писать так
iBuf=(min&127)*100+(sek&127): Что б всякое лишнее из регистров RTC не лезло куда попало.
ОК, спасибо, сейчас перепишу.

Вот листинг программы, пока со всеми ошибками и с кучей мусора, проект только начинает быть, поэтому пока не до красоты.


#include ‹mega48.h›
#include ‹delay.h›


// I2C Bus functions
#asm
.equ __i2c_port=0x05 ;PORTB
.equ __sda_bit=1
.equ __scl_bit=2
#endasm
#include ‹i2c.h›

#asm
.equ __w1_port=0x08 ;PORTC
.equ __w1_bit=0
#endasm
#include ‹1wire.h›
#include ‹delay.h›

#define DS18B20_FAMILY 0x28
#define DS_READ_ROM 0x33
#define DS_SKIP_ROM 0xcc
#define DS_CONVERT_T 0x44
#define DS_WRITE_SCRATCHPAD 0x4e
#define DS_READ_SCRATCHPAD 0xbe
#define DS_12BITS 0x7f

typedef unsigned char byte;
typedef struct {
byte family;
byte serial[6];
byte crc;
}trom;
typedef struct {
union {
struct {
byte l;
byte h;
}b;
int w;
}temp;
union {
struct {
byte l;
byte h;
}b;
int w;
}th;
byte config;
byte res[3];
byte crc;
}tscratchpad;
trom ds_rom;
tscratchpad ds_sp;
bit ds_ok=0;


// DS1307 Real Time Clock functions
#include ‹ds1307.h›


#define SH_CP PORTB.3
#define DS PORTB.4
#define ST_CP PORTB.5

unsigned int iBuf,temp=0;
unsigned int copy_temp=0;
unsigned char counter,symbol, delim=0;

unsigned char hour,min,sec; //часы, минуты, секунды
unsigned char day,month,year; //день, месяц, год

unsigned char dig_table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f};
unsigned char led_buff[4]={0,0,0,0};


void ds_init()
{
byte i;
byte *p;
#asm("cli")
if (w1_init()!=0)
{
p=(byte*)&ds_rom;
w1_write(DS_READ_ROM);
for (i=0;i‹8;i++) *p++=w1_read();
if (w1_dow_crc8(&ds_rom,==0)
{
if (ds_rom.family==DS18B20_FAMILY)
{
w1_init();
w1_write(DS_SKIP_ROM);
w1_write(DS_WRITE_SCRATCHPAD);
w1_write(0);
w1_write(0);
w1_write(DS_12BITS);
ds_ok=1;
}
}
}
#asm("sei")
}

void ds_calc() {
w1_init();
w1_write(DS_SKIP_ROM);
w1_write(DS_CONVERT_T);
}

void ds_read() {
byte i;
byte *p=(byte*)&ds_sp;
w1_init();
w1_write(DS_SKIP_ROM);
w1_write(DS_READ_SCRATCHPAD);
for (i=0;i‹9;i++) *p++=w1_read();
if (w1_dow_crc8(&ds_sp,9)!=0) return;
temp=(ds_sp.temp.w*5)››3;
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
++delim;
PORTB.0=!PORTB.0;

if (delim==30)
{

rtc_get_time(&hour,&min,&sec); //считать время
rtc_get_date(&day,&month,&year); //считать дату


// ds_calc();
// ds_read();
// iBuf=temp;
iBuf=min*100+sec;
led_buff[3]=dig_table[iBuf/1000];
iBuf %=1000;
led_buff[2]=dig_table[iBuf/100];
iBuf %=100;
led_buff[1]=dig_table[iBuf/10];
iBuf %=10;
led_buff[0]=dig_table[iBuf];
delim=0;
}
}



// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif


// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=In Func1=In Func0=Out
// State7=T State6=T State5=0 State4=0 State3=0 State2=T State1=T State0=0
PORTB=0x00;
DDRB=0x39;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// I2C Bus initialization
i2c_init();//**********************

// DS1307 Real Time Clock initialization
// Square wave output on pin SQW/OUT: Off
// SQW/OUT pin state: 0
rtc_init(0,0,0);//**********************

rtc_set_time(23,59,59); //установить время: часы, минуты, секунды

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;

ds_init();
while (ds_ok==0);

// Global enable interrupts
#asm("sei")

while (1)
{

copy_temp = 0xff-led_buff[symbol];

for (counter = 0; counter ‹ 8; counter++)
{
DS = 1-(counter==(symbol+1));
SH_CP = 1;
SH_CP = 0;
}

for (counter = 0; counter ‹ 8; counter++)
{
DS = copy_temp & 0x01;
//Дергаем ногой чтоб пропихнуть бит в регистр
SH_CP = 1;
SH_CP = 0;
copy_temp = copy_temp ›› 1; // Сдвигаем все биты переменной темp влево на один бит
}
//Дергаем ногой и защёлкиваем данные.
ST_CP = 1;
ST_CP = 0;

++symbol;
if (symbol==4){symbol=0;}

}
}
Sany81 вне форума  
Непрочитано 28.10.2012, 19:37  
Sany81
Частый гость
 
Регистрация: 30.08.2010
Сообщений: 46
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Sany81 на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

Вроде нашел проблему, проверю чуть позже.
Не заметил, что под "тяжестью" семисегментника проседает входное напряжение до 4-4.5 вольта в зависимости от того что выводится на дисплей. На часах стоит батарейка с напряжением 3.2 вольта. Из за этого часы периодически уходят в работу от батареи и перестают общаться с МК, в следствии чего и возникает мусор.
А заметил это случайно, просто втащил батарейку и рестартанул МК, после чего часики заткали без ошибок.

Только что уменьшил слегка прожорливость дисплея и часики заходили как положено.
Спасибо всем откликнувшимся, тему можно прикрывать а можно написать комментарии по поводу кода, буду рад услышать конструктивные предложения.
Sany81 вне форума  
Непрочитано 28.10.2012, 20:57  
Godzilla82
Почётный гражданин KAZUS.RU
 
Регистрация: 29.10.2006
Сообщений: 1,448
Сказал спасибо: 96
Сказали Спасибо 319 раз(а) в 233 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: mega48+DS1307=ошибки при чтении

Чтобы поменьше тактов тратилось, желательно не использовать int.
А то мы сначала умножаем, получаем int, затем делим и извлекаем из int. Это куча тактов.
Будет намного быстрее, если
PHP код:
 
digit
[0] = sec 10;
digit[1] = sec 10;
digit[2] = hour 10;
digit[3] = hour 10
И ещё. Цикл измерения температуры при большой точности занимает почти секунду.

Куча действий в прерывании тоже занимает много времени.

Если прерывание произойдёт во время опроса 1wire, могут сбиться тайминги и в результате ошибочное чтение.

Если засунуть опрос датчика в прерывание, оно затянется на секунду.

То есть, вроде бы всё просто, но есть о чём задуматься.
Godzilla82 вне форума  
Непрочитано 29.10.2012, 09:27  
Boba_spb
Почётный гражданин KAZUS.RU
 
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
Boba_spb на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

Да в часах регистры в BCD формате - выводи тетрады на индикатор и никаких умножений и делений не надо делать.
Boba_spb вне форума  
Непрочитано 29.10.2012, 11:48  
kosmos440o
Заблокирован
 
Регистрация: 23.09.2007
Сообщений: 761
Сказал спасибо: 84
Сказали Спасибо 352 раз(а) в 151 сообщении(ях)
kosmos440o на пути к лучшему
По умолчанию Re: mega48+DS1307=ошибки при чтении

А сколько по времени занимает опрос DS1307? Я тут тоже играюсь, у меня получается 3-4 мсек. Не многовато ли для прерывания?
kosmos440o вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна схема автоматического закрывания дверей автомобиля при движении Aviasined Электроника средств транспорта 17 28.09.2010 06:14
Отключение питания при падении напряжения maddemon Поиск схем. Делимся схемами 1 06.02.2009 13:27
[Решено] Сборник перлов любителей кабельщины mikesmith Отвлекитесь, эмбеддеры! 135 14.08.2007 15:49
При чтении CD диска выдаёт 00 треков 00:00 минут axle Аудиотехника 3 10.04.2006 11:06
[Решено] сетевой импульсный преобразователь напряжения (парадокс)!? вадим Источники питания и свет 10 11.10.2005 21:05


Часовой пояс GMT +4, время: 03:46.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot