Например TDA7294

Форум РадиоКот • Просмотр темы - Запись\Чтение EEPROM или flash.
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Пт апр 19, 2024 00:00:46

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 16 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 03:18:39 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Всем здравствуйте.

Возник такой вопрос куда лучше писать энергонезависимую информацию, в моем примере это значение переменной нагрева + состояние вкл/выкл. Я читал что Сам EEPROM ограничен по записям. И где то натыкался на статейку что можно писать во флешь память самого мк.
Просто опыта по МК еще не имею вот и нехочу угробить мк постоянной перезаписью ЕЕПРОМ.
И еще есть вопросик как правильно организовать плавное включение ( увеличение value до save) ,save планирую писать в eeprom.

Код:
Спойлер
Код:
//***************************************************************************
//  Target(s)...: IDE: AVR AtmelStudio 6.2 MC:Attiny26L
//***************************************************************************
#define F_CPU   8000000          //Hz

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>

//настройка параметров работы функций
#define BTN_LOCK_TIME      30               /*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME      1000            /*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/

//настройки портов
#define BTN_PORT         PORTB            /*порт чтения кнопок*/
#define BTN_DDR            DDRB
#define BTN_PIN            PINB

#define BTN_LINE_UP      (1<<4)            /*пины чтения кнопок*/
#define BTN_LINE_DN      (1<<3)
#define BTN_LINE_POWER   (1<<5)
//глобальные переменные
volatile uint8_t BtnFlags;//байт флагов нажатия кнопки
#define BTN_SHRT_UP         (1<<0)         /*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN         (1<<1)         /*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER      (1<<2)         /*бит короткого нажатия кнопки left*/
#define BTN_LONG_UP         (1<<4)         /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN         (1<<5)         /*бит длинного нажатия кнопки dn*/
//----------
#define  En_INT0      GIMSK|=(1<<6);
#define  Dis_INT0     GIMSK&=~(1<<6);     
volatile unsigned char fPower = 0;
volatile unsigned char data1 = 0;
volatile unsigned char data2 = 0;
volatile unsigned char value = 0;

void init_io();
void segchar(unsigned char seg);
//Значения для открывания триака.
const unsigned char TRIAK[]PROGMEM = {
         160,156,155,154,150,148,146,144,142,140,
         139,137,135,131,129,127,125,123,122,120,
         119,118,117,116,115,114,113,112,111,110,
         109,108,107,106,105,104,103,102,101,100,
         99,98,97,96,95,94,93,92,91,90,
         89,88,87,86,85,84,83,82,81,80,
         79,78,77,76,75,74,73,72,71,70,
         69,68,67,66,65,64,63,62,61,60,
         59,58,57,56,55,54,53,52,51,50,
         49,48,47,45,43,41,40,37,35,33};
//----------         
//настройка внешнего прерывния INT0
void int0_init( void )
{
   //настраиваем на срабатывание INT0 по переднему фронту
   MCUCR |= (1<<ISC01)|(0<<ISC00);
   //разрешаем внешнее прерывание INT0
   En_INT0
}
 //----------
ISR(TIMER1_CMPA_vect)
{
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
}
//----------
//функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
   BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//на ввод
   BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//подтяжка вкл
}
//----------
//функция чтения данных о нажатии кнопок
char BtnGet (void)
{
   cli();
   char temp = BtnFlags;
   BtnFlags = 0;
   sei();
   return temp;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
   static unsigned char BtnLockBit;         //ащелка (защита от дребезга)
   static unsigned char BtnLockCoun;         //счетчик защелки (защита от дребезга)
   static unsigned char BtnLongCoun;         //счетчик длинного нажатия
   static unsigned char BtnLastState;         //последнее состояние кнопок перед отпусканием

   char mask = 0;
   if (! (BTN_PIN & BTN_LINE_UP))      mask = BTN_SHRT_UP;
   if (! (BTN_PIN & BTN_LINE_DN))      mask = BTN_SHRT_DN;
   if (! (BTN_PIN & BTN_LINE_POWER))   mask = BTN_SHRT_POWER;;

   if (mask){                           //опрос состояния кнопки
      if (BtnLockCoun < (BTN_LOCK_TIME/10)){   //клавиша нажата
         BtnLockCoun++;
         return;                        //защелка еще не дощитала - возврат
      }
      BtnLastState = mask;
      BtnLockBit =1;                     //нажатие зафиксировано
      if (BtnLongCoun >= (BTN_LONG_TIME/10))
      return;                        //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
      BtnFlags |= (BtnLastState<<4);         //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
   }
   else{                              //клавиша отжата
      if (BtnLockCoun){
         BtnLockCoun --;
         return;                        //защелка еще не обнулилась - возврат
      }
      if (! BtnLockBit)                  //СТАТИЧЕСКИЙ ВОЗВРАТ
      return;
      BtnLockBit =0;                     //отжатие зафиксировано
      if (BtnLongCoun < (BTN_LONG_TIME/10))
      BtnFlags |= BtnLastState;         //установка бита короткого нажатия
      BtnLongCoun = 0;               //сброс счетчика длительности нажатия
   }
}
//----------

