Помогите понять, что творит оптимизатор Си AVR
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: Помогите понять, что творит оптимизатор Си AVR
Этот вариант я писал больше для себя. Заинтересовала задача, вдруг когда буду энкодер использовать. Оказалось проще чем я думал, хотя не поздно все усложнить 
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
я извиняюсь, господа, но что за странные алгоритмы вы используете? матрицы какие-то, состояния... разве не проще завести с контактов энкодера две линии, по одной вызывать прерывание по спаду или фронту и смотреть в обработчике просто на уровень второй линии? если в момент прерывания на второй линии 0 - это вращение в одну сторону, если 1 - в другую... какие матрицы?! или я слишком примитивен?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Помогите понять, что творит оптимизатор Си AVR
Тогда тем более непонятно, что удивительного Вы увидели в том, что этот вариант работает наоборот, по отношению к коду Mika. Ну да ладно.COKPOWEHEU писал(а):Этот вариант я писал больше для себя.
Ну, что вы, вы страшно умный!ARV писал(а):или я слишком примитивен?
Знаете, что существуют два метода - push и poll. 
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
я вашего юмора не понял. потрудитесь объяснить.L.O.D писал(а):Ну, что вы, вы страшно умный! Знаете, что существуют два метода - push и poll.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Помогите понять, что творит оптимизатор Си AVR
Какой такой юмор? Все чистая правда - вы умный и знаете, ну, далее - по тексту.
Только для Mika эта задачка будет несвоевременной:
Только для Mika эта задачка будет несвоевременной:
А в обработчике прерывания INT0 щупаем вторым выводом канал В. И дальше все элементарно!
Если там высокий уровень — делаем +1, если низкий -1 нашему счетному регистру. Кода на три строчки, мне даже писать его лень.
Конечно, можно такой метод прикрутить и на механический энкодер. Но тут надо будет заблокировать прерывания INT0 на несколько миллисекунд. И НИ В КОЕМ СЛУЧАЕ нельзя делать это в обработчике.
Последний раз редактировалось L.O.D Вт апр 05, 2016 08:12:32, всего редактировалось 2 раза.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
я задал конкретный вопрос, цитирую:
если есть какие-то объективные причины, почему мой вариант хуже ваших вариантов или иных упомянутых, я хотел бы их узнать и понять.
и хотел бы получить ответ на него, а не на тот, на который почему-то вы отвечаете в первую очередь:ARV писал(а):разве не проще завести с контактов энкодера две линии, по одной вызывать прерывание по спаду или фронту и смотреть в обработчике просто на уровень второй линии? если в момент прерывания на второй линии 0 - это вращение в одну сторону, если 1 - в другую...
ARV писал(а):или я слишком примитивен?
если есть какие-то объективные причины, почему мой вариант хуже ваших вариантов или иных упомянутых, я хотел бы их узнать и понять.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Помогите понять, что творит оптимизатор Си AVR
Вы не вопрос задали, а захотели блеснуть аффигительной ерундицией: "я извиняюсь, господа, но что за странные алгоритмы вы используете? матрицы какие-то, состояния...".ARV писал(а):я задал конкретный вопрос,
А далее все просто - каков вопрос, таков и ответ.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.
а теперь не будете ли так любезны ответить по существу моего вопроса?
а теперь не будете ли так любезны ответить по существу моего вопроса?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Помогите понять, что творит оптимизатор Си AVR
Читать разучились что ли? Или полагаете, что суть вопроса это только то, что вы сочтете сутью?
PS
PS
Какое самомнение!ARV писал(а):в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.

- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Re: Помогите понять, что творит оптимизатор Си AVR
Отлично, ARV, мне даже и доказывать ничего не надо! 
Ты сам продемонстрировал свое гнилое нутрецо:
Будучи загнанным в угол, включил г***омет?
"Поздравляю вас, гражданин, ..." © Только тут не "соврамши", а кое-что похуже.
Ты сам продемонстрировал свое гнилое нутрецо:
Будучи загнанным в угол, включил г***омет?

