Страница 1 из 1

Загадочный чарлиплексинг

Добавлено: Сб авг 24, 2024 15:07:22
ARV
я тут в некоторой прострации... попал на нечто, к чему никак не был готов, и пока не понимаю, куда копать...

итак, в небольшом проекте решил применить чарлиплексинг для управления линейной шкалой из 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;
		}
	}
}
казалось бы, ничего сложного, поведение прогнозируется элементарное: шкала нарастает и спадает с некоторой скоростью, определяемой значением DELAY, а частота обновления шкалы (динамическое обновление) зависит от значения, которое помечено комментарием "ЗАГАДОЧНОЕ ЧИСЛО".

а загадочное оно потому, что при изменении его с шагом в 10 в любую сторону (я другие варианты просто не пробовал, т.к. и без того странно) можно получать следующее поведение:
- шкала не светится вообще
- на шкале мерцает (примерно герц 10-15) только первый светодиод
- шкала работает отлично, как задумано
- на шкале не просвечиваются светодиоды, включенные катодами к линии LED6 (см. схему)
- на шкале не просвечиваются светодиоды, подключенные к LED6.

хотя, как я предполагал, изменение этой константы меняет только частоты динамического чарлиплексинга и может повлиять только на степень мерцания светодиодов...

такая вот загадка. может, я чего-то очевидного не замечаю?

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 08:13:38
КРАМ
Чисто на основе интуиции. Имеет место быть интерференция исполняемого кода и "загадочной" задержки. То есть причина в том, что диапазон изменения задержек находится целиком в зоне интерференции. Его нужно увеличивать минимум на десятичный порядок.

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 11:21:00
ARV
вы не поверите, но я наткнулся на баг чипа.

чип - atmega328p, купленный недорого на Алиэкспресе. довольно много раз покупал и на проблемы не наталкивался, если не считать общей для всех проблемой несоответствие фьюзов правильным заводским настройкам.


а теперь, после долгих экспериментов, я выяснил, что регистр TCCR0A не работает, как должен по документации:
биты старшей тетрады этого регистра пишутся и читаются, но на результат (т.е. на момент прерывания) влияет только бит 5 (т.е. маска 0x20), причем влияет как раз так, что не работает линия LED6;
биты 2 и 3 младшей тетрады (маска 0x0C) не пишутся, читаются всегда нулями, соответственно и результат работы таймера странный
остальные 2 бита и пишутся, и читаются, но результат работы таймера странный: если младший бит = 1, то прерывание по совпадению возникает в момент, когда у нормального таймера TCCR0A=255 или близкое к тому, т.е. поздно, а если младший бит =0, то прерывание возникает рано.
такие вот пироги, товарищи...

будьте осторожны с алиэкспрессом.

P.S. в принципе, для моего проекта это не критично, т.к. подобрать значение регистра для минимальной и максимальной яркости шкалы можно, хотя, конечно, хотелось регулировать яркость более-менее плавно... главное, чтобы других багов не нашлось.

P.P.S. чисто теоретически я допускаю, что при пайке феном я чип перегрел... но это представляется маловероятным... хотя кто скажет наверняка?

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 11:44:23
smacorp
Наверняка скажет только заливка кода в другие 328р, купленные не на Али, и, желательно, гарантированно подлинные.

А то я лет 20 назад неделю просидел с непоняткой в своей программе, будучи уверенным, что нашёл баг в компиляторе Delphi. Уже думал разработчикам писать. Но через неделю пришло просветление, и оказалось, что компиляторы не ошибаются. Единственное, компилятор не китайцы ваяли, конечно.

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 12:10:04
shonty
ARV писал(а):будьте осторожны с алиэкспрессом.
Макетка.. DIP-ка.. ZIF-ка.. :beer:

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 12:14:57
ARV
smacorp писал(а):А то я лет 20 назад неделю просидел с непоняткой в своей программе, будучи уверенным, что нашёл баг в компиляторе Delphi
ну, как бы если я вывожу два числа (одно то, которое записал в регистр, а другое, которое считал из регистра после записи), и эти два числа разные, грешить на программу было бы странно...
shonty писал(а):Макетка.. DIP-ка.. ZIF-ка..
во-первых, я уже много лет DIP стараюсь не применять, кроме как именно макетирование на единственном чипе в DIP-корпусе
во-вторых, макетирование на одном чипе а изготовление на другом, как выяснилось, более не гарантирует результат...

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 12:40:23
shonty
shonty писал(а):во-вторых, макетирование на одном чипе а изготовление на другом, как выяснилось, более не гарантирует результат..
вот тут имею возразить)) макетирование на исправном чипе, также даст положительный результат на другом исправном чипе))
иначе - бесконечные исследования "случайных" чипов))

