arduino и конденсатор

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

Точно. Про else забыл. Но подобный макрос изврат в любом случае. Лучше уж inline:

Код: Выделить всё

static inline void lighton(void)
{
    PORTB |= (1 << PB3);
    DDRB |= (1 << DDRB3);
}
Ардуинщик. Не шарю в электронике.
Реклама
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Макрос - не изврат, а вполне себе стандартная практика. А inline - не панацея. Это всего-лишь хинт компилятору. Не факт, что будет инлайн. Ладно еще с avr-gcc, на другой платформе, например PIC с XC8 там вообще всё плохо с этим.
Плюс макрос можно закинуть в .h и вызывать из разных .c.
Реклама
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

[uquote="NStorm",url="/forum/viewtopic.php?p=3722831#p3722831"]Макрос - не изврат, а вполне себе стандартная практика.[/uquote]

Макрос норм, но подобный макрос изврат ещё тот.
А inline - не панацея. Это всего-лишь хинт компилятору. Не факт, что будет инлайн.
Если не использовать опции оптимизации, то точно не будет. А если делать -Os - что для avr-gcc strongly recommended - то всё норм.
Или использовать __attribute__((always_inline)).
Ладно еще с avr-gcc, на другой платформе, например PIC с XC8 там вообще всё плохо с этим.
Ну, это прискорбно. Но это не значит, что на нормальных платформах теперь тоже стоит себя ограничивать в удобных инструментах :-).
Плюс макрос можно закинуть в .h и вызывать из разных .c.
Так и static inline тоже - никаких проблем. Так и используют. Вот, хотя бы, list.h - https://github.com/torvalds/linux/blob/ ... nux/list.h .

Добавлено after 2 minutes:
[uquote="NStorm",url="/forum/viewtopic.php?p=3722831#p3722831"]Макрос - не изврат, а вполне себе стандартная практика.[/uquote]

И, кстати, одно другому не противоречит ;-) :-). Это не перестаёт быть извратом от того, что его часто используют.
Ардуинщик. Не шарю в электронике.
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

__attribute__((always_inline)).
Есть только в gcc. Страдает переносимость кода. Хотя если она не нужна, можно и inline конечно. Если точно уверены в своём компиляторе. Ядру Linux-то пофиг на накладные расходы, если они возникнут. А для МК это критично.
Но для записи битика в пару регистров честно не вижу смысла городить функцию. Диод ставить куда больший изврат )))

PS: Там еще могут быть нюансы при вызове из прерывания.

Добавлено after 14 minutes 20 seconds:
А если делать -Os - что для avr-gcc strongly recommended - то всё норм.
А вот как раз таки наоборот. При -Os делается rcall:

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <stdbool.h>

static inline void lighton(void) {
    PORTB |= (1 << PB3);
    DDRB |= (1 << PB3);
}

static inline void lightoff(void) {
    PORTB &= ~(1 << PB3);
    DDRB &= ~(1 << PB3);
}

ISR(INT0_vect) {
    lighton();
}

int main() {
  lightoff();
  _NOP();
  lighton();
  while(true);
}
avr-gcc -std=gnu11 -Os -g -mmcu=atmega8 inline.c -o inline && avr-objdump -d inline > inline.lss
inline.lss:

Код: Выделить всё

...
00000038 <lighton>:
  38:   c3 9a           sbi     0x18, 3 ; 24
  3a:   bb 9a           sbi     0x17, 3 ; 23
  3c:   08 95           ret