"Поздравляю вас, гражданин, ..." © Только тут не "соврамши", а кое-что похуже.
- Вложения
-
- ArvFckgSht.png
- (11.33 КБ) 536 скачиваний
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: Помогите понять, что творит оптимизатор Си AVR
Может хватит спорить чей говномет больше?
ARV, просто приведите свой вариант. Посмотрим его эффективность, объем, помехозащищенность, оформление и та далее.
ARV, просто приведите свой вариант. Посмотрим его эффективность, объем, помехозащищенность, оформление и та далее.
Да сколько повторять - чтобы определить работает он также или наоборот, надо собрать ту же схему и так же назначить выводы. Без этого можно говорить только работает код или нет. Вообще, я поражаюсь вашей способности телепатически определять, что если первый вывод энкодера подключен к PD0, а второй к PD1, то вращению по часовой стрелке должно соответствовать увеличение переменной. При этом не определяя понятия "первый вывод", "второй вывод", "по часовой стрелке" (у колесика мыши, например, такого понятия нет).Тогда тем более непонятно, что удивительного Вы увидели в том, что этот вариант работает наоборот, по отношению к коду Mika. Ну да ладно.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
L.O.D писал(а):Ты сам продемонстрировал свое гнилое нутрецо:
а я и раньше, и впредь буду непрофильные сообщения минусовать. ты ж угомониться сразу не смог, стал "разборки" устраивать? вот и получил минус. и за процитированное твое сообщение тоже получил. что хочешь, то и получаешь. думаю, скоро и модераторы набегут. пока ни одно твое сообщение по теме минус не получало - я умею дело от хрени отличать. успехов!
я даже не знаю, что можно приводить... полностью с нуля все писать как-то лень, а бегло накорябать, так или не понятно будет, или криво. я вот про декодирование RC5 пытался рассказать, как просто делать - все сказали "плохо", а аргументов практически не было, кроме неточных значений выдержки. и с универсальным кодом приема ИК-сигналов с любых пультов та же песня... боюсь, и с энкодером будет то же самое. поэтому вы бы мне на пальцах объяснили, в чем матричный способ или какой иной лучше того, о чем сказал я... хотя бы в теории.COKPOWEHEU писал(а):ARV, просто приведите свой вариант.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: Помогите понять, что творит оптимизатор Си AVR
Самые очевидные недостатки. Привязка к внешнему прерыванию. Это может затруднить разводку. Могут возникнуть проблемы если захочется опрашивать более одного энкодера. Антидребезг потребует использования задержки внутри прерывания (что в любом случае плохо), либо еще и таймера, что серьезно усложнит программу, да и таймеров частенько не хватает. Использование прерывания с высоким приоритетом ухудшает время реакции на внешние события, тем более что как раз энкодер скорости не требует. Плюс некоторое ухудшение модульности - лишняя глобальная переменная. Ну и анализ двух байт (текущего и предыдущего состояний второго вывода) займет какое-то время.
Кроме того, неизвестно, какой из подходов лучше в плане занимаемого места. Мой код, навскидку, занимает 4 байта на инициализацию, 16 байт на процедуру (без учета сохранения регистров, которое далеко не всегда нужно и с ассемблерной вставкой, потому что gcc творит непойми что) и 16 байт на таблицу. Плюс 1 байт ОЗУ. Итого 36 байт ПЗУ и 16 тактов.
Использование прерывания даже без защиты от дребезга потребует, даже без полезного кода, порядка 20 тактов. Впрочем, возможно, вам удастся упаковать лучше, было бы интересно посмотреть.
когда достаточно было этого
Оформление прерывания по минимуму будет выглядеть примерно так
EXT_INT0: ;4 такта на сохранение PC плюс 2 такта на прыжок с таблицы векторов
push temp ;1 такт
in temp,SREG ;1 такт
push temp ;1 такт
lds temp, 0x0060 ;2 такта
;вот тут полезный код ;неизвестно сколько
sts 0x0060,temp ;2 такта
pop temp ;1 такт
out SREG,temp ;1 такт
pop temp ;1 такт
reti ;4 такта
;суммарно как раз 20 тактов плюс полезный код
Кроме того, неизвестно, какой из подходов лучше в плане занимаемого места. Мой код, навскидку, занимает 4 байта на инициализацию, 16 байт на процедуру (без учета сохранения регистров, которое далеко не всегда нужно и с ассемблерной вставкой, потому что gcc творит непойми что) и 16 байт на таблицу. Плюс 1 байт ОЗУ. Итого 36 байт ПЗУ и 16 тактов.
Использование прерывания даже без защиты от дребезга потребует, даже без полезного кода, порядка 20 тактов. Впрочем, возможно, вам удастся упаковать лучше, было бы интересно посмотреть.
Спойлер
Про ассемблерную вставку не просто так написал: gcc сгенерировал вот этоКод: Выделить всё
lds r24, 0x0060
lsr r24
lsr r24
sts 0x0060, r24
if( PIN_0( ENCODER_1 ) )state |= (1<<2); //выставляем биты текущего состояния - 2 и 3 переменной state
sbic 0x16, 0 ; 22
rjmp .+6 ; 0x7a <main+0x22>
ori r24, 0x04 ; 4
sts 0x0060, r24
if( PIN_0( ENCODER_2 ) )state |= (1<<3); //независимо от расположения выводов энкодера
sbic 0x16, 1 ; 22
rjmp .+10 ; 0x88 <main+0x30>
lds r24, 0x0060
ori r24, 0x08 ; 8
sts 0x0060, r24
return pgm_read_byte( &encoder_arr[state] ); //переводим состояние выводов в направление вращения
lds r30, 0x0060
ldi r31, 0x00 ; 0
subi r30, 0xDA ; 218
sbci r31, 0xFF ; 255
lpm r30, Z
;суммарно 28 тактов
Код: Выделить всё
;r30 = state
lds r30,0x0060
;state >>=2
lsr r30
lsr r30
;if( PD0 )state |= (1<<2)
sbic PIND,0
ori r30,0x04
;if( PD1 )state |= (1<<3)
sbic PIND,1
ori r30,0x08
;state = r30
sts 0x0060,r30
;r30 = &encoder_arr[ state ];
ldi r31,0
subi r30,0xDA
sbci r31,0xFF
;r30 = pgm_read_byte( r30 );
lpm r30,Z
;return r30
;суммарно 16 тактов
Оформление прерывания по минимуму будет выглядеть примерно так
EXT_INT0: ;4 такта на сохранение PC плюс 2 такта на прыжок с таблицы векторов
push temp ;1 такт
in temp,SREG ;1 такт
push temp ;1 такт
lds temp, 0x0060 ;2 такта
;вот тут полезный код ;неизвестно сколько
sts 0x0060,temp ;2 такта
pop temp ;1 такт
out SREG,temp ;1 такт
pop temp ;1 такт
reti ;4 такта
;суммарно как раз 20 тактов плюс полезный код
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Помогите понять, что творит оптимизатор Си AVR
благодарю за достаточно развернутый ответ, все, что я хотел, вы мне дали.
с момента, как я перешел на Си в своих поделках, я обращался к ассемблерным вставкам и ассемблеру дважды: когда утрамбовывал в attiny13 свою лампу настроения с дистанционным управлением (ассемблер понадобился для понимания, почему глобальные регистровые переменные портятся по ходу программы) и когда делал многоголосый синтезатор звука (пришлось делать обработчик прерывания полностью в S-файле, иначе не успевал). во всех остальных случаях даже не смотрю, что там GCC наделал. зачем оно вам, мне не понятно, разве что для доказательства выгодности вашего подхода.
кстати, я покопался в своих древних поделиях и нашел, как я сам обрабатывал энкодер. оказалось, почти по-вашему: без массива, но смысл тот же - предыдущее и текущее состояние битов сравнивал, прерывания не задействовал
такая вот эпидерсия вышла...
с момента, как я перешел на Си в своих поделках, я обращался к ассемблерным вставкам и ассемблеру дважды: когда утрамбовывал в attiny13 свою лампу настроения с дистанционным управлением (ассемблер понадобился для понимания, почему глобальные регистровые переменные портятся по ходу программы) и когда делал многоголосый синтезатор звука (пришлось делать обработчик прерывания полностью в S-файле, иначе не успевал). во всех остальных случаях даже не смотрю, что там GCC наделал. зачем оно вам, мне не понятно, разве что для доказательства выгодности вашего подхода.
кстати, я покопался в своих древних поделиях и нашел, как я сам обрабатывал энкодер. оказалось, почти по-вашему: без массива, но смысл тот же - предыдущее и текущее состояние битов сравнивал, прерывания не задействовал
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Помогите понять, что творит оптимизатор Си AVR
Вот и я думаю - сколько мне еще нужно повторять, чтобы Вы поняли, что никакой телепатии тут не нужно - просто сравните свой код с кодом ТСа и узрите, что там, где его код выдаст +1, Ваш выдаст -1, и при том вращении, при котором раньше число на его инкаторе росло, после подстановки Вашего кода оно будет уменьшаться и наоборот. Так понятно?COKPOWEHEU писал(а):Да сколько повторять - чтобы определить работает он также или наоборот, надо собрать ту же схему и так же назначить выводы. Вообще, я поражаюсь вашей способности телепатически определять, ...
ARVе:
Спойлер
Это твой пост:ARV писал(а):ты ж ... стал "разборки" устраивать
и этот тоже:ARV писал(а):я вашего юмора не понял. потрудитесь объяснить.
и т.д. Так что, подбери свой плач-ярославны и не вали с больной головы на здоровую.ARV писал(а):в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.
Договорились. Твои посты про то, какой ты хороший, а я плохой, проминусовал, как непрофильные.ARV писал(а):я и раньше, и впредь буду непрофильные сообщения минусовать.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: Помогите понять, что творит оптимизатор Си AVR
Было бы все-таки интересно глянуть на вашу реализацию на прерывании. Вдруг ТСу понравится.
Ассемблер забывать тоже не стоит. Например, как сейчас, он помогает сравнить разные подходы, посчитать занимаемое место и скорость. Ну и поофигевать иногда над тем что компилятор творит
Ассемблер забывать тоже не стоит. Например, как сейчас, он помогает сравнить разные подходы, посчитать занимаемое место и скорость. Ну и поофигевать иногда над тем что компилятор творит
Разве мой код можно без модификации применить в его устройстве? Я думал что нет, а тогда как можно сравнивать.L.O.D писал(а):сравните свой код с кодом ТСа и узрите, что там, где его код выдаст +1, Ваш выдаст -1
Re: Помогите понять, что творит оптимизатор Си AVR
Я же прямым текстом написал, что и как нужно сравнивать. Прошло не так много времени с тех пор, чтобы потерять нить, но, так и быть, напомню:COKPOWEHEU писал(а):как можно сравнивать.
L.O.D писал(а):Кстати, там нужно транспонировать матрицу, на которой основан массив encoder_arr[16], так как координаты в матрице поменяны местами.COKPOWEHEU писал(а):когда я пример кода выложил
ТС вконец запутается в такой реализации, так как там нужно на ходу включать и выключать INT на время дребезга. О чем, кстати, также уже было написано ранее. "Вы его смерти хочете?" ©COKPOWEHEU писал(а):Было бы все-таки интересно глянуть на вашу реализацию на прерывании. Вдруг ТСу понравится.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Помогите понять, что творит оптимизатор Си AVR
Здравствуйте!
Вот это у вас холивар переходящий на личности, неожиданный расклад. Я рискну вернуться к теме разговора про вынос функций в отдельные файлы и попросить вас всё-же посмотреть мой проект и и подсказать, где я допускаю ошибку
Чтобы не искать, ниже под спойлером я приведу своё сообщение.
[/spoiler]
Вот это у вас холивар переходящий на личности, неожиданный расклад. Я рискну вернуться к теме разговора про вынос функций в отдельные файлы и попросить вас всё-же посмотреть мой проект и и подсказать, где я допускаю ошибку
Чтобы не искать, ниже под спойлером я приведу своё сообщение.
Спойлер
Мikа писал(а):С Ассемблером я знаком, я с ним часы напролет тусовался и дома и на работе
Я, кстати, скачал файлы, в которых реализован Энкодер от COKPOWEHEU, там мало понятного для меня, поэтому улучшение самой функции опроса энкодера оставим на потом, сейчас нужно научиться делать функции во внешних файлах
В общем, что и следовало ожидать - с ходу у меня ничего не получилось, но сегодня с новыми ошибками![]()
При компиляции получается вот что:
Error ld returned 1 exit status
Error undefined reference to `Encoder' EncoderExternal
Error undefined reference to `getEncoderState' EncoderExternal
О чём гласит первая ошибка мне не понятно, следующие говорят о том, что не определена ссылка на эти функции, но я же написал их прототипы в .h файле, сам файл подключил в обоих .c файлах, все как было описано.
Ниже под спойлерами я продублирую содержимое файлов, также в приложении архив с проектом и скриншот того, как я добавил файлы в проект.
Итак, файл main.c
[spoiler]Код: Выделить всё
/*
* EncoderExternal.c
*
* Created: 04.04.2016 0:01:35
* Author : Михаил
*/
#include <avr/io.h>
#include "Encoder.h"
int main(void)
{
// Port D init
DDRD = 0x00;
getEncoderState(); // Получить состояние энкодера в первый раз
while (1)
{
Encoder();
}
}
файл Encoder.hСпойлер
Код: Выделить всё
#ifndef __Encoder_H__
#define __Encoder_H__
// Здесь нет никаких переменных, потому что функция пользууется только локальными переменными
void getEncoderState(void);
void Encoder(void);
#endif
Файл Encoder.cСпойлер
Код: Выделить всё
#include <avr/io.h>
#include "Encoder.h"
static unsigned char Encoder_State = 0;
static signed char Encoder_Summ = 0;
static unsigned char Encoder_NewState = 0;
void getEncoderState(void) // Это нужно для того чтобы получить первое значение состояния энкодера при пуске программы
{
Encoder_State = PIND & 0x3;
}
void Encoder(void)
{
Encoder_NewState = PIND & 0x3;
if(Encoder_State != Encoder_NewState)
{
asm("cli"); //!
switch(Encoder_State)
{
case 2:
{
if(Encoder_NewState == 3) Encoder_Summ++;
if(Encoder_NewState == 0) Encoder_Summ--;
break;
}
case 0:
{
if(Encoder_NewState == 2) Encoder_Summ++;
if(Encoder_NewState == 1) Encoder_Summ--;
break;
}
case 1:
{
if(Encoder_NewState == 0) Encoder_Summ++;
if(Encoder_NewState == 3) Encoder_Summ--;
break;
}
case 3:
{
if(Encoder_NewState == 1) Encoder_Summ++;
if(Encoder_NewState == 2) Encoder_Summ--;
break;
}
}
if (Encoder_Summ == 4) // Увеличение значения числа
{
// Выполняемое действие 1
// В прицнципе здесь должна увеличиться или уменьшиться переменная, передаваемая из основновной программы, но как это сделать пока что не знаю
Encoder_Summ = 0;
}
if (Encoder_Summ == (-4)) // Уменьшение значения числа
{
// Выполняемое действие 2
// В прицнципе здесь должна увеличиться или уменьшиться переменная, передаваемая из основновной программы, но как это сделать пока что не знаю
Encoder_Summ = 0;
}
Encoder_State=Encoder_NewState;
asm("sei")
// Код здесь выполнится в любом случаае
}
}
Я писал я все это по полному подобию того, как вы говорили, но что-то не так.
Надеюсь, вы еще не спите
[/spoiler]
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Re: Помогите понять, что творит оптимизатор Си AVR
А компилятор на что ругается?Мikа писал(а):и подсказать, где я допускаю ошибку
Upd.: Нашел тот пост. Похоже, файл encoder.c не подключен к проекту.
Последний раз редактировалось L.O.D Ср апр 06, 2016 11:02:06, всего редактировалось 1 раз.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Помогите понять, что творит оптимизатор Си AVR
При компиляции получается вот что:
Error ld returned 1 exit status
Error undefined reference to `Encoder' EncoderExternal
Error undefined reference to `getEncoderState' EncoderExternal
О чём гласит первая ошибка мне не понятно, следующие говорят о том, что не определена ссылка на эти функции, но я же написал их прототипы в .h файле, сам файл подключил в обоих .c файлах, все как было описано.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.