Счетчик импульсов с UART(снятие показаний)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

zöner писал(а): Также можно писать только при пропадании питания - компаратором или АЦП ловить момент падения питания, писать данные, и ложиться спать. Для замедления пропадания - большой электролит или ионистор по питанию.
Я вот думал собрать транзисторный ключ, питающий МК, но что-то не могу понять как в протеусе сделать питание МК на автоматическим, в протеусе даже ножки питания не показаны
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Gudd-Head »

andrey_ims писал(а):На сколько это будет надежно?
Дык, так и надо делать — писать в ОЗУ, а при пропадании питания быстренько сохранять в ЕЕПРОМ. Где-то здесь обсасывалась эта тема.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Gudd-Head писал(а): Дык, так и надо делать — писать в ОЗУ, а при пропадании питания быстренько сохранять в ЕЕПРОМ. Где-то здесь обсасывалась эта тема.
Наверное эта тема.
Почитал ее и некоторые другие, схожие темы, но вопросы остались:
1)Как происходит работа с компаратором? Как я понял, если напряжение до стабилизатора не равно напряжению после стабилизатора то происходит прерывание, в котором происходит сохранение данных в память, так?У кого нибудь есть пример кода на Си?
2)Будет ли работать такая схема: Изображение? Т.е. пока питание есть - транзистор открыт и питает конденсатор большой емкости. Когда питание пропадает, срабатывает прерывание МК по перепаду уровня и в обработчике прерывания происходит сохранение данных.

Спасибо.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

Чем обычный диод вместо транзистора не устраивает? Почему в "-" цепь?

что будет с программой при кратковременном проседании напряжения?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Kavka »

Хм... На базу "плюс" будет приходить пока кондёр не разрядиться?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Gudd-Head »

andrey_ims писал(а):Наверное эта тема.
Нет, конкретно про запись в ЕЕПРОМ при пропадании питания.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Alexeyslav писал(а):Чем обычный диод вместо транзистора не устраивает? Почему в "-" цепь?