//Прерывания по инт0 от синхра импулса
static unsigned char count = 0;
ISR(INT0_vect)
{
   if (fPower==1)
   {
   OCR1A = pgm_read_byte(&(TRIAK[value]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;
   //зажигаем следующий разр§д
   if (count == 0)
   {
      if (data2>0) //гасим старший разряд , если он == 0 .
      {
         segchar(data2);
         PORTB &= ~(1<<2);
      }
      else
      {
         PORTB |=(1<<PB2);
      }
   }
   if (count == 1)
   {
      segchar(data1);
      PORTB &= ~(1<<0);
   }
   count++;
   if (count == 2) {count = 0;}
   }
   else
   {
   OCR1A = pgm_read_byte(&(TRIAK[0]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;      
   }
   BtnExe();
}

int main(void)
{
   unsigned char save=0;
   init_io();
   sei();
   int0_init();
   BtnInit();
   while(1)
   {
      char BtnMask = BtnGet ();
      //одиночное нажатие +
      if ((BtnMask == BTN_SHRT_UP) & (value < 99))     
      {
         value++;
      }
      //одиночное нажатие -
      if ((BtnMask == BTN_SHRT_DN) & (value > 0))
      {
         value--;
      }
      //одиночное нажатие Power
      if (BtnMask == BTN_SHRT_POWER)
      {
         if (fPower==0)
         {
            value=save;
         }
         if (fPower==1)
         {
            save=value;
            value=0;
         }
         fPower++;
         if (fPower==2)
         {
            fPower=0;
         }
      }
      //Удержание +
      if ((BtnMask == BTN_LONG_UP) & (value < 99))
      {
         while ((!(PINB&0b00010000))& (value < 99))
         {
            value++;
            _delay_ms(100);
         }
      }
      //Удержание -
      if ((BtnMask == BTN_LONG_DN) & (value > 0))
      {
         while ((!(PINB&0b00001000))& (value > 0))
         {
            value--;
            _delay_ms(100);
         }
      }
   }
   return 0;
}

//Коды сегментов
void segchar (unsigned char seg)
{
   switch (seg)
   {
      case 1: PORTA = 0b01111100; break;
      case 2: PORTA = 0b10000100; break;
      case 3: PORTA = 0b01000100; break;
      case 4: PORTA = 0b01101000; break;
      case 5: PORTA = 0b01000010; break;
      case 6: PORTA = 0b00000010; break;
      case 7: PORTA = 0b01110100; break;
      case 8: PORTA = 0b00000000; break;
      case 9: PORTA = 0b01000000; break;
      case 0: PORTA = 0b00010000; break;
   }
}

void init_io()
{
   //порт, к которому подкл. сегменты
   PORTA = 0xff;
   DDRA = 0xff;
   //порт, к которому подкл. катод
   DDRB |=(1<<0)|(1<<1)|(1<<2);
   PORTB =0x00;
   //Иницилизация прерываний по совпадению Т1.
   TIMSK |=(1<<OCIE1A);
   TCCR1B |=/*(1<<CTC1)*/(0<<CS10)|(1<<CS11)|(0<<CS12)|(1<<CS13);   
   OCR1A=0xFF;
}


Всех с праздником всемирного дня электросвязи и информационного общества. :beer:

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 04:27:32 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2694
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
7seg писал(а):
Я читал что Сам EEPROM ограничен по записям. И где то натыкался на статейку что можно писать во флешь память самого мк.
Лучше читать ДШ или хотя бы сверять их со статьями.
Изображение
Для того чтобы записать байт во Флеш придется стереть всю страницу.


Вложения:
еепром.png [17.77 KiB]
Скачиваний: 897

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 04:43:00 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1384
Рейтинг сообщения: 3
Алгоритм работы с EEPROM: при включении, сбросе считываются значения в ОЗУ и работаем с данными в ОЗУ. Один пин мк отдаем по контроль питания, как только пропало питание скидываем данные в EEPROM. Такой алгоритм подразумевает использование ионистора либо конденсаторы большой емкости на бп. Следует учитывать, что запись одного байта в EEPROM длится 8 мс.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 05:16:57 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
А при записи в ЕЕПРОМ мк входит в ожидание как при _delay или программа выполняется дальше ?

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 06:59:57 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Программа выполняется дальше, но если до окончания цикла записи вы вдруг решите снова что-то записать, можете похерить данные в EEPROM.
А вообще: почему бы вам не читать даташит?
Ну и обязательно пользуйтесь библиотечными функциями, они хотя бы гарантируют, что цикл записи не будет прерван (но снова напомню, что документацию читать надо, ибо эти функции не рассчитаны на применение и в прерываниях, и в главном цикле).

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 07:28:21 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2694
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
ARV писал(а):
ибо эти функции не рассчитаны на применение и в прерываниях, и в главном цикле).
А где ж их использовать то тогда? :))
ARV писал(а):
обязательно пользуйтесь библиотечными функциями
Это совет только для тех кто ДШ не читает. Операция записи в ЕЕПРОМ несложная.

7seg, напишите парочку несложных проектов на ассемблере. Это даст понимание МК. И ДШ тут совсем придется читать. :)

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 07:47:30 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Z_h_e писал(а):
А где ж их использовать то тогда?
и там и там - означает одновременно :) т.е. только в прерываниях или только в главном цикле - пожалуйста, ну а сразу всюду - это надо быть хорошим программистом, тогда тоже можно.

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

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 08:36:16 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2694
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Не понял что Вы имели ввиду одновременное использование. Хотя я и тут не вижу проблемы. В прерывпниях их не использовал. Интересно, эти функции учитывают что в обработчтке не надо трогать маску глобального разрешения прерываний.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 09:00:48 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Z_h_e писал(а):
Хотя я и тут не вижу проблемы
а когда умеешь что-то делать, проблем обычно и не бывает. они бывают, когда не умеешь.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 09:31:19 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2694
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Только что попробовал использовать функцию eeprom_write_byte((uint8_t*)0,0); в прерывании и поглядеть во что скомпилировалось (AS6). Код конечно сильно избыточен, есть команды которые совсем непонятно зачем включены (избыточность это отдельная тема). Я хотел проверить, не включит ли эта функция прерывания после запрета. Все нормально в этом плане, функция сохраняет SREG, только затем идет запрет, а после команды записи восстановление SREG.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 10:36:34 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Да ведь дело не в том, что прерывание или избыточность, а в том, что функции работают со статическими счетчиками и вспомогательными переменными, что может нарушить их работу, если во время работы "первой" функции записи произойдет прерывание, внутри которого эта же функция будет вызвана повторно, это нарушит работу "первой" функции.