0000003e <__vector_1>:
  3e:   1f 92           push    r1
  40:   0f 92           push    r0
  42:   0f b6           in      r0, 0x3f        ; 63
  44:   0f 92           push    r0
  46:   11 24           eor     r1, r1
  48:   2f 93           push    r18
  4a:   3f 93           push    r19
  4c:   4f 93           push    r20
  4e:   5f 93           push    r21
  50:   6f 93           push    r22
  52:   7f 93           push    r23
  54:   8f 93           push    r24
  56:   9f 93           push    r25
  58:   af 93           push    r26
  5a:   bf 93           push    r27
  5c:   ef 93           push    r30
  5e:   ff 93           push    r31
  60:   eb df           rcall   .-42            ; 0x38 <lighton>
  62:   ff 91           pop     r31
  64:   ef 91           pop     r30
  66:   bf 91           pop     r27
  68:   af 91           pop     r26
  6a:   9f 91           pop     r25
  6c:   8f 91           pop     r24
  6e:   7f 91           pop     r23
  70:   6f 91           pop     r22
  72:   5f 91           pop     r21
  74:   4f 91           pop     r20
  76:   3f 91           pop     r19
  78:   2f 91           pop     r18
  7a:   0f 90           pop     r0
  7c:   0f be           out     0x3f, r0        ; 63
  7e:   0f 90           pop     r0
  80:   1f 90           pop     r1
  82:   18 95           reti

00000084 <main>:
  84:   c3 98           cbi     0x18, 3 ; 24
  86:   bb 98           cbi     0x17, 3 ; 23
  88:   00 00           nop
  8a:   d6 df           rcall   .-84            ; 0x38 <lighton>
  8c:   ff cf           rjmp    .-2             ; 0x8c <main+0x8>
...
Забавно, но такой простой пример выдает с -Os код больше, чем с -Og/-O1 из-за всех этих телодвижений со стеком. -O1 действительно делает инлайн:

Код: Выделить всё

00000044 <__vector_1>:
  44:   1f 92           push    r1
  46:   0f 92           push    r0
  48:   0f b6           in      r0, 0x3f        ; 63
  4a:   0f 92           push    r0
  4c:   11 24           eor     r1, r1
  4e:   c3 9a           sbi     0x18, 3 ; 24
  50:   bb 9a           sbi     0x17, 3 ; 23
  52:   0f 90           pop     r0
  54:   0f be           out     0x3f, r0        ; 63
  56:   0f 90           pop     r0
  58:   1f 90           pop     r1
  5a:   18 95           reti
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

[uquote="NStorm",url="/forum/viewtopic.php?p=3722868#p3722868"]
__attribute__((always_inline)).
Есть только в gcc. Страдает переносимость кода. Хотя если она не нужна, можно и inline конечно. Если точно уверены в своём компиляторе. Ядру Linux-то пофиг на накладные расходы, если они возникнут. А для МК это критично.[/uquote]

Я вас умоляю. Если для проекта вызов функции критичен, то надо либо в сторону ассемблера смотреть, либо в сторону контроллера помощнее. Какой смысл жертвовать читаемостью кода, отдавая предпочтение разным хакам.
Но для записи битика в пару регистров честно не вижу смысла городить функцию.
Если это делается двумя выражениями, как выше, плюс do/while(0), то уж лучше функция. Хотя, это субъективно. Каждый сам определяет, когда нужно остановиться :-).
Диод ставить куда больший изврат )))
Для обучения норм :-).
А если делать -Os - что для avr-gcc strongly recommended - то всё норм.
А вот как раз таки наоборот. При -Os делается rcall:
rcall делается с ISR. Если эту конструкцию убрать, то с inline всё норм.
Ардуинщик. Не шарю в электронике.
Реклама
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

do { ... } while(0) макро из моего примера подставляется в 2 инструкции asm sbi/cbi. Всегда и везде. Даже с отключенной оптимизацией сами do {} while(0) ни во что не собираются и не дают накладных расходов. Это просто что-то противоположное синтаксическому сахару.
А rcall делается, в случае с функций, что из main(), что из ISR. Вы соберите мой пример сами. С -Os он у меня вроде 146 байт занимал. С -O1 уже 96 байт. Вот и оптимизация по размеру ) А всё из-за тонны вызовов push/pop для сохранения регистров. А вовсе не из-за rcall конечно же.
Если для проекта вызов функции критичен, то надо либо в сторону ассемблера смотреть, либо в сторону контроллера помощнее.
Мне как-то несколько байт не хватало ) Пришлось пожертвовать читаемостью кода и все функции запихнуть одной простыней. Зато влезло в текущий МК, который был под рукой и который не надо было покупать. Это когда речь о личных поделках.
А в серийных ус-ах порой разница в цене за счет серийности может встать в существенную сумму. Всякое бывает.
Хотя, это субъективно. Каждый сам определяет, когда нужно остановиться :-).
Именно. На самом деле не критично в большинстве случаев. Мне просто максос с do {} while(0) никак читаемость кода не ухудшает, я к ним привык, они много кем используются. Но случаи бывают разные. )
Реклама
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