что будет с программой при кратковременном проседании напряжения?
Та ну может и диод, я просто весьма поверхностно в теме разбираюсь :-(
Вот поэтому я пытаюсь максимально просто сделать. Пока не получается, примеры везде сложные
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

Максимально просто - это м/с часов со встроенной SRAM, одной батарейки CR2032 хватит на 5 лет непрерывного поддержания памяти. Но поддержание это хорошо... до тех пор пока свет не начинают отключать часто и надолго. Тогда просто "сохранить" в памяти уже не катит. Ведь в отсутствие электричества счетчики считают, а контроллер совсем не в курсе - он пока без питания держит в себе значение при сохранении... а счетчики-то тикают!

Есть такие теплосчетчики - подсчитывают калории ушедшие на отопление дома, так вот они имеют встроенную литиевую батарею с минимальным ресурсом в 10 лет! Счетчику не нужно питание, он в течение 10 лет считать будет.

В принципе такое можно реализовать и на контроллере - но он должен большую часть времени находится в глубокой спячке, просыпаясь только по сигналам прерывания от датчиков и при получении команды на считывание данных. Тогда такая схема сможет работать и считать непрерывно, даже на ионисторе. Если разорится на парочку ионисторов 200Ф@2.7В - то такая схема сможет полнофункционально работать без питания сутки, двое... вобщем считать надо. И в виду необходимости экономии - прийдется просчитать минимальную необходимую тактовую частоту и найти нужный кварц, так чтобы его деление на целое число могло дать 9600. Вроде бы 32768 часовой должен подойти.

Либо...поставить микросхемы-часы вроде PCF8535 по количеству каналов регистрации и включить их в режиме счета импульсов - они смогут считать импульсы независимо от работы контроллера лишь от резервного источника. Но есть один ньюанс - датчики ведь "сухой контакт" и для них нужна подтяжка... так вот, она будет потреблять энергии в 100 раз больше чем сами счетчики, особенно если датчики будут большую часть времени в состоянии "замкнуто".
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Jack_A »

Как я понял, если напряжение до стабилизатора не равно напряжению после стабилизатора то происходит прерывание
Напряжение ПОСЛЕ никогда не равно напряжению ДО стаба, кроме случая -- стаб пробит :(
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Начал пробовать работать с UART.
Взял пример из даташита и немного доточил:
Спойлер

Код: Выделить всё

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

// Constants.
uint32_t constTick = 6400;

// EEPROM addresses.
unsigned int waterCounterAddress = 0;
unsigned int electricCounterAddress = 100;

// Counters.
uint32_t electricCounter = 0;
uint32_t electricTickCounter = 0;
uint32_t waterCounter = 0;

// Water counter interrupt
ISR(INT0_vect)
{
	waterCounter++;

	_delay_ms(500);
	PORTB  |=  (1<<PB6);
	_delay_ms(500);
	PORTB  &= ~(1<<PB6);
}

// Electric counter interrupt
ISR(INT1_vect)
{
	electricTickCounter++;
	
	if (electricTickCounter == constTick) {
		electricTickCounter = 0;
		electricCounter++;
	}
	
	_delay_ms(500);
	PORTB  |=  (1<<PB6);
	_delay_ms(500);
	PORTB  &= ~(1<<PB6);
}

// Power problems interrupt.
ISR(ANA_COMP_vect)
{	
	//Save counters to EEPROM.
	eeprom_write_dword ((uint32_t*)waterCounterAddress, waterCounter);
	eeprom_write_dword ((uint32_t*)electricCounterAddress, electricCounter);
	
	_delay_ms(500);
	PORTB  |=  (1<<PB7);
	_delay_ms(500);
	PORTB  &= ~(1<<PB7);
}

void initHardware() {
	//Set port B pins direction
	DDRB  &= ~(1<<PB0);    // PB0 is AIN0 -- make it an input
	DDRB  &= ~(1<<PB1);    // PB1 is AIN1 -- make it an input
	DDRB  |=  (1<<PB6);    // PB6 pin as output for eye LED
	DDRB  |=  (1<<PB7);    // PB7 pin as output for eye LED
	
	//Set port B default voltage
	PORTB &= ~(1<<PB0);    // no Pull-up on PB0
	PORTB &= ~(1<<PB1);    // no Pull-up on PB1
	PORTB &= ~(1<<PB6);    // Set PB6 LED is Off
	PORTB &= ~(1<<PB7);    // Set PB7 LED is Off

	//Set external interrupter settings
	PCMSK |= (1<<PIND2);   //What is it?
	MCUCR = (1<<ISC01) | (1<<ISC00);   // INT0 will be interrupt by rising side of impulse
	MCUCR = (1<<ISC11) | (1<<ISC10);   // INT1 will be interrupt by rising side of impulse
	GIMSK |= (1<<INT0);   // Enable int0 interrupt
	GIMSK |= (1<<INT1);   // Enable int1 interrupt

	//Set comparator settings
	ACSR  |=  (1<<ACI);    // clear Analog Comparator interrupt
	ACSR  |=
	(0<<ACD)   |           // Comparator ON
	(0<<ACBG)  |           // Disconnect 1.23V reference from AIN0 (use AIN0 and AIN1 pins)
	(1<<ACIE)  |           // Comparator Interrupt enabled
	(0<<ACIC)  |           // input capture disabled
	(1<<ACIS1) |           // set interrupt bit on positive edge
	(1<<ACIS0);            // (ACIS1 and ACIS0 == 11), so comparator do interrupt by rising side of impulse
	
	sei();                 // enable global interrupts
}

// Read counters values from EEPROM.
void initCounters(){
	waterCounter = eeprom_read_dword ((uint32_t*)waterCounterAddress);
	electricCounter = eeprom_read_dword ((uint32_t*)electricCounterAddress);
	
	// TODO: Drop this stub.
	waterCounter = 0;
	electricCounter = 0;
}


void USART_Init( unsigned int baud )
{
	/* Set baud rate */
	UBRRH = (unsigned char)(baud>>8);
	UBRRL = (unsigned char)baud;
	/* Enable receiver and transmitter */
	UCSRB = (1<<RXEN)|(1<<TXEN);
	// Режим 8 бит, 2 стоповыx бита
	UCSRC = (1<<USBS)|(3<<UCSZ0);
}

unsigned char USART_Receive( void ) //Функция приема данных
{
	while (!(UCSRA & (1<<RXC))); //Ожидание приема символа
	return UDR; //Возврат содержимого буфера приема символа
}

void USART_Transmit( unsigned char data ) //Функция отправки данных
{
	while (!(UCSRA & (1<<UDRE)) ); //Ожидание опустошения буфера приема
	
	UDR = data; //Начало передачи данных
}


int main(void)
{
    	initHardware();	
	initCounters();
	
	const unsigned int rate = 9600;
	const unsigned int BAUDDIVIDER= F_CPU/(16*rate)-1;
	USART_Init( BAUDDIVIDER );
    USART_Transmit('h');
	USART_Transmit('i');
	USART_Transmit(0x65);

	while(1)
    {
		 USART_Transmit( USART_Receive() );
    }
}
Подключил в протеусе виртуальный терминал и.... ничего. При эмуляции видно, что МК что-то шлет(мигает tx-ножка), но терминал ниче не показывает. Если переключить терминал в HEX-режим, то на него приходят только нули.

Пытался загуглить, народ рекомендует отключить предделитель. Пробовал(CLKPR &= ~(1<<CLKPCE);) - не помогло.
Кто может подсказать где кроется проблема?

Спасибо.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

Скорость передачи и приема одинаковая? Уверен? Нули приходят... кстати, инверсию в терминале надо потрогать, т.к. терминал в протеусе универсальный - он как с COM портом работает так и с UART - отличаются они лишь инверсией сигналов.

Выдавать нули терминал будет если КОНТРОЛЛЕР передает слишком медленно - причем раз в 10-20 медленней чем настроен терминал, тогда каждый импульс будет рассматриваться как стартовый а дальше естественно терминал принимает 8 нулей прежде чем твой контроллер может переключить выход на "1".

Проверить это гениально просто - подключи к RX и TX осциллограф. Сразу увидишь что идет с контроллера, и нажав кнопку в терминале узнаешь с какой скоростью передает/принимает терминал.

Ну и самое очевидное, в протеусе вы наверняка не учли фьюз-биты установленные по-умолчанию, там стоит CKDIV8 - он делит тактовую частоту на 8 со всеми вытекающими.

Дальше.

это непотребство переписать:
DDRB &= ~(1<<PB0); // PB0 is AIN0 -- make it an input
DDRB &= ~(1<<PB1); // PB1 is AIN1 -- make it an input

в таком варианте в DDRB окажется только последнее значение, лучше вообще просто укажи двоичное значение с нужной маской. И все остальные подобные места тоже перепиши.
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Alexeyslav писал(а):Скорость передачи и приема одинаковая? Уверен? Нули приходят... кстати, инверсию в терминале надо потрогать, т.к. терминал в протеусе универсальный - он как с COM портом работает так и с UART - отличаются они лишь инверсией сигналов.
В протеусе:
CKDIV8 = programmed
CKSEL = 0100(8MHz)
SUT=10

Т.е. частота=1 MHz
Исходя из чего я считаю baud = 1000000/(16*9600)+1

На терминале 9600 стоит.

Сейчас всемремя віводит И вместо h.

По осцилографу видно, что частота на порядок отличается.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

У тебя формула верная, да... но ты используешь константу F_CPU = 8 000 000, а реально у тебя еще делитель задействован! учти его в формуле, либо F_CPU = 1 000 000 тогда все сойдется.
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Простите, совсем забыл указать, что F_CPU я изменил на 1000000, т.е. проблема оставется и при корректном F_CPU
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

Тогда даташит, для тактовой частоты найти делитель и подставить его. В конце концов, подобрать точное значение по осциллограмме и дальше попытаться анализировать во сколько раз эта частота отличается от рассчетной, и откуда взялся этот коэфициент. Может все-таки в протеусе делитель не активен?
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Мне кажется что это проблема в терминале. Я создал 2 терминала с одинаковыми настройками и они друг-друга не понимают 0_0.(Символ доходит со смещением)

Это на 2х стоп-битах. На одном вроде нормально.
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Заработало!

Я просто изменил битрэйд с 9600 на 110. И в протеусе терминалу выствил стоп-бит=1(хотя в МК настроено 2)
Формулы и расчеты те-же.

Странно это конечно...
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

А кто может подсказать как увеличить время симуляции в протеусе?
А то он симулирует работу устройства около часа и останавливается :(
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение Alexeyslav »

А зачем больше? Симулируй с более быстрыми сигналами, а длительные тесты уже после отладки на коротких симуляциях и на реальном железе.
andrey_ims
Открыл глаза
Сообщения: 73
Зарегистрирован: Пн июл 01, 2013 22:38:09

Re: Счетчик импульсов с UART(снятие показаний)

Сообщение andrey_ims »

Alexeyslav писал(а):
это непотребство переписать:
DDRB &= ~(1<<PB0); // PB0 is AIN0 -- make it an input
DDRB &= ~(1<<PB1); // PB1 is AIN1 -- make it an input

в таком варианте в DDRB окажется только последнее значение, лучше вообще просто укажи двоичное значение с нужной маской. И все остальные подобные места тоже перепиши.
Кстати, хотел спросить почему это непотребство? Почему там окажется только последнее значение? Я же использую составное присвоение!
Ответить

Вернуться в «Разные вопросы по МК»