Нереентерабельная функция означает, что она не допускает рекурсивный вход в себя, т.е. вход до выхода.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 11:08:17 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Чет пока лажа с еепром пока что получается. правильно ли я пытаюсь работать с еепром можете подсказать ?

код:
Спойлер
Код:
//***************************************************************************
//  Author(s)...: Плотников Андрей Игоревич
//  Target(s)...: IDE: AVR AtmelStudio 6.2 MC:Attiny26L
//  Data........: 15.05.17
//***************************************************************************
#define F_CPU   8000000          //Hz

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//FOR EEPROM
uint16_t my_var=0;
uint16_t eeprom_data EEMEM;
uint16_t eeprom_read_word (const uint16_t *__p); //- прочитать слово (2 байта)
void eeprom_write_word (uint16_t *__p, uint16_t __value); //- запись слова (2 байта)

//настройка параметров работы функций
#define BTN_LOCK_TIME      30               /*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME      1000            /*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/

//настройки портов
#define BTN_PORT         PORTB            /*порт чтения кнопок*/
#define BTN_DDR            DDRB
#define BTN_PIN            PINB

#define BTN_LINE_UP      (1<<4)            /*пины чтения кнопок*/
#define BTN_LINE_DN      (1<<3)
#define BTN_LINE_POWER   (1<<5)
//глобальные переменные
volatile uint8_t BtnFlags;//байт флагов нажатия кнопки
#define BTN_SHRT_UP         (1<<0)         /*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN         (1<<1)         /*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER      (1<<2)         /*бит короткого нажатия кнопки left*/
#define BTN_LONG_UP         (1<<4)         /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN         (1<<5)         /*бит длинного нажатия кнопки dn*/
//----------
#define  En_INT0      GIMSK|= (1<<6);
#define  Dis_INT0     GIMSK&= ~(1<<6);   

volatile unsigned char save=0; 
volatile unsigned char fPower = 0;
volatile unsigned char data1 = 0;
volatile unsigned char data2 = 0;
volatile unsigned char value = 0;

void init_io();
void segchar(unsigned char seg);
//Значения для открывания триака.
const unsigned char TRIAK[]PROGMEM = {
         160,156,155,154,150,148,146,144,142,140,
         139,137,135,131,129,127,125,123,122,120,
         119,118,117,116,115,114,113,112,111,110,
         109,108,107,106,105,104,103,102,101,100,
         99,98,97,96,95,94,93,92,91,90,
         89,88,87,86,85,84,83,82,81,80,
         79,78,77,76,75,74,73,72,71,70,
         69,68,67,66,65,64,63,62,61,60,
         59,58,57,56,55,54,53,52,51,50,
         49,48,47,45,43,41,40,37,35,33};
//----------         
//настройка внешнего прерывния INT0
void int0_init( void )
{
   //настраиваем на срабатывание INT0 по переднему фронту
   MCUCR |= (1<<ISC01)|(0<<ISC00);
   //разрешаем внешнее прерывание INT0
   En_INT0
}
 //----------
