итак, в небольшом проекте решил применить чарлиплексинг для управления линейной шкалой из 48 светодиодов, схема ниже.
написал программку тестовую, исходник в спойлере.
Спойлер
#include <avr/io.h>#include <stdbool.h>
#include "avr_helper.h"
#define SCALE_LEN 48
#define L1 _BV(PD0)
#define L2 _BV(PD1)
#define L3 _BV(PD2)
#define L4 _BV(PD3)
#define L5 _BV(PD4)
#define L6 _BV(PD5)
#define L7 _BV(PD6)
#define L8 _BV(PD7)
#define CHPX(d,p) {.ddr = (d + p), .port = (d)}, {.ddr = (d + p), .port = (p)}
typedef struct {
uint8_t ddr;
uint8_t port;
} charli_t;
extern bool scale[SCALE_LEN];
extern const __flash charli_t leds[SCALE_LEN];
Спойлер
Код: Выделить всё
#include <avr/interrupt.h>
#include "global.h"
const __flash charli_t leds[SCALE_LEN] = {
CHPX(L1,L2), // HL1-2
CHPX(L1,L3), // HL3-4
CHPX(L1,L4), // HL5-6
CHPX(L1,L5), // HL7-8
CHPX(L1,L6), // HL9-10
CHPX(L1,L7), // HL11-12
CHPX(L1,L8), // HL13-14
CHPX(L2,L3), // HL15-16
CHPX(L2,L4), // HL17-18
CHPX(L2,L5), // HL19-20
CHPX(L2,L6), // HL21-22
CHPX(L2,L7), // HL23-24
CHPX(L2,L8), // HL25-26
CHPX(L3,L4), // HL27-28
CHPX(L3,L5), // HL29-30
CHPX(L3,L6), // HL31-32
CHPX(L3,L7), // HL33-34
CHPX(L3,L8), // HL35-36
CHPX(L4,L5), // HL37-38
CHPX(L4,L6), // HL39-40
CHPX(L4,L7), // HL41-42
CHPX(L4,L8), // HL43-44
CHPX(L5,L6), // HL45-46
CHPX(L5,L7) // HL47-48
};
bool scale[SCALE_LEN];
void led_bar(uint8_t height){
for(uint8_t i=0; i<SCALE_LEN; i++){
scale[i] = i < height;
}
}
#define DELAY 10000
volatile bool next;
volatile bool key;
ISR(TIMER0_COMPA_vect){
static uint8_t item;
static uint16_t delay = DELAY;
PORTD = 0;
DDRD = 0;
if(++item >= SCALE_LEN) item = 0;
if(scale[item]){
PORTD = leds[item].port;
DDRD = leds[item].ddr;
}
if(!--delay){
key = !!!(PINC & _BV(PC3));
next = true;
delay = DELAY;
}
}
int main(void){
uint8_t val = 1;
int8_t d = 1;
PORTC = _BV(PC3);
TCCR0A = _BV(WGM01);
TCCR0B = TIMER_CLK_DIV_64;
TCCR0A = 90; // ЗАГАДОЧНОЕ ЧИСЛО!!!
TIMSK0 = _BV(OCIE0A);
sei();
while(1){
while(key);
led_bar(val);
while(!next);
next = false;
val += d;
if(
((d > 0) && (val == (SCALE_LEN-1)))
||
((d < 0) && (val == 0))
){
d = -d;
}
}
}
а загадочное оно потому, что при изменении его с шагом в 10 в любую сторону (я другие варианты просто не пробовал, т.к. и без того странно) можно получать следующее поведение:
- шкала не светится вообще
- на шкале мерцает (примерно герц 10-15) только первый светодиод
- шкала работает отлично, как задумано
- на шкале не просвечиваются светодиоды, включенные катодами к линии LED6 (см. схему)
- на шкале не просвечиваются светодиоды, подключенные к LED6.
хотя, как я предполагал, изменение этой константы меняет только частоты динамического чарлиплексинга и может повлиять только на степень мерцания светодиодов...
такая вот загадка. может, я чего-то очевидного не замечаю?


