| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Работа с битове в C30 за PIC24 http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=8135 |
Страница 1 от 2 |
| Автор: | dan [ Вто Сеп 21, 2010 4:26 pm ] |
| Заглавие: | Работа с битове в C30 за PIC24 |
Здравейте, как се задава битова променлива в C30? |
|
| Автор: | fan [ Вто Сеп 21, 2010 4:44 pm ] |
| Заглавие: | |
http://www.microchip.su/showthread.php? ... hlight=c30 |
|
| Автор: | ¶ [ Сря Сеп 22, 2010 4:47 am ] |
| Заглавие: | |
С обединения ( union ), няма го като вградена променлива. |
|
| Автор: | Цецо [ Сря Сеп 22, 2010 12:40 pm ] |
| Заглавие: | |
А ако си мързелив или правиш портабъл код, може и така: typedef enum { FALSE = 0, TRUE; }BOOL; Естествено това не е оптимално точно за Пик архитектурата. Но пък ще работи на всички процесори ако ти се наложи да прехвърляш кода след това. Неудобството на битовите полета е че трябва да се съобразяваш къде и как си ги дефинирал - локални/глобални, стек, хип, как ще ги изкомбинираш и така нататък. Въобще битовите полета са правени за структурирани данни и са много неудобни когато ти трябват малко на брой отделени по смисъла си на използване битове из целия сорс. Например да си направиш локално флагче за една функцийка. Там използването на цяла дума (8,16 или 32 битова) в стека/регистър е някак си по разбираемо. Е губиш 7,15 или 31 бита на вятъра, ама. Проблема при пиковете е, че имат еднотактови инструкции за работа с битове много удобни и бързи...ама ако пишеш на асемблер. Ама в ANSI C няма подходяща имплементация за целта. Просто стандарта е писан за процесори с друга архитектура. |
|
| Автор: | ¶ [ Сря Сеп 22, 2010 1:48 pm ] | |||||||||
| Заглавие: | ||||||||||
Понякога C30 компилатора се усеща и манипулациите на битовите полета ги прави с BTG, BSF & BCF. |
||||||||||
| Автор: | dan [ Сря Сеп 22, 2010 2:07 pm ] | |||||||||
| Заглавие: | ||||||||||
1.Има ли значение дали ще го направя със struct или с union, щом вътре има само един "елемент"? 2.Ако го направя както е показано на руския сайт, т.е. така :
компилатора как ще подреди променливите в паметта-ще използва ли един адрес за 16 бита? |
||||||||||
| Автор: | Цецо [ Сря Сеп 22, 2010 2:09 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Така е. Ама може ли да направи битово поле локално за функция (в стека или в регистър)? А да предаде битче от битово поле като параметър на функция? Нямам голям опит с тоя компилатор, ама се съмнявам да може такива чудесии. Аз затова на пикове битови полета използвам само когато се нуждая от върховни времена за реакция - например в прекъсване. Или съм закъсал тотално за Рам. И ги правя глобални. Удобни са например за някакви глобални флагове, дето трябва да се виждат от разни места. Ама става доста "мръсен" кода. И не е особенно портабъл.
Ми пусни го и виж асемблерския листинг. Откъде да знаем, зависи сигурно и от опциите с които е извикан, къде точно си вмъкнал тия редове в сорса.... |
|||||||||||||||||||
| Автор: | Gogo [ Сря Сеп 22, 2010 3:19 pm ] | |||||||||
| Заглавие: | ||||||||||
Ето един пример:
|
||||||||||
| Автор: | head_up [ Сря Сеп 22, 2010 3:36 pm ] |
| Заглавие: | |
я се загледайте какво прави отдолу асемблера и ще разберете, че тая операция си хаби доста редове asm код. не съм го правил точно със структури/обединения, а с промяна на бит от специалните регистри и като видях какво се случва ми се изправи косата - от тогава цялата желана стойност за рег-а се хвърля в него със съответното &=/ |=, никакви побитови операции в тоя стил, че ... жална майка като почне да не стига флаша! |
|
| Автор: | ¶ [ Сря Сеп 22, 2010 7:11 pm ] | |||||||||||||||||||||||||||
| Заглавие: | ||||||||||||||||||||||||||||
Ако се използва класическия метод за предаването на параметрите на функция през стека на едното битче винаги ще се направи typecast до широчината на стека. Няма как да вкараш в стека 1 бит, понеже стека е 8, 16 и т.н. битов. Затова битовите полета обикновено се предават чрез указатели като параметри на функция. Вътре във функцията си правиш локална променлива от тип битовото поле и си манипулираш бита който ти трябва. Тогава вече компилатора си използва наличните инструкции за манипулации на бит. Ето един пример:
Понеже не използвам локална променлива ами директно манипулирам битовото поле чрез указател, то ясно се вижда, че компилатора първо извлича в регистър стойността на битовото поле от паметта, след това използва blcr/bset за да присвои нова стойност, после обратно копира регистъра в паметта. Дори обаче да бях използвал локална променлива, компилатора отново ще използва същия брой инструкции, защото bclr/bset инструкциите могат да работят само с директна адресация, т.е. предварително те трябва да знаят адреса в паметта. Ако професора позволяваше индиректна адресация с битовите инструкции компилатора нямаше да се замисли да ги използва. PIC30/33/24 компилаторите са GCC компилатори и са много добре оптимизирани, поне досега не съм намерил парче код, който бих го направил кой знае колко по-бърз, ако започна да го оптимизирам на ръка. Ако обаче вътре във функцията дефинирам моето битово поле като static, тогава компилатора използва директната адресация на bclr/bset и си манипулира директно битовете:
По принцип идеята на bclr/bset/btg инструкциите е за манипулиране на служебните регистри плюс глобално дефинираните променливи ( които са статични ). |
||||||||||||||||||||||||||||
| Автор: | Цецо [ Чет Сеп 23, 2010 10:31 am ] | |||||||||
| Заглавие: | ||||||||||
Аха де и аз това казвам. |
||||||||||
| Автор: | dan [ Чет Сеп 23, 2010 11:47 pm ] | ||||||||||||||||||||||||||||||||||||
| Заглавие: | |||||||||||||||||||||||||||||||||||||
Направих го със структура и typedef. Изникна обаче следващия проблем:когато искам да използвам тази пременлива в друг файл от този проект, нещо не става. Направих така:
В друг .c файл съм направил това:
излиза ми следната грешка:
и за мястото, където се обръщам към бита:
Странното е, че всичко работеше, докато нещата ми бяха в един файл. Щом пробвах да ги разделя в два файла- работата се оплеска. |
|||||||||||||||||||||||||||||||||||||
| Автор: | head_up [ Пет Сеп 24, 2010 9:57 am ] | ||
| Заглавие: | |||
първо: не вижда къде си указал какво е bitvar, за това мяка - трябва да му инклиднеш .h файла където си разписал typedef на bitvar. обаче се чудя защо я правиш тая акробатика като можеш да ползваш това (виж приложението). не помня дали съм го копал отделно или е дошло с C30-ката, ама съм го ползвал за една 24-ка (сефте ги ползвах, както и C за PIC).
|
|||
| Автор: | Цецо [ Пет Сеп 24, 2010 10:04 am ] | |||||||||
| Заглавие: | ||||||||||
Начи не става ясно как втория .c фаил (този в който имаш extern) вижда дефиницията на новия тип "bitvar". Ако в второто си includ-нал първото, ще имаш проблем, щото два пъти дефинираш едно и също (bitvar error_m_B). Ако не си го includ-нал (което вероятно не си направил), пак имаш проблем щото във второто ползваш типа (bitvar) без да си го дефинирал преди това. Обикновенно практиката е в един съвсем отделен фаил да се сложат всички typdef които ползваш насам натам. Точно по начина по който ти показа head_up преди мен. После този фаил си го инклудваш където ползваш тези типове и си ок. Обърни внимание обаче на редовете: #ifndef Generic_Type_Defs_h #define __Generic_Type_Defs_h #endif //__GENERIC_TYPE_DEFS_H_ Те са ти задължителни! |
||||||||||
| Автор: | dan [ Пет Сеп 24, 2010 12:07 pm ] |
| Заглавие: | Ново 20 |
Направих един общ .h файл с всички променливи, но като го инклудна на няколко места дава грешката "multiple definition of...". После преместих променливите в друг файл var.c, а в vars.h ги зададох като extern. Въпреки това проблема с "multiple definition of..." си остава. Ако пък махна дефиницията на променливите от хедъра (т.е. вместо extern int а=10 напиша extern int a), излиза съобщениято за грешка "undefined reference to..." What could i do? (Както пее Махалия Джаксън |
|
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|