и макетирование на неизвестном чипе, может вообще не превести ни к какому результату))

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 12:43:18
OKF
[uquote="ARV",url="/forum/viewtopic.php?p=4619049#p4619049"]во-первых, я уже много лет DIP стараюсь не применять, кроме как именно макетирование на единственном чипе в DIP-корпусе
во-вторых, макетирование на одном чипе а изготовление на другом, как выяснилось, более не гарантирует результат...[/uquote]
Как то закручено всё. А можно членораздельнее? Ибо не понятно. Для особо одарённых.)

Re: Загадочный чарлиплексинг

Добавлено: Вс авг 25, 2024 12:52:46
ARV
ну... у меня есть единственная atmega328p в DIP-корпусе... я её только для макетирования и применяю. а в проектах, для которых разрабатываю платы, применяю TQFP32 корпуса (еще купил на пробу QFN, но пока не применял).

макетировать в TQFP32 смысла нет, т.к. панельки дорогие, да и нету у меня, а для QFN и панелек-то не существует. с учетом этой темы, результат макетирования в DIP-е не гарантия того, что в другом корпусе заработает, т.к. другой корпус может быть с сюрпризом.

а что касается грубых ошибок, из-за которых вообще не заработает, то я таких не допускаю, т.к. даже перед макетированием всё в протеусе отлаживаю.

Re: Загадочный чарлиплексинг

Добавлено: Пн авг 26, 2024 13:42:41
Demiurg
1. Контрафактные МК могут попасться.
2. Есть ревизии разных годов. Нужно смотреть Errata.
3. Разница по корпусам бывает (DIP SOIC). Нужно уточнять в даташитах.

Re: Загадочный чарлиплексинг

Добавлено: Сб авг 31, 2024 07:59:20
shonty
Вот и мне посчастливилось столкнуться с подобным https://radiokot.ru/forum/viewtopic.php ... 6#p4620636
Написано под один чип, а на 2-х других не желает работать.. :facepalm: правда "аналог" - LGT8f328p
Благо что всё на разъёмах, а проект штучный, для домашней лаборатории.

Re: Загадочный чарлиплексинг

Добавлено: Сб авг 31, 2024 12:01:19
smacorp
shonty, это просто бракованный чип. С купленным на Али, такое не редкость.

Re: Загадочный чарлиплексинг

Добавлено: Вс сен 01, 2024 18:25:00
ARV
А 16-битный таймер работает. Пришлось всё навесить на него, теперь и яркость регулируется, и прочее работает.

Добавлено after 4 hours 18 minutes 23 seconds:
кстати, вот что вышло в итоге:
Изображение
шкальный термометр :))

измеряет в пределах того, что позволяет DS18B20, отображает на шкале от -10°С до +99°С, 48 точек на шкале, каждая точка - 1°, "деления" шкалы автоматически передвигаются так, чтобы текущее значение уместилось на шкале (т.е. на фото шкала 0 - 40, температура 31 но если бы температура была, например, 46, то шкала стала бы 10 - 50). опционально в нижнем "делении" может отображаться истинное значение температуры. так же опционально можно выводить температуру "нормальным способом", т.е. обычными символами (3 варианта), но в этом случае положение должно быть горизонтальным и шкала не отображается. 15 уровней яркости. управление режимами одной кнопкой.
Изображение
Изображение
Изображение

есть лишних 4 платы, могу укомплектовать индикаторами (дешевле рынка, но все равно они очень дорогие, погуглите HCMS-2915). если кому нужно - пишите в ЛС.

Добавлено after 7 minutes 56 seconds:
чарлиплексинг, скажу я вам, довольно противная штука - частота динамической индикации получается высокая, малейшая задержка прерывания индикации неизбежно ведет к изменению яркости одного или нескольких светодиодов... довольно долго ковырялся с тем, чтобы совместить все в коде - работу по 1-wire, где крайне необходимо в некоторые моменты запрещать прерывания на время до 70 микросекунд (примерно), и различные задачи, связанные с некритичным отсчетом времени - период опроса датчика, дребезг кнопки и т.п.

но все получилось :)))