RTV forum PL | NewsGroups PL

Definiowane portów/flag w C

NOWY TEMAT

elektroda.net NewsGroups Forum Index - Elektronika Polska - Definiowane portów/flag w C

Goto page 1, 2  Next

sword
Guest

Thu Oct 19, 2017 11:01 am   



Cześć,

Może nie do końca ta grupa ale wielu z Was pisze w C i może mi podpowie :)

Korzystam z takich makr, które pracują na bitach, np.:

#define setbit(VAR,Place) ( (VAR) |= (uint8_t)((uint8_t)1<<(uint8_t)(Place)) )

w programie mam zdefiniowane np.:

#define PORT_LED GPIOA
#define LED_R 0

uint8_t main_flags1, main_flags2, main_flags3;
#define FLAGA1 0
#define FLAGA2 0


i później takie wykorzystanie np.:

setbit(PORT_LED, LED_R);
setbit(main_flags, FLAGA1);
setbit(main_flags2, FLAGA2);

Przy portach to jeszcze nie jest problemu ale przy flagach trzeba
ręcznie panować nad tym w której zmiennej leży jaka flaga. Już
kilka razy szukałem przez to błędów.

Jak zrobić, żeby odwołanie do flagi było jednoznaczne, chodziło by mi
o coś takiego (co nie działa przez ten przecinek):

#define F_LED_R PORT_LED,LED_R

setbit(F_LED_R);

Wtedy w programie nie muszę się już zastanawiać gdzie leży jaki bit.

Zawsze tak pisałem w asm, a teraz mi tego brakuje :)


Pozdrawiam,
--
sword

sword
Guest

Thu Oct 19, 2017 12:15 pm   



On 2017-10-19 13:47, Adam Wysocki wrote:
Quote:
sword <nick_at_poczta.onet.pl> wrote:

Jak zrobić, żeby odwołanie do flagi było jednoznaczne, chodziło by mi
o coś takiego (co nie działa przez ten przecinek):

#define F_LED_R PORT_LED,LED_R

setbit(F_LED_R);

#define led_set() set_bit(PORT_LED, LED_R)

Ja tych makr mam więcej, to był tylko przykład z 'setbit'.
Chodzi o to, żeby w dowolnym makrze można było podstawić port
lub flagę nie generując przy tym osobnego makra dla każdego
przypadku, np.:

setbit(F_LED_R);
clrbit(F_LED_R);
chgbit(F_LED_R);
if (valbit(F_LED_R))


--
sword

Waldemar
Guest

Thu Oct 19, 2017 12:30 pm   



Am 19.10.2017 um 14:15 schrieb sword:
Quote:
On 2017-10-19 13:47, Adam Wysocki wrote:
sword <nick_at_poczta.onet.pl> wrote:

Jak zrobić, żeby odwołanie do flagi było jednoznaczne, chodziło by mi
o coś takiego (co nie działa przez ten przecinek):

#define F_LED_R PORT_LED,LED_R

setbit(F_LED_R);

#define led_set() set_bit(PORT_LED, LED_R)

Ja tych makr mam więcej, to był tylko przykład z 'setbit'.
Chodzi o to, żeby w dowolnym makrze można było podstawić port
lub flagę nie generując przy tym osobnego makra dla każdego
przypadku, np.:

setbit(F_LED_R);
clrbit(F_LED_R);
chgbit(F_LED_R);
if (valbit(F_LED_R))

a czemu upierasz się przy makrach? Nie możesz dać inline function?

Waldek

Adam Wysocki
Guest

Thu Oct 19, 2017 1:47 pm   



sword <nick_at_poczta.onet.pl> wrote:

Quote:
Jak zrobić, żeby odwołanie do flagi było jednoznaczne, chodziło by mi
o coś takiego (co nie działa przez ten przecinek):

#define F_LED_R PORT_LED,LED_R

setbit(F_LED_R);

#define led_set() set_bit(PORT_LED, LED_R)