ISR(TIMER1_CMPA_vect)
{
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
}
//----------
//функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
   BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//на ввод
   BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//подтяжка вкл
}
//----------
//функция чтения данных о нажатии кнопок
char BtnGet (void)
{
   cli();
   char temp = BtnFlags;
   BtnFlags = 0;
   sei();
   return temp;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
   static unsigned char BtnLockBit;         //ащелка (защита от дребезга)
   static unsigned char BtnLockCoun;         //счетчик защелки (защита от дребезга)
   static unsigned char BtnLongCoun;         //счетчик длинного нажатия
   static unsigned char BtnLastState;         //последнее состояние кнопок перед отпусканием

   char mask = 0;
   if (! (BTN_PIN & BTN_LINE_UP))      mask = BTN_SHRT_UP;
   if (! (BTN_PIN & BTN_LINE_DN))      mask = BTN_SHRT_DN;
   if (! (BTN_PIN & BTN_LINE_POWER))   mask = BTN_SHRT_POWER;;

   if (mask){                           //опрос состояния кнопки
      if (BtnLockCoun < (BTN_LOCK_TIME/10)){   //клавиша нажата
         BtnLockCoun++;
         return;                        //защелка еще не дощитала - возврат
      }
      BtnLastState = mask;
      BtnLockBit =1;                     //нажатие зафиксировано
      if (BtnLongCoun >= (BTN_LONG_TIME/10))
      return;                        //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
      BtnFlags |= (BtnLastState<<4);         //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
   }
   else{                              //клавиша отжата
      if (BtnLockCoun){
         BtnLockCoun --;
         return;                        //защелка еще не обнулилась - возврат
      }
      if (! BtnLockBit)                  //СТАТИЧЕСКИЙ ВОЗВРАТ
      return;
      BtnLockBit =0;                     //отжатие зафиксировано
      if (BtnLongCoun < (BTN_LONG_TIME/10))
      BtnFlags |= BtnLastState;         //установка бита короткого нажатия
      BtnLongCoun = 0;               //сброс счетчика длительности нажатия
   }
}
//----------
//Прерывания по ИНТ0 от синхра импулса
static unsigned char count = 0;
static unsigned char time_eeprom = 0;
ISR(INT0_vect)
{
   if (fPower==1)
   {
   OCR1A = pgm_read_byte(&(TRIAK[value]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;
   //зажигаем следующий разр§д
   if (count == 0)
   {
      if (data2>0) //гасим старший разряд , если он == 0 .
      {
         segchar(data2);
         PORTB &= ~(1<<2);
      }
      else
      {
         PORTB |=(1<<PB2);
      }
   }
   if (count == 1)
   {
      segchar(data1);
      PORTB &= ~(1<<0);
   }
   count++;
   if (count == 2) {count = 0;}
   }
   else
   {
   OCR1A = pgm_read_byte(&(TRIAK[0]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;      
   }
   if (time_eeprom==9){
      if (!(save==value))
      {
         my_var=value;
         eeprom_write_word (&eeprom_data, my_var);
      }
   }
   if (time_eeprom==10){time_eeprom=0;}
   BtnExe();
}
//----------
//----------
int main(void)
{
   //читаем байт из eeprom
   my_var = eeprom_read_word(&eeprom_data);
   _delay_ms(1000);
   save=my_var;
   init_io();
   sei();
   int0_init();
   BtnInit();
   unsigned char OneEn=0;
   while(1)
   {
      char BtnMask = BtnGet ();
      //одиночное нажатие +
      if ((BtnMask == BTN_SHRT_UP) & (value < 99))     
      {
         value++;
      }
      //одиночное нажатие -
      if ((BtnMask == BTN_SHRT_DN) & (value > 0))
      {
         value--;
      }
      //одиночное нажатие Power
      if (BtnMask == BTN_SHRT_POWER)
      {
         if (fPower==0)
         {
            value=save;
            //OneEn=0;
         }
         if (fPower==1)
         {
            save=value;
            value=0;
            OneEn=0;
         }
         if (fPower==2)
         {
            fPower=0;
            //OneEn=0;
         }
         fPower++;
      }
      //Удержание +
      if ((BtnMask == BTN_LONG_UP) & (value < 99))
      {
         while ((!(PINB&0b00010000))& (value < 99))
         {
            value++;
            _delay_ms(100);
         }
      }
      //Удержание -
      if ((BtnMask == BTN_LONG_DN) & (value > 0))
      {
         while ((!(PINB&0b00001000))& (value > 0))
         {
            value--;
            _delay_ms(100);
         }
      }
      if ((fPower==1)&(OneEn==0))
      {
         while ((value<save)& (value < 99))
         {
            value++;
            _delay_ms(100);
         }
      }
      if (value==save)
      {
         OneEn=1;
      }
   }
   return 0;
}
//----------
//Коды сегментов
void segchar (unsigned char seg)
{
   switch (seg)
   {
      case 1: PORTA = 0b01111100; break;
      case 2: PORTA = 0b10000100; break;
      case 3: PORTA = 0b01000100; break;
      case 4: PORTA = 0b01101000; break;
      case 5: PORTA = 0b01000010; break;
      case 6: PORTA = 0b00000010; break;
      case 7: PORTA = 0b01110100; break;
      case 8: PORTA = 0b00000000; break;
      case 9: PORTA = 0b01000000; break;
      case 0: PORTA = 0b00010000; break;
   }
}
//----------
void init_io()
{
   //порт, к которому подкл. сегменты
   PORTA = 0xff;
   DDRA = 0xff;
   //порт, к которому подкл. катод
   DDRB |=(1<<0)|(1<<1)|(1<<2);
   PORTB =0x00;
   //Иницилизация прерываний по совпадению Т1.
   TIMSK |=(1<<OCIE1A);
   TCCR1B |=/*(1<<CTC1)*/(0<<CS10)|(1<<CS11)|(0<<CS12)|(1<<CS13);   
   OCR1A=0xFF;
}

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 11:14:54 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
В простыне кода разбираться влом, но настоятельно рекомендую применять вместо eeprom_write_xxxx функции eeprom_update_xxxx
Последние функции проверяют содержимое ячеек на совпадение и не перезаписывают те, которые в этом не нуждаются, чем повышают ресурс EEPROM.
В остальном их действие аналогично.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 11:41:38 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
eeprom_write_xxxx заменил на eeprom_update_xxxx )

Добавлено after 12 minutes 20 seconds:
вроде бы получилось работает, но не совсем гладко, иногда сохраняет на 1 меньше почему то )) и плавное повышение яркости не робит . буду дальше разбираться.

Спойлер
Код:
//***************************************************************************
//  Target(s)...: IDE: AVR AtmelStudio 6.2 MC:Attiny26L
//***************************************************************************
#define F_CPU   8000000          //Hz

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//FOR EEPROM
uint16_t my_var=0;
uint16_t eeprom_data EEMEM;
uint16_t eeprom_read_word (const uint16_t *__p); //- прочитать слово (2 байта)
void eeprom_write_word (uint16_t *__p, uint16_t __value); //- запись слова (2 байта)
void eeprom_update_word (uint16_t *__p, uint16_t __value);

//настройка параметров работы функций
#define BTN_LOCK_TIME      30               /*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME      1000            /*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/

//настройки портов
#define BTN_PORT         PORTB            /*порт чтения кнопок*/
#define BTN_DDR            DDRB
#define BTN_PIN            PINB

#define BTN_LINE_UP      (1<<4)            /*пины чтения кнопок*/
#define BTN_LINE_DN      (1<<3)
#define BTN_LINE_POWER   (1<<5)
//глобальные переменные
volatile uint8_t BtnFlags;//байт флагов нажатия кнопки
#define BTN_SHRT_UP         (1<<0)         /*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN         (1<<1)         /*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER      (1<<2)         /*бит короткого нажатия кнопки left*/
#define BTN_LONG_UP         (1<<4)         /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN         (1<<5)         /*бит длинного нажатия кнопки dn*/
//----------
#define  En_INT0      GIMSK|= (1<<6);
#define  Dis_INT0     GIMSK&= ~(1<<6);   
volatile unsigned char save=0; 
volatile unsigned char fPower = 0;
volatile unsigned char data1 = 0;
volatile unsigned char data2 = 0;
volatile unsigned char value = 0;

void init_io();
void segchar(unsigned char seg);
//Значения для открывания триака.
const unsigned char TRIAK[]PROGMEM = {
         160,156,155,154,150,148,146,144,142,140,
         139,137,135,131,129,127,125,123,122,120,
         119,118,117,116,115,114,113,112,111,110,
         109,108,107,106,105,104,103,102,101,100,
         99,98,97,96,95,94,93,92,91,90,
         89,88,87,86,85,84,83,82,81,80,
         79,78,77,76,75,74,73,72,71,70,
         69,68,67,66,65,64,63,62,61,60,
         59,58,57,56,55,54,53,52,51,50,
         49,48,47,45,43,41,40,37,35,33};
//----------         
//настройка внешнего прерывния INT0
void int0_init( void )
{
   //настраиваем на срабатывание INT0 по переднему фронту
   MCUCR |= (1<<ISC01)|(0<<ISC00);
   //разрешаем внешнее прерывание INT0
   En_INT0
}
 //----------
ISR(TIMER1_CMPA_vect)
{
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
      PORTB |= (1<<1);
      _delay_us(9);
      PORTB &= ~(1<<1);
      _delay_us(1);
}
//----------
//функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
   BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//на ввод
   BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//подтяжка вкл
}
//----------
//функция чтения данных о нажатии кнопок
char BtnGet (void)
{
   cli();
   char temp = BtnFlags;
   BtnFlags = 0;
   sei();
   return temp;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
   static unsigned char BtnLockBit;         //ащелка (защита от дребезга)
   static unsigned char BtnLockCoun;         //счетчик защелки (защита от дребезга)
   static unsigned char BtnLongCoun;         //счетчик длинного нажатия
   static unsigned char BtnLastState;         //последнее состояние кнопок перед отпусканием

   char mask = 0;
   if (! (BTN_PIN & BTN_LINE_UP))      mask = BTN_SHRT_UP;
   if (! (BTN_PIN & BTN_LINE_DN))      mask = BTN_SHRT_DN;
   if (! (BTN_PIN & BTN_LINE_POWER))   mask = BTN_SHRT_POWER;;

   if (mask){                           //опрос состояния кнопки
      if (BtnLockCoun < (BTN_LOCK_TIME/10)){   //клавиша нажата
         BtnLockCoun++;
         return;                        //защелка еще не дощитала - возврат
      }
      BtnLastState = mask;
      BtnLockBit =1;                     //нажатие зафиксировано
      if (BtnLongCoun >= (BTN_LONG_TIME/10))
      return;                        //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
      BtnFlags |= (BtnLastState<<4);         //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
   }
   else{                              //клавиша отжата
      if (BtnLockCoun){
         BtnLockCoun --;
         return;                        //защелка еще не обнулилась - возврат
      }
      if (! BtnLockBit)                  //СТАТИЧЕСКИЙ ВОЗВРАТ
      return;
      BtnLockBit =0;                     //отжатие зафиксировано
      if (BtnLongCoun < (BTN_LONG_TIME/10))
      BtnFlags |= BtnLastState;         //установка бита короткого нажатия
      BtnLongCoun = 0;               //сброс счетчика длительности нажатия
   }
}
//----------
//Прерывания по ИНТ0 от синхра импулса
static unsigned char count = 0;
static unsigned char time_eeprom = 0;
ISR(INT0_vect)
{
   if (fPower==1)
   {
   time_eeprom++;
   OCR1A = pgm_read_byte(&(TRIAK[value]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;
   //зажигаем следующий разр§д
   if (count == 0)
   {
      if (data2>0) //гасим старший разряд , если он == 0 .
      {
         segchar(data2);
         PORTB &= ~(1<<2);
      }
      else
      {
         PORTB |=(1<<PB2);
      }
   }
   if (count == 1)
   {
      segchar(data1);
      PORTB &= ~(1<<0);
   }
   count++;
   if (count == 2) {count = 0;}
   }
   else
   {
   OCR1A = pgm_read_byte(&(TRIAK[0]));
   TCNT1 = 0;
   data1 = value % 10;
   data2= value/10;
   //гасим оба разр§да
   PORTB |=(1<<PB0);
   PORTB |=(1<<PB2);
   PORTA = 0b11111110;      
   }
   BtnExe();
   if (time_eeprom==9){
      if (!(save==value))
      {
         my_var=value;
         eeprom_update_word (&eeprom_data, my_var);
      }
   }
   if (time_eeprom==10){time_eeprom=0;}
}
//----------
//----------
int main(void)
{
   //читаем байт из eeprom
   my_var = eeprom_read_word(&eeprom_data);
   _delay_ms(1000);
   init_io();
   sei();
   int0_init();
   BtnInit();
   unsigned char OneEn=0;
   save=my_var;
   while(1)
   {
      char BtnMask = BtnGet ();
      //одиночное нажатие +
      if ((BtnMask == BTN_SHRT_UP) & (value < 99))     
      {
         value++;
      }
      //одиночное нажатие -
      if ((BtnMask == BTN_SHRT_DN) & (value > 0))
      {
         value--;
      }
      //одиночное нажатие Power
      if (BtnMask == BTN_SHRT_POWER)
      {
         if (fPower==0)
         {
            value=save;
         }
         if (fPower==1)
         {
            save=value;
            value=0;
            OneEn=0;
         }
         if (fPower==2)
         {
            fPower=0;
         }
         fPower++;
      }
      //Удержание +
      if ((BtnMask == BTN_LONG_UP) & (value < 99))
      {
         while ((!(PINB&0b00010000))& (value < 99))
         {
            value++;
            _delay_ms(100);
         }
      }
      //Удержание -
      if ((BtnMask == BTN_LONG_DN) & (value > 0))
      {
         while ((!(PINB&0b00001000))& (value > 0))
         {
            value--;
            _delay_ms(100);
         }
      }
      if ((fPower==1)&(OneEn==0))
      {
         while ((value<save)& (value < 99))
         {
            value++;
            _delay_ms(100);
         }
      }
      if (value==save)
      {
         OneEn=1;
      }
   }
   return 0;
}
//----------
//Коды сегментов
void segchar (unsigned char seg)
{
   switch (seg)
   {
      case 1: PORTA = 0b01111100; break;
      case 2: PORTA = 0b10000100; break;
      case 3: PORTA = 0b01000100; break;
      case 4: PORTA = 0b01101000; break;
      case 5: PORTA = 0b01000010; break;
      case 6: PORTA = 0b00000010; break;
      case 7: PORTA = 0b01110100; break;
      case 8: PORTA = 0b00000000; break;
      case 9: PORTA = 0b01000000; break;
      case 0: PORTA = 0b00010000; break;
   }
}
//----------
void init_io()
{
   //порт, к которому подкл. сегменты
   PORTA = 0xff;
   DDRA = 0xff;
   //порт, к которому подкл. катод
   DDRB |=(1<<0)|(1<<1)|(1<<2);
   PORTB =0x00;
   //Иницилизация прерываний по совпадению Т1.
   TIMSK |=(1<<OCIE1A);
   TCCR1B |=/*(1<<CTC1)*/(0<<CS10)|(1<<CS11)|(0<<CS12)|(1<<CS13);   
   OCR1A=0xFF;
}


Добавлено after 9 minutes 20 seconds:
Да и вроде помаргивание на лампе наблюдается (

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Ср май 17, 2017 11:44:13 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Вы идеологически неверно делаете сохранение.
Зачем в таймере?!

В главном цикле после нажатия кнопки. Нет нажатий - нет изменений - нет сохранений. В главном цикле так же желательно отслеживать время с последнего нажатия, и если оно больше некоторого значения, только тогда сохранять, чтобы минимизировать перезаписи при изменении "яркости" несколькими нажатиями.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Запись\Чтение EEPROM или flash.
СообщениеДобавлено: Пт май 19, 2017 11:36:47 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Уважаемые знатоки всем спасибо за советы) мой первый проект готов. 8)
Отдельное спасибо участникам форума: ARV. Z_h_e.

И по традиции сделал сам поделись с остальными (мб поможет новичкам) .100% правильность работы программы не гарантирую использовать на свой страх и риск. :)

