Пт окт 20, 2017 07:19:22
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//----------///init_pwm///----------//
void init_pwm()
{
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
OCR0A=0x00;
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
OCR1AL=0x00;
OCR1BL=0x00;
TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
OCR2A=0x00;
OCR2B=0x00;
}
//----------//
void init_int0()
{
//настраиваем на срабатывание INT0 по переднему фронту
EICRA |= (1<<ISC01)|(0<<ISC00);
//разрешаем внешнее прерывание INT0
EIMSK |= (1<<INT0);
}
//----------//
void init_io()
{
DDRB=(0<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(0<<PB5)|(0<<PB6)|(0<<PB7);
PORTB=0x00;
DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6);
PORTC=0x00;
DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
PORTD=0x00;
}
//----------//
//настройка параметров работы функций
#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<<7)
#define BTN_LINE_DN (1<<6)
#define BTN_LINE_POWER (1<<5)
#define BTN_LINE_SW (1<<0)
//глобальные переменные
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_SHRT_SW (1<<3) /*бит короткого нажатия кнопки SW*/
#define BTN_LONG_UP (1<<4) /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN (1<<5) /*бит длинного нажатия кнопки dn*/
#define BTN_LONG_SW (1<<6) /*бит короткого нажатия кнопки SW*/
//----------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//на ввод
BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//подтяжка вкл
}
//----------
//Функция чтения данных о нажатии кнопок
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 (! (BTN_PIN & BTN_LINE_SW)) mask = BTN_SHRT_SW;
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; //сброс счетчика длительности нажатия
}
}
//----------****7SEG****----------
#define SEGA 6
#define SEGB 5
#define SEGC 1
#define SEGD 2
#define SEGE 3
#define SEGF 4
#define SEGG 0
#define ANOD1 4
#define ANOD2 7
#define ANOD3 4
//----------
void segchar (unsigned char seg)
{
switch (seg)
{
case 0:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG);break;
case 1:
PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
case 2:
PORTC=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
case 3:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
case 4:
PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 5:
PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 6:
PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 7:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
case 8:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 9:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 99: //OFF Все сегменты
PORTC=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
}
}
unsigned char ValuePWM[]={0,0,0,0,0,0};
unsigned char FlagPower[]={0,0,0,0,0,0};
void UpdateFlagPower(unsigned char ZoneNumber,unsigned char Flag)
{
FlagPower[ZoneNumber]=Flag;
}
void UpdateValue(void)
{
for (unsigned char ValueCount = 0; ValueCount < 5; ValueCount++)
{
switch (ValueCount)
{
case 0:
OCR0A=ValuePWM[ValueCount]*2.56;break;
case 1:
OCR0B=ValuePWM[ValueCount]*2.56;break;
case 2:
OCR1AL=ValuePWM[ValueCount]*2.56;break;
case 3:
OCR1BL=ValuePWM[ValueCount]*2.56;break;
case 4:
OCR2A=ValuePWM[ValueCount]*2.56;break;
case 5:
OCR2B=ValuePWM[ValueCount]*2.56;break;
}
}
}
unsigned char data1 = 0;
unsigned char data2 = 0;
unsigned char count = 0;
unsigned char ZoneNumber=0;
void WriteSeg(unsigned char Number)
{
data1=ValuePWM[Number]%10;
data2=ValuePWM[Number]/10;
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
segchar(99);
count++;
if (count==1){
PORTB &= ~(1<<ANOD1);
segchar(data1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
}
if (count==2){
PORTD &= ~(1<<ANOD2);
segchar(data2);
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD3);
}
if (count==3){
PORTD &= ~(1<<ANOD3);
segchar(Number+1);
PORTB |=(1<<ANOD1);
PORTD|=(1<<ANOD2);
}
if (count==3){count=0;}
}
ISR(INT0_vect)
{
WriteSeg(ZoneNumber);
UpdateValue();
BtnExe();
}
unsigned char fBtnPower=0;
void BtnUpdate(void)
{
char BtnMask = BtnGet ();
if (BtnMask == BTN_SHRT_POWER)
{
}
if ((BtnMask == BTN_SHRT_SW))
{
ZoneNumber++;
if (ZoneNumber==6)
{
ZoneNumber=0;
}
}
//одиночное нажатие +
if ((BtnMask == BTN_SHRT_UP)& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
}
//одиночное нажатие -
if ((BtnMask == BTN_SHRT_DN)& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
}
//Удержание +
if ((BtnMask == BTN_LONG_UP) & (ValuePWM[ZoneNumber] < 99))
{
while ((!(PINB&0b10000000))& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
_delay_ms(50);
}
}
//Удержание -
if ((BtnMask == BTN_LONG_DN) & (ValuePWM[ZoneNumber] > 0))
{
while ((!(PINB&0b01000000))& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
_delay_ms(50);
}
}
}
//----------
uint8_t EEMEM FlagPower1_EEPROM=0;
uint8_t EEMEM FlagPower2_EEPROM=0;
uint8_t EEMEM FlagPower3_EEPROM=0;
uint8_t EEMEM FlagPower4_EEPROM=0;
uint8_t EEMEM FlagPower5_EEPROM=0;
uint8_t EEMEM FlagPower6_EEPROM=0;
uint8_t EEMEM Value1_EEPROM=0;
uint8_t EEMEM Value2_EEPROM=0;
uint8_t EEMEM Value3_EEPROM=0;
uint8_t EEMEM Value4_EEPROM=0;
uint8_t EEMEM Value5_EEPROM=0;
uint8_t EEMEM Value6_EEPROM=0;
unsigned char LoadingFlagEEPROM(uint8_t NumberZone)
{
unsigned char PowerFlag=0;
switch(NumberZone)
{
case 1:
PowerFlag = eeprom_read_byte(&Value1_EEPROM);
break;
case 2:
PowerFlag = eeprom_read_byte(&Value2_EEPROM);
break;
case 3:
PowerFlag = eeprom_read_byte(&Value3_EEPROM);
break;
case 4:
PowerFlag = eeprom_read_byte(&Value4_EEPROM);
break;
case 5:
PowerFlag = eeprom_read_byte(&Value5_EEPROM);
break;
case 6:
PowerFlag = eeprom_read_byte(&Value6_EEPROM);
break;
}
_delay_ms(10);
return(PowerFlag);
}
uint8_t LoadingValueEEPROM(uint8_t NumberZone)
{
uint8_t ValueFlag=0;
switch(NumberZone)
{
case 1:
ValueFlag = eeprom_read_byte(&FlagPower1_EEPROM);
break;
case 2:
ValueFlag = eeprom_read_byte(&FlagPower2_EEPROM);
break;
case 3:
ValueFlag = eeprom_read_byte(&FlagPower3_EEPROM);
break;
case 4:
ValueFlag = eeprom_read_byte(&FlagPower4_EEPROM);
break;
case 5:
ValueFlag = eeprom_read_byte(&FlagPower5_EEPROM);
break;
case 6:
ValueFlag = eeprom_read_byte(&FlagPower6_EEPROM);
break;
}
_delay_ms(10);
return(ValueFlag);
}
void SaveEEPROM(uint8_t SaveValue,uint8_t SaveFlagPower,uint8_t NumberZone)
{
switch(NumberZone)
{
case 1:
eeprom_write_byte (&Value1_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower1_EEPROM, SaveFlagPower);
break;
case 2:
eeprom_write_byte (&Value2_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower2_EEPROM, SaveFlagPower);
break;
case 3:
eeprom_write_byte (&Value3_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower3_EEPROM, SaveFlagPower);
break;
case 4:
eeprom_write_byte (&Value4_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower4_EEPROM, SaveFlagPower);
break;
case 5:
eeprom_write_byte (&Value5_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower5_EEPROM, SaveFlagPower);
break;
case 6:
eeprom_write_byte (&Value6_EEPROM, SaveValue);
eeprom_write_byte (&FlagPower6_EEPROM, SaveFlagPower);
break;
}
}
//----------
int main(void)
{
for (unsigned char Count = 0; Count < 5; Count++)
{
SaveEEPROM(1,2,Count+1);
_delay_ms(15);
}
for (unsigned char Count = 0; Count < 5; Count++)
{
FlagPower[Count]=LoadingFlagEEPROM(Count+1);
}
for (unsigned char Count = 0; Count < 5; Count++)
{
ValuePWM[Count]=LoadingValueEEPROM(Count+1);
}
init_io();
init_int0();
BtnInit();
init_pwm();
_delay_ms(10);
sei();
while(1)
{
BtnUpdate();
}
return 0;
}
Пт окт 20, 2017 07:28:21
Пт окт 20, 2017 07:51:00
Пт окт 20, 2017 07:55:49
Пт окт 20, 2017 07:59:13
Пт окт 20, 2017 08:27:52
// определяем константу-количество конфигураций
#define CONFIG_CNT 6
// описываем структуру конфигурации
typedef struct{
int param1;
char param2;
long param3;
} configuration;
//определяем массив конфигураций в EEPROM
EEMEM configuration e_config[CONFIG_CNT];
// для удобства такой же массив в ОЗУ
configuration config[CONFIG_CNT];
// вот так конфигурация из ОЗУ сохраняется в EEPROM
eeprom_update_block((void*)config, (void*)e_config, sizeof(config));
// вот так конфигурация считывается в ОЗУ из EEPROM
eeprom_read_block((void*)e_config, (void*)config, sizeof(config)); // я тут ранее опечатался - теперь корректно!!!
// вот так вы получаете параметр из 2-й конфигурации для работы
int var = config[1].param1;
Пт окт 20, 2017 08:30:01
Пт окт 20, 2017 08:36:08
обратите внимание на приписку о параметрах функций, которую я сделал позже - порядок адресов для чтения и записи - разный! на первом месте адрес массива, откуда берутся данные, на втором - куда помещаются. если вы сделаете так, как процитировано - функция чтения работать не будет7seg писал(а):eeprom_update_block((void*)config, (void*)e_config, sizeof(config));
eeprom_read_block((void*)config, (void*)e_config, sizeof(config));
Пт окт 20, 2017 08:58:27
#define CONFIG_CNT 5
typedef struct
{
char FlagPower;
char ValuePWM;
}ConfigurationLamp;
EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_CNT];
ConfigurationLamp ConfigLamp[CONFIG_CNT];
Пт окт 20, 2017 09:12:20
Пт окт 20, 2017 09:32:21
#define CONFIG_CNT 6
typedef struct
{
char FlagPower;
char ValuePWM;
}ConfigurationLamp;
EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_CNT];
ConfigurationLamp ConfigLamp[CONFIG_CNT];
for (unsigned char ValueCount = 0; ValueCount < 5; ValueCount++)
{
ConfigLamp[ValueCount].FlagPower=(ValueCount+1);
ConfigLamp[ValueCount].ValuePWM=(6-ValueCount);
}
eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
Пт окт 20, 2017 09:45:44
for (unsigned char ValueCount = 0; ValueCount < CONFIG_CNT; ValueCount++)
Пт окт 20, 2017 11:54:11
#define CONFIG_AMOUNT 6
typedef struct
{
char FlagPower;
char ValuePWM;
}ConfigurationLamp;
EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_AMOUNT];
ConfigurationLamp ConfigLamp[CONFIG_AMOUNT];
unsigned char ValuePWM[CONFIG_AMOUNT];
unsigned char FlagPower[CONFIG_AMOUNT];
void LoadingEEPROM()
{
eeprom_read_block((void*)E_ConfigLamp, (void*)ConfigLamp, sizeof(ConfigLamp));
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
FlagPower[ValueCount]=ConfigLamp[ValueCount].FlagPower;
ValuePWM[ValueCount]=ConfigLamp[ValueCount].ValuePWM;
}
}
void SaveEEPROM()
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
ConfigLamp[ValueCount].FlagPower=(FlagPower[ValueCount]);
ConfigLamp[ValueCount].ValuePWM=(ValuePWM[ValueCount]);
}
eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
}
int main(void)
{
LoadingEEPROM();
init_io();
init_int0();
BtnInit();
init_pwm();
_delay_ms(10);
sei();
while(1)
{
SaveEEPROM();
BtnUpdate();
}
return 0;
}
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//----------///init_pwm///----------//
void init_pwm()
{
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
OCR0A=0x00;
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
OCR1AL=0x00;
OCR1BL=0x00;
TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
OCR2A=0x00;
OCR2B=0x00;
}
//----------//
void init_int0()
{
//настраиваем на срабатывание INT0 по переднему фронту
EICRA |= (1<<ISC01)|(0<<ISC00);
//разрешаем внешнее прерывание INT0
EIMSK |= (1<<INT0);
}
//----------//
void init_io()
{
DDRB=(0<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(0<<PB5)|(0<<PB6)|(0<<PB7);
PORTB=0x00;
DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6);
PORTC=0x00;
DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
PORTD=0x00;
}
//----------//
//настройка параметров работы функций
#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<<7)
#define BTN_LINE_DN (1<<6)
#define BTN_LINE_POWER (1<<5)
#define BTN_LINE_SW (1<<0)
//глобальные переменные
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_SHRT_SW (1<<3) /*бит короткого нажатия кнопки SW*/
#define BTN_LONG_UP (1<<4) /*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN (1<<5) /*бит длинного нажатия кнопки dn*/
#define BTN_LONG_SW (1<<6) /*бит короткого нажатия кнопки SW*/
//----------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//на ввод
BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//подтяжка вкл
}
//----------
//Функция чтения данных о нажатии кнопок
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 (! (BTN_PIN & BTN_LINE_SW)) mask = BTN_SHRT_SW;
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; //сброс счетчика длительности нажатия
}
}
//----------****7SEG****----------
#define SEGA 6
#define SEGB 5
#define SEGC 1
#define SEGD 2
#define SEGE 3
#define SEGF 4
#define SEGG 0
#define ANOD1 4
#define ANOD2 7
#define ANOD3 4
//----------
void segchar (unsigned char seg)
{
switch (seg)
{
case 0:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG);break;
case 1:
PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
case 2:
PORTC=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
case 3:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
case 4:
PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 5:
PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 6:
PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 7:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
case 8:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 9:
PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
case 99: //OFF Все сегменты
PORTC=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
}
}
#define CONFIG_AMOUNT 6
typedef struct
{
char FlagPower;
char ValuePWM;
}ConfigurationLamp;
EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_AMOUNT];
ConfigurationLamp ConfigLamp[CONFIG_AMOUNT];
unsigned char ValuePWM[CONFIG_AMOUNT];
unsigned char FlagPower[CONFIG_AMOUNT];
//----------
void LoadingEEPROM()
{
eeprom_read_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
FlagPower[ValueCount]=ConfigLamp[ValueCount].FlagPower;
ValuePWM[ValueCount]=ConfigLamp[ValueCount].ValuePWM;
}
}
void SaveEEPROM()
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
ConfigLamp[ValueCount].FlagPower=(FlagPower[ValueCount]);
ConfigLamp[ValueCount].ValuePWM=(ValuePWM[ValueCount]);
}
eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
}
//----------
void UpdateFlagPower(unsigned char ZoneNumber,unsigned char Flag)
{
FlagPower[ZoneNumber]=Flag;
}
void UpdateValue(void)
{
for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
{
switch (ValueCount)
{
case 0:
if (FlagPower[ValueCount]==1)
{
OCR0A=ValuePWM[ValueCount]*2.56;
}
else{
OCR0A=0;
}break;
case 1:
if (FlagPower[ValueCount]==1)
{
OCR0B=ValuePWM[ValueCount]*2.56;
}
else{
OCR0B=0;}break;
case 2:
if (FlagPower[ValueCount]==1)
{
OCR1AL=ValuePWM[ValueCount]*2.56;
}
else{
OCR1AL=0;
}break;
case 3:
if (FlagPower[ValueCount]==1)
{
OCR1BL=ValuePWM[ValueCount]*2.56;
}
else{
OCR1BL=0;
}break;
case 4:
if (FlagPower[ValueCount]==1)
{
OCR2A=ValuePWM[ValueCount]*2.56;
}
else{
OCR2A=0;
}break;
case 5:
if (FlagPower[ValueCount]==1)
{
OCR2B=ValuePWM[ValueCount]*2.56;
}
else{
OCR2B=0;
}break;
}
}
}
unsigned char data1 = 0;
unsigned char data2 = 0;
unsigned char count = 0;
unsigned char ZoneNumber=0;
void WriteSeg(unsigned char Number)
{
data1=ValuePWM[Number]%10;
data2=ValuePWM[Number]/10;
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
segchar(99);
if(FlagPower[Number]==1)
{
count++;
if (count==1){
PORTB &= ~(1<<ANOD1);
segchar(data1);
PORTD |=(1<<ANOD2);
PORTD |=(1<<ANOD3);
}
if (count==2){
PORTD &= ~(1<<ANOD2);
segchar(data2);
PORTB |=(1<<ANOD1);
PORTD |=(1<<ANOD3);
}
if (count==3){
PORTD &= ~(1<<ANOD3);
segchar(Number+1);
PORTB |=(1<<ANOD1);
PORTD|=(1<<ANOD2);
}
if (count==3){count=0;}
}
}
ISR(INT0_vect)
{
WriteSeg(ZoneNumber);
UpdateValue();
BtnExe();
}
unsigned char fBtnPower=0;
void BtnUpdate(void)
{
char BtnMask = BtnGet ();
if (BtnMask == BTN_SHRT_POWER)
{
FlagPower[ZoneNumber]++;
if (FlagPower[ZoneNumber]>1)
{
FlagPower[ZoneNumber]=0;
}
SaveEEPROM();
}
if ((BtnMask == BTN_SHRT_SW))
{
ZoneNumber++;
if (ZoneNumber==6)
{
ZoneNumber=0;
}
}
//одиночное нажатие +
if ((BtnMask == BTN_SHRT_UP)& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
SaveEEPROM();
}
//одиночное нажатие -
if ((BtnMask == BTN_SHRT_DN)& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
SaveEEPROM();
}
//Удержание +
if ((BtnMask == BTN_LONG_UP) & (ValuePWM[ZoneNumber] < 99))
{
while ((!(PINB&0b10000000))& (ValuePWM[ZoneNumber] < 99))
{
ValuePWM[ZoneNumber]++;
_delay_ms(50);
}
SaveEEPROM();
}
//Удержание -
if ((BtnMask == BTN_LONG_DN) & (ValuePWM[ZoneNumber] > 0))
{
while ((!(PINB&0b01000000))& (ValuePWM[ZoneNumber] > 0))
{
ValuePWM[ZoneNumber]--;
_delay_ms(50);
}
SaveEEPROM();
}
}
int main(void)
{
LoadingEEPROM();
_delay_ms(50);
init_io();
init_int0();
BtnInit();
init_pwm();
_delay_ms(10);
sei();
while(1)
{
BtnUpdate();
}
return 0;
}
Пт окт 20, 2017 12:27:09
а что она делает? можете словами описать, потому что анализировать ваш код у меня лично желания нет...7seg писал(а):А есть идеи как можно сделать покомпактней функцию UpdateValue();
Пт окт 20, 2017 12:32:49
7seg писал(а):А есть идеи как можно сделать покомпактней функцию UpdateValue();
Пт окт 20, 2017 14:23:22
Пт окт 20, 2017 14:29:58
Пт окт 20, 2017 14:34:35
Пт окт 20, 2017 14:41:18
Пт окт 20, 2017 14:53:47