Непонимание, AlmelStudio 7.0, pgmspace и Attiny10
- Войдите на сайт для отправки комментариев
Сколько не пытался, но все тщетно
Значит имеется: - МК Attiny10
- AtmelStudio 7.0
- библиотека avr/pgmspace
Собственно стоит задача: методом чарлиплексинга зажигать 4 светодиода (одновременно или по очереди) используя 2 порта, PB0 и PB1.
Имеем 4 светодиода по 2 встречнопараллельных(1нога идет на массу, другая на плюс, их общий вывод на порт)
Зная что порт может иметь 3 состояния, получаем следующие конфигурации портов:
PROGMEM const uint8_t sp_ddr [] =
{
0x01,
0x01,
0x02,
0x02
};
PROGMEM const uint8_t sp_port [] =
{
0x00,
0x01,
0x00,
0x02
};
В связи с ограниченной оперативной (и не только) памятью контроллера, было решено использовать флеш память для хранение данных, но что-то не срослось, если отдельно вызывать каждое состояние, то все работает как надо(если не обращать на разницу в свечении, эта проблема будет решена через таймер), собственно рабочий код:
while(1) {
i++;
switch (i)
{
case 0:
DDRB=0x01;
PORTB=0x00;
_delay_ms(1);
break;
case 1:
DDRB=0x01;
PORTB=0x01;
_delay_ms(1);
break;
case 2:
DDRB=0x02;
PORTB=0x00;
_delay_ms(1);
break;
case 3:
DDRB=0x02;
PORTB=0x02;
_delay_ms(1);
break;
}
}
i++;
if (i==4){i=0;}
}
А теперь собственно проблема, при использовании pgm_read_byte контроллер наотрез отказывается что-либо делать, пробовал и в основном цикле пихать и по таймеру и вписывать значения вручную, такое чувство что компилятор просто не воспринимает библиотеку pgmspase
ISR (TIM0_COMPA_vect)
{
lednum ++;
if (lednum == 4 ) lednum = 0 ;
// if (( 1 << lednum) & pgm_read_byte (& diceplay [state1])) в зависимости от значения ацп, зажигаем от 1 до 4-х светодиодов
// {
PORTB = pgm_read_byte (& sp_port [lednum]);
DDRB = pgm_read_byte (& sp_ddr [lednum]);
// PORTB = pgm_read_byte (sp_port [lednum]);
// DDRB = pgm_read_byte ( sp_ddr [lednum]);
// PORTB = pgm_read_byte (&( sp_port [lednum]));
// DDRB = pgm_read_byte (& (sp_ddr [lednum]));
// }
// else
// {
// DDRB = 0 ;
// }
}
Прошу помощи, тыкнуть где я не прав
попробуйте читать из прогмем вот так:
Увы, та же беда, значения просто не записываются в регистры
А схема будет работать? Напряжение питания какое? Потому что если 5 вольт, то 2 из 4-х светодиодов будут гореть (светиться). Когда порт будет в 3-м состоянии будут светить оба светодиода - верхний и нижний.
Питал и от 5 вольт, сейчас остановился на 2.7-2.5. Работает и так и так. А причем тут напряжение питания? 3 состояние порта (HI-Z) или высокоимпедансное состояние порта, это когда ключ просто отключает выход и он «повисает в воздухе» — соединяется с остальной схемой через высокое сопротивление (импеданс) закрытого транзистора, так что сопротивление на нем близится к "бесконечности?".
схема для наглядности:
TheZlobik, вам из 8 ми байт данных реально нужно всего по 2 бита с каждого байта, то есть все данные можно ужать в 2 байта, Первоначально записать в байт данных для DDRB значение 10 10 01 01 а в байт данных для PORTB 10 00 01 00, затем сдвигать эти биты по кругу влево на 2 шага. Т.к. необходимолсть в счёте шагов отпадает, то if или swith тоже не потребуются.
А можно сдвигать биты сразу в порту, без перекладывания в переменные:
setup(){ PORTB=B10000100; } ISR (TIM0_COMPA_vect) PORTB = (PORTB << 2) | (PORTB >> 6); }По аналогии сделать для DDRB.