Также принимается всевозможная критика по коду и алгоритму работы.
Спойлер
Код:
//***************************************************************************
//  Target(s)...: IDE: AVR AtmelStudio 6.2 MC:Attiny26L
//  Data........: 19.05.17
//***************************************************************************
#define F_CPU   8000000          //Hz
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//----------
volatile unsigned char timer_save=0;
volatile unsigned char savePower=0;
volatile unsigned char saveValue=0;
volatile unsigned char fBtPower=1; // Состояние  кнопки
volatile unsigned char fPower = 0;
//EEPROM
uint16_t power_var = 0;
uint16_t value_var = 0;
uint16_t eeprom_power EEMEM;
uint16_t eeprom_value EEMEM;
//----------
//настройка параметров работы функций
#define BTN_LOCK_TIME      20               /*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME      1000            /*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/
//настройки портов
/*порт чтения кнопок*/
#define BTN_PORT         PORTB         
#define BTN_DDR            DDRB
#define BTN_PIN            PINB
/*пины чтения кнопок*/
#define BTN_LINE_UP      (1<<4)         
#define BTN_LINE_DN      (1<<3)
#define BTN_LINE_POWER   (1<<5)
//глобальные переменные
volatile uint8_t BtnFlags;                           //байт флагов нажатия кнопки
#define BTN_SHRT_UP         (1<<0)         /*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN         (1<<1)         /*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER      (1<<2)         /*бит короткого нажатия кнопки POWER */
#define BTN_LONG_UP         (1<<4)         /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN         (1<<5)         /*бит длинного нажатия кнопки dn*/
//----------
#define  En_INT0      GIMSK|= (1<<6);
#define  Dis_INT0     GIMSK&= ~(1<<6);
//----------
volatile unsigned char data1 = 0;   //Младший разряд индикатора
volatile unsigned char data2 = 0;   //Старший разряд индикатора
volatile unsigned char cValue = 0;   //Значения нагрева лампы от 0 до 99
//----------
static void init_io();
static void segchar(unsigned char seg);
//Значения для срабатывание триака.
const unsigned char TRIAK[]PROGMEM = {
   160,156,155,154,150,148,146,144,142,140,
   139,137,135,131,129,127,125,123,122,120,
   119,118,117,116,115,114,113,112,111,110,
   109,108,107,106,105,104,103,102,101,100,
   99,98,97,96,95,94,93,92,91,90,
   89,88,87,86,85,84,83,82,81,80,
   79,78,77,76,75,74,73,72,71,70,
   69,68,67,66,65,64,63,62,61,60,
   59,58,57,56,55,54,53,52,51,50,
   49,48,47,45,43,41,40,37,35,33};