[uquote="NStorm",url="/forum/viewtopic.php?p=3722975#p3722975"]А rcall делается, в случае с функций, что из main(), что из ISR.[/uquote]

Вы меня не так поняли. Если убрать это из кода:

Код: Выделить всё

ISR(INT0_vect) {
    lighton();
}
То вызовов функции не будет в main. Она будет инлайниться. Если эту часть кода оставить, то везде будет вызов lighton и только lightoff будет инлайниться. Видимо, действительно, прерывания вносят что-то своё тут.
Мне как-то несколько байт не хватало ) Пришлось пожертвовать читаемостью кода и все функции запихнуть одной простыней. Зато влезло в текущий МК, который был под рукой и который не надо было покупать. Это когда речь о личных поделках.
Прикольно :-).
А в серийных ус-ах порой разница в цене за счет серийности может встать в существенную сумму. Всякое бывает.
Ну, смотря какое серийное производство. Если это промышленное оборудование какое-то, то цена контроллера потеряется среди прочего оборудования, которое он будет мониторить/управлять. И в этом случае для стабильности и надёжности лучше выбрать что-то помощнее и с большей памятью, что бы не извращаться с исходным кодом, ибо больше хаков - больше потенциальных ошибок.
Ардуинщик. Не шарю в электронике.
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

То вызовов функции не будет в main. Она будет инлайниться.
Не хочет )

inline.c:

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <stdbool.h>

static inline void lighton(void) {
    PORTB |= (1 << PB3);
    DDRB |= (1 << PB3);
}

static inline void lightoff(void) {
    PORTB &= ~(1 << PB3);
    DDRB &= ~(1 << PB3);
}

void fn() {
  lighton();
}

int main() {
  fn();
  _NOP();
  lightoff();
  _NOP();
  lighton();
  while(true);
}
Выхлоп -Os:

Код: Выделить всё

...
00000038 <lighton>:
  38:   c3 9a           sbi     0x18, 3 ; 24
  3a:   bb 9a           sbi     0x17, 3 ; 23
  3c:   08 95           ret

0000003e <fn>:
  3e:   fc cf           rjmp    .-8             ; 0x38 <lighton>

00000040 <main>:
  40:   fb df           rcall   .-10            ; 0x38 <lighton>
  42:   00 00           nop
  44:   c3 98           cbi     0x18, 3 ; 24
  46:   bb 98           cbi     0x17, 3 ; 23
  48:   00 00           nop
  4a:   f6 df           rcall   .-20            ; 0x38 <lighton>
  4c:   ff cf           rjmp    .-2             ; 0x4c <main+0xc>
...
А с макросом, что из ISR, что из обычных функций rcall/rjmp не будет )
Последний раз редактировалось NStorm Ср окт 23, 2019 14:27:40, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 15600
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Ужжшшш выбирайте Си или ассемблер.
8)
Надо хоть под каким-нибудь для начала более-менее разобраться.
:wink:
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

[uquote="NStorm",url="/forum/viewtopic.php?p=3723408#p3723408"]
То вызовов функции не будет в main. Она будет инлайниться.
Не хочет )[/uquote]

Да. Точно. Не подумал проверить вызов внутри функции. В этом случае только __attribute__((always_inline)) помогает.
Ардуинщик. Не шарю в электронике.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

NStorm, а вы уверены что static inline void у вас действительно inline ,
у меня к примеру что static inline void что static void - одно и то же.
А вот если так указать static inline __attribute__((__always_inline__)) void , то уже совсем другое.