--
[ Email: a_at_b a=grp b=chmurka.net ]
[ Web: http://www.chmurka.net/ ]

Sebastian Biały
Guest

Thu Oct 19, 2017 6:17 pm   



On 10/19/2017 1:01 PM, sword wrote:
Quote:
Wtedy w programie nie muszę się już zastanawiać gdzie leży jaki bit.

Nie musisz jesli użyjesz C++. Nie mam stosownego przykładu pod reką w
tej chwili ale kilka lat temu mając ochote ukręcić leb idiotom od
definicji rejestrow SAM7 narzeźbilem coś takiego i "sprzedałem" kod.
Napisanie tego na nowo jest w zasadzie osiągalne.

Oczywiście od razu informacja dla wszystkich co podskoczyli na hasło C++
- ten mechanizm nie genaruje ani bajta więcej w kodzie. To
metaprogramowanie na szablonach, operatorach itd, na końcu wychodzi to
samo tylko pewne i bez głupich pomyłek i wygląda prawie identycznie.

sword
Guest

Thu Oct 19, 2017 7:14 pm   



On 2017-10-19 14:30, Waldemar wrote:
Quote:
Ja tych makr mam więcej, to był tylko przykład z 'setbit'.
Chodzi o to, żeby w dowolnym makrze można było podstawić port
lub flagę nie generując przy tym osobnego makra dla każdego
przypadku, np.:

setbit(F_LED_R);
clrbit(F_LED_R);
chgbit(F_LED_R);
if (valbit(F_LED_R))

a czemu upierasz się przy makrach? Nie możesz dać inline
function?

Hmm, mogę dać inline ale wydaje mi się, że jestem w tym samym
punkcie co z makrami.

static inline void setbit (u8 port, u8 pin)
{
port |= 1<<pin;
}

No i co dalej? Chciałbym ją tak samo wywołać, np.:

setbit(F_LED)


--
sword

sword
Guest

Thu Oct 19, 2017 7:15 pm   



On 2017-10-19 20:17, Sebastian Biały wrote:
Quote:
On 10/19/2017 1:01 PM, sword wrote:
Wtedy w programie nie muszę się już zastanawiać gdzie leży
jaki bit.

Nie musisz jesli użyjesz C++. Nie mam stosownego przykładu
pod reką w tej chwili ale kilka lat temu mając ochote
ukręcić leb idiotom od definicji rejestrow SAM7 narzeźbilem
coś takiego i "sprzedałem" kod. Napisanie tego na nowo jest
w zasadzie osiągalne.

Oczywiście od razu informacja dla wszystkich co podskoczyli
na hasło C++ - ten mechanizm nie genaruje ani bajta więcej w
kodzie. To metaprogramowanie na szablonach, operatorach itd,
na końcu wychodzi to samo tylko pewne i bez głupich pomyłek
i wygląda prawie identycznie.

Ja mam C na sztywno w tym projekcie i nie dam rady przeskoczyć
na C++.

--
sword

Sebastian Biały
Guest

Thu Oct 19, 2017 7:19 pm   



On 10/19/2017 9:15 PM, sword wrote:
Quote:
Ja mam C na sztywno w tym projekcie i nie dam rady przeskoczyć
na C++.

Z powodu jakiego? Technicznego czy białkowego?

Grzegorz Niemirowski
Guest

Thu Oct 19, 2017 7:38 pm   



sword <nick_at_poczta.onet.pl> napisał(a):
Quote:
Hmm, mogę dać inline ale wydaje mi się, że jestem w tym samym
punkcie co z makrami.
static inline void setbit (u8 port, u8 pin)
{
port |= 1<<pin;
}
No i co dalej? Chciałbym ją tak samo wywołać, np.:
setbit(F_LED)


Musisz stworzyć coś, co oprócz bitu będzie nisło też informację o porcie,
np.

#include <stdio.h>

#define PINA1 0x01
#define PINA2 0x02
#define PINB2 0x02
#define PINB3 0x03

#define F_PINA1 (0x0000 | PINA1)
#define F_PINA2 (0x0000 | PINA2)
#define F_PINB2 (0x0100 | PINB2)
#define F_PINB3 (0x0100 | PINB3)

int porta = 0, portb = 0;

void setpin(unsigned int fpin);

int main() {
setpin(F_PINA1);
setpin(F_PINA2);
setpin(F_PINB2);
setpin(F_PINB3);
printf("%x %x\n", porta, portb);
return 0;
}

void setpin(unsigned int fpin){
int port = fpin >> 8;
int pin = 0x00ff & fpin;
switch(port) {
case 0x00:
porta |= 1 << pin;
break;
case 0x01:
portb |= 1 << pin;
break;
}
}

--
Grzegorz Niemirowski
http://www.grzegorz.net/

sword
Guest

Thu Oct 19, 2017 8:17 pm   



On 2017-10-19 21:19, Sebastian Biały wrote:
Quote:
On 10/19/2017 9:15 PM, sword wrote:
Ja mam C na sztywno w tym projekcie i nie dam rady
przeskoczyć
na C++.

Z powodu jakiego? Technicznego czy białkowego?

Jest narzucone z "góry".

--
sword

Sebastian Biały
Guest

Thu Oct 19, 2017 8:28 pm   



On 10/19/2017 10:17 PM, sword wrote:
Quote:
Z powodu jakiego? Technicznego czy białkowego?
Jest narzucone z "góry".

Czyli białkowy. Nadzieja w tym że problemy białkowe czasami rozwiązują
się szybciej niż komercyjne kompilatory dostają wsparcie C++, ale to
rodzaj czarnego humoru.

To nie pomogę bo każde rozwiązanie w C będzie gówniane.

Jakub Rakus
Guest

Thu Oct 19, 2017 8:48 pm   



W dniu 19.10.2017 o 13:01, sword pisze:

Quote:
Przy portach to jeszcze nie jest problemu ale przy flagach trzeba
ręcznie panować nad tym w której zmiennej leży jaka flaga. Już
kilka razy szukałem przez to błędów.
Problem moim zdaniem nie leży ani w wybranym w języku programowania, ani

w sposobie implementacji tylko "wyżej" - zagadnienie nazywa się semantyka.

Rozwiązanie banalne - stosuj nazwy zmiennych, funkcji, makr i definicji,
które będą JEDNOZNACZNE i SAMOKOMENTUJĄCE SIĘ. Dobrym przykładem mogą
być biblioteki dostarczane przez ST do ich procków, bo tam przyjęto
regułę, że jeśli rejestr nazywa się REG_BLA_BLA to bity w nim nazywają
się REG_BLA_BLA_ENABLE_COŚTAM, REG_BLA_BLA_DISABLE_INNE_COŚTAM itd.

--
Pozdrawiam
Jakub Rakus

J.F.
Guest

Fri Oct 20, 2017 12:04 am   



Dnia Thu, 19 Oct 2017 21:38:58 +0200, Grzegorz Niemirowski napisał(a):
Quote:
sword <nick_at_poczta.onet.pl> napisał(a):
Hmm, mogę dać inline ale wydaje mi się, że jestem w tym samym
punkcie co z makrami.
static inline void setbit (u8 port, u8 pin)
{
port |= 1<<pin;
}
No i co dalej? Chciałbym ją tak samo wywołać, np.:
setbit(F_LED)


Musisz stworzyć coś, co oprócz bitu będzie nisło też informację o porcie,
np.
[...]


A na bezczelnego ?

#define F_LED GPIO,7

.... setbit(F_LED) ...

https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html


J.

Marcin
Guest

Fri Oct 20, 2017 9:43 am   



Quote:
A na bezczelnego ?

#define F_LED GPIO,7

... setbit(F_LED) ...

https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html


Do takiego zadzialania potrzeba "podwojnego makra":

#define _test_set_bit(port,pin) do{ (port)->PDOR |=(1<<(pin)); }while(0)
#define test_set_bit(x) _test_set_bit(x)
#define LEG_G_7 GPIOB,7

i wtedy
test_set_bit(LEG_G_7);
preprocesor rozwinie poprawnie:
do{ (((GPIO_Type *)(0x400FF040u)))->PDOR |=(1<<(7)); }while(0);

Przy pojedynczym makro (jak pierwsze) arm-none-eabi-gcc zglasza blad ze makro ma miec 2 parametry a przekazany jest tylko 1.

$ arm-none-eabi-gcc -E -mcpu=cortex-m0plus makro.c -o makro2.lst
makro.c:14:23: error: macro "test_set_bit" requires 2 arguments, but only 1 given
test_set_bit(LEG_G_7);



Marcin

Janusz
Guest

Fri Oct 20, 2017 9:53 am   



W dniu 2017-10-19 o 13:01, sword pisze:
Quote:

Cześć,

Może nie do końca ta grupa ale wielu z Was pisze w C i może mi podpowie :)

Korzystam z takich makr, które pracują na bitach, np.:

Ja to robię tak wpierw definicje makr
#define SET_(p, m) (p |= (1 << (m)))
#define CLR_(p, m) (p &= ~(1 << (m)))
#define TEST_(p,m) (p & (1 << (m)))
#define TOGGLE_(p, m) (p ^= (1 << (m)))

#define SET(x) SET_(x)
#define CLR(x) CLR_(x)
#define TEST(x) TEST_(x)
#define TOGGLE(x) TOGGLE_(x)

potem właściwa konfiguracja

#define ZIELONA PORTB,1

i potem w programie

SET(ZIELONA);

--
Pozdr
Janusz

Goto page 1, 2  Next

elektroda.net NewsGroups Forum Index - Elektronika Polska - Definiowane portów/flag w C

NOWY TEMAT

RTV map News map