//----------
ISR(TIMER1_CMPA_vect)
{
   cli();
   PORTB |= (1<<1);
   _delay_us(9);
   PORTB &= ~(1<<1);
   _delay_us(1);
   PORTB |= (1<<1);
   _delay_us(9);
   PORTB &= ~(1<<1);
   sei();
}
//----------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
   BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//на ввод
   BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER);//подтяжка вкл
}
//----------
//Функция чтения данных о нажатии кнопок
char BtnGet (void)
{
   cli();
   char temp = BtnFlags;
   BtnFlags = 0;
   sei();
   return temp;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
   static unsigned char BtnLockBit;            //ащелка (защита от дребезга)
   static unsigned char BtnLockCoun;         //счетчик защелки (защита от дребезга)
   static unsigned char BtnLongCoun;         //счетчик длинного нажатия
   static unsigned char BtnLastState;         //последнее состояние кнопок перед отпусканием

   char mask = 0;
   if (! (BTN_PIN & BTN_LINE_UP))      mask = BTN_SHRT_UP;
   if (! (BTN_PIN & BTN_LINE_DN))      mask = BTN_SHRT_DN;
   if (! (BTN_PIN & BTN_LINE_POWER))   mask = BTN_SHRT_POWER;;

   if (mask){                           //опрос состояния кнопки
      if (BtnLockCoun < (BTN_LOCK_TIME/10)){   //клавиша нажата
         BtnLockCoun++;
         return;                        //защелка еще не дощитала - возврат
      }
      BtnLastState = mask;
      BtnLockBit =1;                     //нажатие зафиксировано
      if (BtnLongCoun >= (BTN_LONG_TIME/10))
      return;                        //возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
      BtnFlags |= (BtnLastState<<4);         //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
   }
   else{                              //клавиша отжата
      if (BtnLockCoun){
         BtnLockCoun --;
         return;                        //защелка еще не обнулилась - возврат
      }
      if (! BtnLockBit)                  //СТАТИЧЕСКИЙ ВОЗВРАТ
      return;
      BtnLockBit =0;                     //отжатие зафиксировано
      if (BtnLongCoun < (BTN_LONG_TIME/10))
      BtnFlags |= BtnLastState;         //установка бита короткого нажатия
      BtnLongCoun = 0;               //сброс счетчика длительности нажатия
   }
}
//----------
//Прерывания по ИНТ0 от синхра импулса
volatile unsigned char count = 0;
ISR(INT0_vect)
{
   if (fPower==1)
   {
      data1 = cValue % 10;
      data2= cValue/10;
      OCR1A = pgm_read_byte(&(TRIAK[cValue]));
      TCNT1 = 0;
      //гасим оба разряда
      PORTB |=(1<<PB0);
      PORTB |=(1<<PB2);
      PORTA = 0b11111110;
      //зажигаем следующий разряд
      if (count == 0)
      {
         if (data2>0) //Пропускаем старший разряд , если он == 0 .
         {
            segchar(data2);
            PORTB &= ~(1<<2);
         }
         else
         {
            PORTB |=(1<<PB2);
         }
      }
      if (count == 1)
      {
         segchar(data1);
         PORTB &= ~(1<<0);
      }
      count++;
      if (count == 2) {count = 0;}
   }
   else
   {
      PORTB |=(1<<PB0);
      PORTB |=(1<<PB2);
      PORTA = 0b11111110;
      OCR1A = pgm_read_byte(&(TRIAK[0]));
      TCNT1 = 0;
   }
   BtnExe();
}
//----------
int main(void)
{
   //читаем байт из eeprom
    value_var= eeprom_read_word(&eeprom_value);
   _delay_ms(100);
   power_var=eeprom_read_word(&eeprom_power);
   _delay_ms(100);
   fBtPower=power_var;
   if (fBtPower==2)
   {
      fPower=1;
   }
   if (fBtPower==1)
   {
      fPower=0;
   }
   saveValue=value_var;
   init_io();
   BtnInit();
   unsigned char OneEn=0;
   _delay_ms(800);
   sei();
   while(1)
   {
      if (OneEn==0)
      {
         OneEn=1;
      }
      if ((fPower == 1)&(OneEn==1))
      {
         while ((cValue<saveValue)& (cValue < 99))
         {
            cValue++;
            _delay_ms(100);
         }
         OneEn=2;
      }
      char BtnMask = BtnGet ();
      //одиночное нажатие +
      if ((BtnMask == BTN_SHRT_UP) & (cValue < 99)&(fPower==1))
      {
         cValue++;
         saveValue=cValue;
         value_var=saveValue;
         eeprom_update_word (&eeprom_value, value_var);
      }      
      //одиночное нажатие -
      if ((BtnMask == BTN_SHRT_DN) & (cValue > 0)&(fPower==1))
      {
         cValue--;
         saveValue=cValue;
         value_var=saveValue;
         eeprom_update_word (&eeprom_value, value_var);
      }         
      
      //одиночное нажатие Power
      if (BtnMask == BTN_SHRT_POWER)
      {
         fBtPower++;
         if (fBtPower==2)
         {
            fPower=1;
            savePower=fBtPower;
         }
         if (fBtPower==3)
         {
            OneEn=1;
            cValue=0;
            savePower=(fBtPower-2);
            fPower=0;
         }
         if (fBtPower==3)
         {
            fBtPower=1;
         }
         power_var=savePower;
         eeprom_update_word (&eeprom_power, power_var);
      }
      //Удержание +
      if ((BtnMask == BTN_LONG_UP) & (cValue < 99)&(fPower==1))
      {
         while ((!(PINB&0b00010000))& (cValue < 99))
         {
            cValue++;
            _delay_ms(100);
         }
         saveValue=cValue;
         value_var=saveValue;
         eeprom_update_word (&eeprom_value, value_var);
      }
      //Удержание -
      if ((BtnMask == BTN_LONG_DN) & (cValue > 0)&(fPower==1))
      {
         while ((!(PINB&0b00001000))& (cValue > 0))
         {
            cValue--;
            _delay_ms(100);
            saveValue=cValue;
            value_var=saveValue;
            eeprom_update_word (&eeprom_value, value_var);
         }
      }
   }
   return 0;
}
//----------
//Функция включения сегментов + кодировка.
static void segchar (unsigned char seg)
{
   switch (seg)
   {
      case 1: PORTA = 0b01111100; break;
      case 2: PORTA = 0b10000100; break;
      case 3: PORTA = 0b01000100; break;
      case 4: PORTA = 0b01101000; break;
      case 5: PORTA = 0b01000010; break;
      case 6: PORTA = 0b00000010; break;
      case 7: PORTA = 0b01110100; break;
      case 8: PORTA = 0b00000000; break;
      case 9: PORTA = 0b01000000; break;
      case 0: PORTA = 0b00010000; break;
   }
}
//----------
static void init_io()
{
   //порт, к которому подкл. сегменты
   PORTA = 0xff;
   DDRA = 0xff;
   //порт, к которому подкл. катод
   DDRB |=(1<<0)|(1<<1)|(1<<2);
   PORTB =0x00;
   //Иницилизация прерываний по совпадению Т1.
   TIMSK |=(1<<OCIE1A);
   TCCR1B |=/*(1<<CTC1)*/(0<<CS10)|(1<<CS11)|(0<<CS12)|(1<<CS13);
   OCR1A=0xFF;
   //настраиваем на срабатывание INT0 по переднему фронту
   MCUCR |= (1<<ISC01)|(0<<ISC00);
   //разрешаем внешнее прерывание INT0
   En_INT0
}

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 16 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Google [Bot], shaaimars и гости: 23


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

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y