И наиболее оптимальная схема
СпойлерИзображение
Если R1 сделать равным R2 300 кОм будет и плавное включение.
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Dimon456, я не знаю о чем вы. Я написал, что я уверен, что static inline в определенных случаях становитсяы по факту вовсе не inline, а обычной функцией. И это нормальное поведение в соответствии со стандартом. А __attribute__((__always_inline__)) это нестандартное расширение gcc, о чем я тоже писал уже.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

NStorm, приведите пример.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Dimon456, я несколько раз проверял: gcc при нормальной оптимизации (-O2) static inline обычно раскрывает и подставляет куда нужно. А вот при -Os он оформляет ее как функцию, тратя уйму ресурсов на работу со стеком… Выше уже было про это: в некоторых случаях static inline при -Os приводят к увеличению объема кода…
Вот с sdcc похуже: этот гад творит что хочет!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Dimon456, а выше что? Прочитайте тему целиком пожалуйста, все примеры приведены, всё раскрыто и расписано.

Добавлено after 4 minutes 27 seconds:
Eddy_Em, так и есть, я о том же. Соб-но выше даже показал выхлоп ассемблерный с разными опциями оптимизации на примерах. Но какие-то еще примеры просят )
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Давайте я тогда свой пример приведу
СпойлерСледующий код-1

Код: Выделить всё

 static inline void lighton(void) {
    PORTB |= (1 << PB3);
    DDRB |= (1 << PB3);
}

static inline void lightoff(void) {
    PORTB &= ~(1 << PB3);
    DDRB &= ~(1 << PB3);
}

void fn(void) {
  lighton();
}

ISR(INT0_vect) {
    lighton();
}

int main(void) {
  fn();
  _NOP();
  lightoff();
  _NOP();
  lighton();
  while(true);
}
компилируется в 232 байта. -Os
На выходе имеем

Код: Выделить всё

00000080 <lighton>:
  80:	2b 9a       	sbi	0x05, 3	; 5
  82:	23 9a       	sbi	0x04, 3	; 4
  84:	08 95       	ret

00000086 <fn>:
  86:	0c 94 40 00 	jmp	0x80	; 0x80 <lighton>

0000008a <__vector_1>:
  8a:	1f 92       	push	r1
  8c:	0f 92       	push	r0
  8e:	0f b6       	in	r0, 0x3f	; 63
  90:	0f 92       	push	r0
  92:	11 24       	eor	r1, r1
  94:	2f 93       	push	r18
  96:	3f 93       	push	r19
  98:	4f 93       	push	r20
  9a:	5f 93       	push	r21
  9c:	6f 93       	push	r22
  9e:	7f 93       	push	r23
  a0:	8f 93       	push	r24
  a2:	9f 93       	push	r25
  a4:	af 93       	push	r26
  a6:	bf 93       	push	r27
  a8:	ef 93       	push	r30
  aa:	ff 93       	push	r31

  ac:	0e 94 40 00 	call	0x80	; 0x80 <lighton>

  b0:	ff 91       	pop	r31
  b2:	ef 91       	pop	r30
  b4:	bf 91       	pop	r27
  b6:	af 91       	pop	r26
  b8:	9f 91       	pop	r25
  ba:	8f 91       	pop	r24
  bc:	7f 91       	pop	r23
  be:	6f 91       	pop	r22
  c0:	5f 91       	pop	r21
  c2:	4f 91       	pop	r20
  c4:	3f 91       	pop	r19
  c6:	2f 91       	pop	r18
  c8:	0f 90       	pop	r0
  ca:	0f be       	out	0x3f, r0	; 63
  cc:	0f 90       	pop	r0
  ce:	1f 90       	pop	r1
  d0:	18 95       	reti

