Непонимание, AlmelStudio 7.0, pgmspace и Attiny10
- Войдите на сайт для отправки комментариев
Сколько не пытался, но все тщетно
Значит имеется: - МК Attiny10
- AtmelStudio 7.0
- библиотека avr/pgmspace
Собственно стоит задача: методом чарлиплексинга зажигать 4 светодиода (одновременно или по очереди) используя 2 порта, PB0 и PB1.
Имеем 4 светодиода по 2 встречнопараллельных(1нога идет на массу, другая на плюс, их общий вывод на порт)
Зная что порт может иметь 3 состояния, получаем следующие конфигурации портов:
01 | PROGMEM const uint8_t sp_ddr [] = |
02 | { |
03 | 0x01, |
04 | 0x01, |
05 | 0x02, |
06 | 0x02 |
07 | }; |
08 | |
09 | PROGMEM const uint8_t sp_port [] = |
10 | { |
11 | 0x00, |
12 | 0x01, |
13 | 0x00, |
14 | 0x02 |
15 | }; |
В связи с ограниченной оперативной (и не только) памятью контроллера, было решено использовать флеш память для хранение данных, но что-то не срослось, если отдельно вызывать каждое состояние, то все работает как надо(если не обращать на разницу в свечении, эта проблема будет решена через таймер), собственно рабочий код:
01 | while (1) { |
02 | |
03 | i++; |
04 | switch (i) |
05 | { |
06 | case 0: |
07 | DDRB=0x01; |
08 | PORTB=0x00; |
09 | _delay_ms(1); |
10 | break ; |
11 | case 1: |
12 | DDRB=0x01; |
13 | PORTB=0x01; |
14 | _delay_ms(1); |
15 | break ; |
16 | case 2: |
17 | DDRB=0x02; |
18 | PORTB=0x00; |
19 | _delay_ms(1); |
20 | break ; |
21 | case 3: |
22 | DDRB=0x02; |
23 | PORTB=0x02; |
24 | _delay_ms(1); |
25 | break ; |
26 | } |
27 | } |
28 | i++; |
29 | if (i==4){i=0;} |
30 | } |
А теперь собственно проблема, при использовании pgm_read_byte контроллер наотрез отказывается что-либо делать, пробовал и в основном цикле пихать и по таймеру и вписывать значения вручную, такое чувство что компилятор просто не воспринимает библиотеку pgmspase
01 | ISR (TIM0_COMPA_vect) |
02 | { |
03 | lednum ++; |
04 | if (lednum == 4 ) lednum = 0 ; |
05 | |
06 | // if (( 1 << lednum) & pgm_read_byte (& diceplay [state1])) в зависимости от значения ацп, зажигаем от 1 до 4-х светодиодов |
07 | // { |
08 | PORTB = pgm_read_byte (& sp_port [lednum]); |
09 | DDRB = pgm_read_byte (& sp_ddr [lednum]); |
10 |
11 | // PORTB = pgm_read_byte (sp_port [lednum]); |
12 | // DDRB = pgm_read_byte ( sp_ddr [lednum]); |
13 |
14 | // PORTB = pgm_read_byte (&( sp_port [lednum])); |
15 | // DDRB = pgm_read_byte (& (sp_ddr [lednum])); |
16 |
17 | // } |
18 | // else |
19 | // { |
20 | // DDRB = 0 ; |
21 | // } |
22 | } |
Прошу помощи, тыкнуть где я не прав
попробуйте читать из прогмем вот так:
1
PORTB = pgm_read_byte (sp_port + lednum);
Увы, та же беда, значения просто не записываются в регистры
А схема будет работать? Напряжение питания какое? Потому что если 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 тоже не потребуются.
А можно сдвигать биты сразу в порту, без перекладывания в переменные:
01
setup
(){
02
03
PORTB=B10000100;
04
05
}
06
07
ISR (TIM0_COMPA_vect)
08
09
PORTB = (PORTB << 2) | (PORTB >> 6);
10
11
}
По аналогии сделать для DDRB.