Я вот думал собрать транзисторный ключ, питающий МК, но что-то не могу понять как в протеусе сделать питание МК на автоматическим, в протеусе даже ножки питания не показаныzöner писал(а): Также можно писать только при пропадании питания - компаратором или АЦП ловить момент падения питания, писать данные, и ложиться спать. Для замедления пропадания - большой электролит или ионистор по питанию.
Счетчик импульсов с UART(снятие показаний)
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
- Реклама
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Счетчик импульсов с UART(снятие показаний)
Дык, так и надо делать — писать в ОЗУ, а при пропадании питания быстренько сохранять в ЕЕПРОМ. Где-то здесь обсасывалась эта тема.andrey_ims писал(а):На сколько это будет надежно?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Наверное эта тема.Gudd-Head писал(а): Дык, так и надо делать — писать в ОЗУ, а при пропадании питания быстренько сохранять в ЕЕПРОМ. Где-то здесь обсасывалась эта тема.
Почитал ее и некоторые другие, схожие темы, но вопросы остались:
1)Как происходит работа с компаратором? Как я понял, если напряжение до стабилизатора не равно напряжению после стабилизатора то происходит прерывание, в котором происходит сохранение данных в память, так?У кого нибудь есть пример кода на Си?
2)Будет ли работать такая схема:
Спасибо.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Счетчик импульсов с UART(снятие показаний)
Чем обычный диод вместо транзистора не устраивает? Почему в "-" цепь?
что будет с программой при кратковременном проседании напряжения?
что будет с программой при кратковременном проседании напряжения?
Re: Счетчик импульсов с UART(снятие показаний)
Хм... На базу "плюс" будет приходить пока кондёр не разрядиться?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Реклама
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Счетчик импульсов с UART(снятие показаний)
Нет, конкретно про запись в ЕЕПРОМ при пропадании питания.andrey_ims писал(а):Наверное эта тема.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Та ну может и диод, я просто весьма поверхностно в теме разбираюсьAlexeyslav писал(а):Чем обычный диод вместо транзистора не устраивает? Почему в "-" цепь?
что будет с программой при кратковременном проседании напряжения?
Вот поэтому я пытаюсь максимально просто сделать. Пока не получается, примеры везде сложные
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Счетчик импульсов с UART(снятие показаний)
Максимально просто - это м/с часов со встроенной SRAM, одной батарейки CR2032 хватит на 5 лет непрерывного поддержания памяти. Но поддержание это хорошо... до тех пор пока свет не начинают отключать часто и надолго. Тогда просто "сохранить" в памяти уже не катит. Ведь в отсутствие электричества счетчики считают, а контроллер совсем не в курсе - он пока без питания держит в себе значение при сохранении... а счетчики-то тикают!
Есть такие теплосчетчики - подсчитывают калории ушедшие на отопление дома, так вот они имеют встроенную литиевую батарею с минимальным ресурсом в 10 лет! Счетчику не нужно питание, он в течение 10 лет считать будет.
В принципе такое можно реализовать и на контроллере - но он должен большую часть времени находится в глубокой спячке, просыпаясь только по сигналам прерывания от датчиков и при получении команды на считывание данных. Тогда такая схема сможет работать и считать непрерывно, даже на ионисторе. Если разорится на парочку ионисторов 200Ф@2.7В - то такая схема сможет полнофункционально работать без питания сутки, двое... вобщем считать надо. И в виду необходимости экономии - прийдется просчитать минимальную необходимую тактовую частоту и найти нужный кварц, так чтобы его деление на целое число могло дать 9600. Вроде бы 32768 часовой должен подойти.
Либо...поставить микросхемы-часы вроде PCF8535 по количеству каналов регистрации и включить их в режиме счета импульсов - они смогут считать импульсы независимо от работы контроллера лишь от резервного источника. Но есть один ньюанс - датчики ведь "сухой контакт" и для них нужна подтяжка... так вот, она будет потреблять энергии в 100 раз больше чем сами счетчики, особенно если датчики будут большую часть времени в состоянии "замкнуто".
Есть такие теплосчетчики - подсчитывают калории ушедшие на отопление дома, так вот они имеют встроенную литиевую батарею с минимальным ресурсом в 10 лет! Счетчику не нужно питание, он в течение 10 лет считать будет.
В принципе такое можно реализовать и на контроллере - но он должен большую часть времени находится в глубокой спячке, просыпаясь только по сигналам прерывания от датчиков и при получении команды на считывание данных. Тогда такая схема сможет работать и считать непрерывно, даже на ионисторе. Если разорится на парочку ионисторов 200Ф@2.7В - то такая схема сможет полнофункционально работать без питания сутки, двое... вобщем считать надо. И в виду необходимости экономии - прийдется просчитать минимальную необходимую тактовую частоту и найти нужный кварц, так чтобы его деление на целое число могло дать 9600. Вроде бы 32768 часовой должен подойти.
Либо...поставить микросхемы-часы вроде PCF8535 по количеству каналов регистрации и включить их в режиме счета импульсов - они смогут считать импульсы независимо от работы контроллера лишь от резервного источника. Но есть один ньюанс - датчики ведь "сухой контакт" и для них нужна подтяжка... так вот, она будет потреблять энергии в 100 раз больше чем сами счетчики, особенно если датчики будут большую часть времени в состоянии "замкнуто".
Re: Счетчик импульсов с UART(снятие показаний)
Напряжение ПОСЛЕ никогда не равно напряжению ДО стаба, кроме случая -- стаб пробитКак я понял, если напряжение до стабилизатора не равно напряжению после стабилизатора то происходит прерывание
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Начал пробовать работать с UART.
Взял пример из даташита и немного доточил:
Подключил в протеусе виртуальный терминал и.... ничего. При эмуляции видно, что МК что-то шлет(мигает tx-ножка), но терминал ниче не показывает. Если переключить терминал в HEX-режим, то на него приходят только нули.
Пытался загуглить, народ рекомендует отключить предделитель. Пробовал(CLKPR &= ~(1<<CLKPCE);) - не помогло.
Кто может подсказать где кроется проблема?
Спасибо.
Взял пример из даташита и немного доточил:
Спойлер
Код: Выделить всё
#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() );
}
}Пытался загуглить, народ рекомендует отключить предделитель. Пробовал(CLKPR &= ~(1<<CLKPCE);) - не помогло.
Кто может подсказать где кроется проблема?
Спасибо.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Счетчик импульсов с UART(снятие показаний)
Скорость передачи и приема одинаковая? Уверен? Нули приходят... кстати, инверсию в терминале надо потрогать, т.к. терминал в протеусе универсальный - он как с 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 окажется только последнее значение, лучше вообще просто укажи двоичное значение с нужной маской. И все остальные подобные места тоже перепиши.
Выдавать нули терминал будет если КОНТРОЛЛЕР передает слишком медленно - причем раз в 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(снятие показаний)
В протеусе: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(снятие показаний)
У тебя формула верная, да... но ты используешь константу F_CPU = 8 000 000, а реально у тебя еще делитель задействован! учти его в формуле, либо F_CPU = 1 000 000 тогда все сойдется.
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Простите, совсем забыл указать, что F_CPU я изменил на 1000000, т.е. проблема оставется и при корректном F_CPU
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Счетчик импульсов с UART(снятие показаний)
Тогда даташит, для тактовой частоты найти делитель и подставить его. В конце концов, подобрать точное значение по осциллограмме и дальше попытаться анализировать во сколько раз эта частота отличается от рассчетной, и откуда взялся этот коэфициент. Может все-таки в протеусе делитель не активен?
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Мне кажется что это проблема в терминале. Я создал 2 терминала с одинаковыми настройками и они друг-друга не понимают 0_0.(Символ доходит со смещением)
Это на 2х стоп-битах. На одном вроде нормально.
Это на 2х стоп-битах. На одном вроде нормально.
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Заработало!
Я просто изменил битрэйд с 9600 на 110. И в протеусе терминалу выствил стоп-бит=1(хотя в МК настроено 2)
Формулы и расчеты те-же.
Странно это конечно...
Я просто изменил битрэйд с 9600 на 110. И в протеусе терминалу выствил стоп-бит=1(хотя в МК настроено 2)
Формулы и расчеты те-же.
Странно это конечно...
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
А кто может подсказать как увеличить время симуляции в протеусе?
А то он симулирует работу устройства около часа и останавливается
А то он симулирует работу устройства около часа и останавливается
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Счетчик импульсов с UART(снятие показаний)
А зачем больше? Симулируй с более быстрыми сигналами, а длительные тесты уже после отладки на коротких симуляциях и на реальном железе.
-
andrey_ims
- Открыл глаза
- Сообщения: 73
- Зарегистрирован: Пн июл 01, 2013 22:38:09
Re: Счетчик импульсов с UART(снятие показаний)
Кстати, хотел спросить почему это непотребство? Почему там окажется только последнее значение? Я же использую составное присвоение!Alexeyslav писал(а):
это непотребство переписать:
DDRB &= ~(1<<PB0); // PB0 is AIN0 -- make it an input
DDRB &= ~(1<<PB1); // PB1 is AIN1 -- make it an input
в таком варианте в DDRB окажется только последнее значение, лучше вообще просто укажи двоичное значение с нужной маской. И все остальные подобные места тоже перепиши.