000000d2 <main>:
  d2:	0e 94 40 00 	call	0x80	; 0x80 <lighton>
  d6:	00 00       	nop
  d8:	2b 98       	cbi	0x05, 3	; 5
  da:	23 98       	cbi	0x04, 3	; 4
  dc:	00 00       	nop
  de:	0e 94 40 00 	call	0x80	; 0x80 <lighton>
  e2:	ff cf       	rjmp	.-2      	; 0xe2 <main+0x10>
Теперь так, код-2

Код: Выделить всё

 static void lighton(void) {
    PORTB |= (1 << PB3);
    DDRB |= (1 << PB3);
}

 static void lightoff(void) {
    PORTB &= ~(1 << PB3);
    DDRB &= ~(1 << PB3);
}

void fn(void) {
  lighton();
}

ISR(INT0_vect) {
    lighton();
}

int main(void) {
  fn();
  _NOP();
  lightoff();
  _NOP();
  lighton();
  while(true);
}
По прежнему 232 байта. -Os
На выходе

Код: Выделить всё

00000080 <lighton>:
  80:	2b 9a       	sbi	0x05, 3	; 5
  82:	23 9a       	sbi	0x04, 3	; 4
  84:	08 95       	ret

00000086 <fn>:
  86:	0c 94 40 00 	jmp	0x80	; 0x80 <lighton>

0000008a <__vector_1>:
  8a:	1f 92       	push	r1
  8c:	0f 92       	push	r0
  8e:	0f b6       	in	r0, 0x3f	; 63
  90:	0f 92       	push	r0
  92:	11 24       	eor	r1, r1
  94:	2f 93       	push	r18
  96:	3f 93       	push	r19
  98:	4f 93       	push	r20
  9a:	5f 93       	push	r21
  9c:	6f 93       	push	r22
  9e:	7f 93       	push	r23
  a0:	8f 93       	push	r24
  a2:	9f 93       	push	r25
  a4:	af 93       	push	r26
  a6:	bf 93       	push	r27
  a8:	ef 93       	push	r30
  aa:	ff 93       	push	r31

  ac:	0e 94 40 00 	call	0x80	; 0x80 <lighton>

  b0:	ff 91       	pop	r31
  b2:	ef 91       	pop	r30
  b4:	bf 91       	pop	r27
  b6:	af 91       	pop	r26
  b8:	9f 91       	pop	r25
  ba:	8f 91       	pop	r24
  bc:	7f 91       	pop	r23
  be:	6f 91       	pop	r22
  c0:	5f 91       	pop	r21
  c2:	4f 91       	pop	r20
  c4:	3f 91       	pop	r19
  c6:	2f 91       	pop	r18
  c8:	0f 90       	pop	r0
  ca:	0f be       	out	0x3f, r0	; 63
  cc:	0f 90       	pop	r0
  ce:	1f 90       	pop	r1
  d0:	18 95       	reti

000000d2 <main>:
  d2:	0e 94 40 00 	call	0x80	; 0x80 <lighton>
  d6:	00 00       	nop
  d8:	2b 98       	cbi	0x05, 3	; 5
  da:	23 98       	cbi	0x04, 3	; 4
  dc:	00 00       	nop
  de:	0e 94 40 00 	call	0x80	; 0x80 <lighton>
  e2:	ff cf       	rjmp	.-2      	; 0xe2 <main+0x10>

Теперь такой код-3

Код: Выделить всё

#define INLINE static inline __attribute__((__always_inline__))


 INLINE void lighton(void) {
    PORTB |= (1 << PB3);
    DDRB |= (1 << PB3);
}

 INLINE void lightoff(void) {
    PORTB &= ~(1 << PB3);
    DDRB &= ~(1 << PB3);
}

void fn(void) {
  lighton();
}

ISR(INT0_vect) {
    lighton();
}

int main(void) {
  fn();
  _NOP();
  lightoff();
  _NOP();
  lighton();
  while(true);
}
компилируется уже в 162 байта. -Os
и на выходе

Код: Выделить всё

00000080 <fn>:
  80:	2b 9a       	sbi	0x05, 3	; 5
  82:	23 9a       	sbi	0x04, 3	; 4
  84:	08 95       	ret

