Возник такой вопрос куда лучше писать энергонезависимую информацию, в моем примере это значение переменной нагрева + состояние вкл/выкл. Я читал что Сам 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;
}.................................................................................................................