00000086 <__vector_1>:
  86:	2b 9a       	sbi	0x05, 3	; 5
  88:	23 9a       	sbi	0x04, 3	; 4
  8a:	18 95       	reti

0000008c <main>:
  8c:	0e 94 40 00 	call	0x80	; 0x80 <fn>
  90:	00 00       	nop
  92:	2b 98       	cbi	0x05, 3	; 5
  94:	23 98       	cbi	0x04, 3	; 4
  96:	00 00       	nop
  98:	2b 9a       	sbi	0x05, 3	; 5
  9a:	23 9a       	sbi	0x04, 3	; 4
  9c:	ff cf       	rjmp	.-2      	; 0x9c <main+0x10>
Не хотите в void fn(void) добавить INLINE void fn(void)?
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

Dimon456, вы не так поняли :-). Насчёт того, что __attribute__((always_inline)) работает никто не сомневается. Разговор был про то, что inline не всегда работает. И в этом, в принципе, тоже никто не сомневается. А изначально разговор был о равнозначной по функциональности замене define функцией с inline. Вывод такой, что кому надо не только gcc, то лучше define.

Добавлено after 1 minute 58 seconds:
[uquote="Dimon456",url="/forum/viewtopic.php?p=3723560#p3723560"]И наиболее оптимальная схема
Изображение[/uquote]

Я ж правильно понимаю, что R2 можно безболезненно убрать в случае, когда pin переключается с 1 на 0(без HiZ)? Т.е. его единственная задача убирать наводки с базы в случае, когда на пине HiZ, так?
Ардуинщик. Не шарю в электронике.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

R2 служит для разрядки конденсатора С1 пока транзистор не закроется.
Два варианта схемы с HiZ.
1- R1=2кОм R2 300кОм, моментальное включение, плавное погасание.
2- R1=300кОм R2 300кОм, плавное включение, плавное погасание.

Один варианта схемы без HiZ.
R1=300кОм R2 убрать, плавное включение, плавное погасание (разряд конденсатора через пин порта).
Встал на лапы
Сообщения: 141
Зарегистрирован: Чт сен 26, 2019 20:42:21

Сообщение oleg_4rk »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3724117#p3724117"]Один варианта схемы без HiZ.
R1=300кОм R2 убрать, плавное включение, плавное погасание (разряд конденсатора через пин порта).[/uquote]

Если конденсатор разряжается через пин, а не через транзистор, то никакого плавного погасания нет. Если же добавить слева R1 диод, то всё норм.

Хотя, нет. Наверное будет с 300 КОм. У меня нет таких больших, я с 10 КОм проверял.
Ардуинщик. Не шарю в электронике.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

По "оптимальной схеме"
Изображение

Господа, откуда тут будет плавное зажигание-угасание?
Конденсатор через R1 заряжается до момента открывания транзистора, потом будет короткий период действительно плавного открывания транзистора, но потом напряжение на конденсаторе останется равным напряжению падения на открытом переходе база-эммитер.....
Т.е. условно, конденсатор заряжается до 0.55 вольта через резистор, потом начинает открываться транзистор и... всё.... при 0.65-0.7 вольта заряд ёмкости прекратится..... И из всей схемы плавность работает в диапазоне 100-200 мВ...
Либо ставить большую емкость надо, что бы плавносьт была заметна глазу....
"Помоему так" (ц) Иа

Как вариант - вижу перенос светодиода с резистором в эммитерную цепь... получаем каскад с ОК (эммитерный повторитель).
Тогда плавное зажигание светодиода будет начинаться от 1.5-2 вольт на базе (зависит от падения напряжения на переходе светодиода) и до полного питания (в случае 5 вольт питания - диапазон 2..5 вольт).
Либо менять биполярник на какой то полевик низковольтный.

Dimon456, Т.е. с точки зрения оптимизации gcc static в случае inline-функций - зло?

И кто-нибудь, подскажите сакральный смысл static в определении функций в чистом Си (не ++)?
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Ответить

Вернуться в «AVR»