programovanie v c

C,C++,C#

Moderátori: psichac, Moderátori

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4415
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: programovanie v c

Príspevok od používateľa romiadam » 01 Nov 2021, 19:50

Cavte,

Ucim sa programovat v C. Citam aj knizku a zaroven aj pisem program. Teraz som narazil na nasledovny problem:

LCD kniznica je napisana na tak ze data idu po RB0 az RB3. Bity RB0 az RB3 sa vynuluju a potom sa urobi bitovy sucet registra DATA 0000 xxxx s PORTB a 4 nibles sa poslu do LCD. To mi je jasne a jednoduche.

Ale co ak ja chcem (alebo musim) pouzit rozne piny z MCU pre data? Napr RA0 RD3 RC2 RA3. Tam sa to neda urobit na ten system cez bitovy sucet registra.

Ja som rozmyslal ze by som cez if (pouzit 4x if) skontroloval kazdy bit registra DATA (spodne a horne nibbles) a podla toho prepisal jednotlive bity portu a poslal do LCD. (na styl ako v v asembleri najprv sa nastavi bit portu do 1 (bsf PORTB,0) potom otestuje ci bit0 registra DATA je 1 (btfss DATA,0) ak nie je tak by som ho vynulova 0 (bcf PORTB,0), a toto napisat 4 krat pre kazdy bit. To nie je problem, lenze ja neviem ako sa kontroluje 1 bit registera v C. A uz to hladam na nete asi 20 min. Neviem pod akym heslom to hladat. Pre vas skusenych C-karov to je asi "malina" na 5 sekund. :D

Ak mam takto deklarovany register:
uint8_t DATA
Ako sa otestuju jednotlive bity registra DATA?

Predpokldam ze neako tako:
DATAbits.x a neviem co napisat za x. Ale tiez neviem ci DATAbits. je OK.

Diki za rady.
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

Používateľov profilový obrázok
mac26
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1298
Dátum registrácie: 01 Feb 2010, 00:00
Bydlisko: Martin

Re: programovanie v c

Príspevok od používateľa mac26 » 01 Nov 2021, 20:01

RB0 = data & 0x01;
RB1 = (data >> 1) & 0x01;
RB2 = (data >> 2) & 0x01;
RB3 = (data >> 3) & 0x01;

v XC8 je RB0,.. tusim definovane ako _bit, takze by mohlo stacit aj bez posuvania:
RB0 = data & 0x01;
RB1 = data & 0x02;
RB2 = data & 0x04;
RB3 = data & 0x08;

Dalsia moznost by bola pouzit tercialny operator (v podstate nieco ako if-else):
RB0 = (data & 0x01) ? 1 : 0;
RB1 = (data & 0x02) ? 1 : 0;
RB2 = (data & 0x04) ? 1 : 0;
RB3 = (data & 0x08) ? 1 : 0;
0

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4415
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: programovanie v c

Príspevok od používateľa romiadam » 01 Nov 2021, 20:19

Diki mac26,

sice nedostal som odpoved ci existuje nieco taketo: DATAbits.x

ale toto je presne to co mi vyhovuje.

Nakolko ja by som mal "rozsypane" portove bity tak by som to spravil takto:

uint8_t data //deklarovany register ako data

RA0 = data & 0x01;
RD3 = (data >> 1) & 0x01;
RC2 = (data >> 2) & 0x01;
RA3 = (data >> 3) & 0x01;

:thumbup:

A existuje prikaz na otestovanie jedneho bitu nejakeho registra napr. toho deklarovaneho data?
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 982
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: programovanie v c

Príspevok od používateľa budvar10 » 02 Nov 2021, 12:36

Existuje bitove pole (bit field), napr.:

union _bit_field_reg {
struct { // po bitoch
bit_0 : 1;
bit_1 : 1;
bit_2 : 1;
bit_3 : 1;
bit_4 : 1;
bit_5 : 1;
bit_6 : 1;
bit_7 : 1;
};
uint8_t value; // cely byte
};

union _bit_field_reg data;

data.value = 0x66;

if(data.bit_0) {
}

Prekladac by to mal elegantne prelozit vzdy s min. instrukciami. Ja PIC neovladam, ale pre AVR to funguje skvelo.
Este je tam pouzity union - jednoducho je to rozny datovy typ na tom istom pamatovom mieste.
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Re: programovanie v c

Príspevok od používateľa Radus » 02 Nov 2021, 12:42

https://svetelektro.com/clanky/programu ... -cast-446/
...všetko je to tu a pekne popísané...
Maskovanie využívame aj pri čítaní:
Máme napr. podmienku v ktorej nás zaujíma či daný pin portu je zvonka nastavený na log. 1.
Pre názornosť si zvoľme tento pin napr. PD4

if (PIND & (1 << PD4) ){
/*… príkazy po splnení podmienky…*/
}
..ja osobne pri maskovaní nepoužívam rotáciu, maskujem napríklad:
If(Port_x & 0b00001000)...
0

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 982
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: programovanie v c

Príspevok od používateľa budvar10 » 02 Nov 2021, 12:59

Pri teste na 0 je rotacia zbytocna operacia, ale optimizer si s tym aj tak poradi.
Tu ale v priklade, co si poslal PIND & (1 << PD4) nejde o rotaciu doslova, je to konstanta a osobne mi pride prehladnejsie ako 0b00001000, tu skor urobis chybu. BTW: Konkretne PD4 by malo byt 0b00010000.
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Re: programovanie v c

Príspevok od používateľa Radus » 02 Nov 2021, 13:07

...ale to bola rotácia portu x nie D :biggrin:
0

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 982
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: programovanie v c

Príspevok od používateľa budvar10 » 02 Nov 2021, 14:18

Jasne, OK. :ignore:
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Re: programovanie v c

Príspevok od používateľa Radus » 02 Nov 2021, 17:19

Inak, použitie definovanej veľkosti v štruktúrach prináša pri preklade problémy, ja som od toho upustil...
https://atadiat.com/en/e-embedded-c-str ... on-part-2/
0

slonik
Okoloidúci
Okoloidúci
Príspevky: 39
Dátum registrácie: 19 Dec 2019, 22:01
Bydlisko: Žilina

Re: programovanie v c

Príspevok od používateľa slonik » 03 Nov 2021, 09:32

Snažím sa rozbehať komunikáciu SPI na procesore PIC16F1705. Do teraz som používal starší procesor PIC16F887 a na ňom mi komunikácia bežala bez problémov. Na tom novom procesore sa snažím rozbehať cez SPI displej 5110. Stále mi však SPI nefunguje a neviem prísť na to kde robím chybu.

môj kód: mplab x ide ... xc8

Kód: Vybrať všetko

void SPI_inic_master()
{
    ADCON0=0;
    ADCON1=0;
    ADCON2=0;
    ANSELC=0;
    ANSELA=0;//analogove vstupy vyp.
    
    //vypnutie uzamknutia  PPS ... DS str.138
    PPSLOCK=0x55;
    PPSLOCK=0XAA;
    PPSLOCK.bitsPPSLOCKED=0;
    
    //nastavenie pinov periférie ....DS str.139-141
    SSPDATPPS=0b000010001;// SDI na RC1 vstup........str.139 register 12-1: xxxPPS
    RC0PPS=0b00010000;//SCK na RC0 vystup...............str. 141 register 12-3: RxyPPS
    RC2PPS=0b00010010;//SD0 na RC2 vystup...............str. 141 register 12-3: RxyPPS
    
    //nastavenie vstupov a vystupov TRIS
    TRISCbits.TRISC1=1;//RC1 je vstup SDI
    TRISCbits.TRISC0=0;//RC0 je vystup SCK
    TRISCbits.TRISC2=0;//RC2 je vystup SD0
    
    //nastavenie registrov SPI
    SSP1STAT=0b01000000;// register SSP1STAT .... str. 318
    SSP1CON1=0b00100000;//register SSP1CON1 .... str. 318
    PIR1bits.SSP1IF=0;//register PRI1 ...........................str. 88
}

Kód: Vybrať všetko

void SPI_zapis(unsigned char x)
{
    unsigned char data_flush;
    SSP1BUF=x;
    while(!PIR1bits.SSP1IF);
    PIR1bits.SSP1IF=0;
    data_flush=SSP1BUF;
}
Prešiel som celý datasheet a snažil som sa všetky registre nastaviť správne. Stále mi ale čosi uniká a neviem prísť na problém. Ak sa stým niekto stretol budem mu vďačný za každú radu.
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: programovanie v c

Príspevok od používateľa jirka.jirka. » 03 Nov 2021, 09:34

Logičťákem (nebo osciloskopem) ses koukal? Je opravdu SPI mrtvá? Třeba jenom blbě inicializuješ display. Chtělo by to schema, mrknout logičťákem jestli něco chodí a pak dělat závěry.
0

slonik
Okoloidúci
Okoloidúci
Príspevky: 39
Dátum registrácie: 19 Dec 2019, 22:01
Bydlisko: Žilina

Re: programovanie v c

Príspevok od používateľa slonik » 03 Nov 2021, 09:45

osciloskop nemám.
Displej inicializujem správne pretože pod tým starým procesorom mi beží bez problémov. Rovnaké rutiny kódu, funkcie, povolenie príkaz/dáta, všetko mám tak isto nastavené. Jedine čo som spravil je že som vymenil mcu a nastavenie SPI. Dokonca som skúšal zapojiť rôzne zariadenia ktoré komunikujú cez SPI a ktoré mi bez problémov bežali na starom mcu. A stále nič.
0

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4415
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: programovanie v c

Príspevok od používateľa romiadam » 04 Nov 2021, 03:45

Zdravim opat,

Ma niekto skusenosti s MPLAB Code Configuratorom ?

Ja som v tomto novacik. Mam problemy s kompilovanim projektu, lebo funkcia tmr1.h nepozna premenne.
V preruseni potrebujem inkrementovat dva registre TL_1cnt a LEDcnt, ktore sa dalej budu spracovavat v main.c
image.png
Ak funkciu prerusenia napisem do suboru main.c tak nie je ziaden problem, aj to funguje, nakolko hore v main.c su tie dva registre TL_1cnt a LEDcnt deklarovane ako globalne premenne.
Potom som vsak MCU nakonfiguroval cez MCC, cim sa vytvorili rozne subory*.h a *.c v projekte.
Uspesne som nastavil cez MCC TMR1 aj s aktivovanym prerusenim, TMR1 ma hodnotu 1ms.
Problem, vsak mam s Build Project, lebo subor tmr1.c nepozna TL_1cnt a LEDcnt.
Ako sa to deklaruje?
Pokusne (ze co to spravi) som tieto dva registre deklaroval presne tak ako v main.c aj v tmr1.c. Vtedy sa projekt zkompiloval. Aj som to simuloval a tie dva registre sa inkriminovali v preruseni. Lenze ak sa prerusenie opustilo tie dva registre zrazu mali hodnotu 0. Cize to co som spravil nebolo spravne.

Ako sa deklaruje register aby bol vsade "poznany", aj v tmr1.h a potom aby tie dva registre po inkrementacii v preruseni mali tu novu hodnotu v main.c?

Diki.
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

Používateľov profilový obrázok
mac26
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1298
Dátum registrácie: 01 Feb 2010, 00:00
Bydlisko: Martin

Re: programovanie v c

Príspevok od používateľa mac26 » 04 Nov 2021, 06:25

V dalsi suboroch ich deklarujes ako extern:
extern uint8_t TL1_cnt;
...
0

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4415
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: programovanie v c

Príspevok od používateľa romiadam » 04 Nov 2021, 08:13

Aha, ja som to deklaroval bez toho extern. Vecr ked pridem z roboty vyskusam.
Prerusenie sa zacina v interrupt,_manager.c a odtial sa vola funkcia tmr1.c. Mam to teda deklarovat v oboch ? Alebo len v tmr1.c?
0
Naposledy upravil/-a romiadam v 04 Nov 2021, 10:45, upravené celkom 1 krát.
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2561
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: programovanie v c

Príspevok od používateľa maskrtnik01 » 04 Nov 2021, 09:12

Ja keď som robil na STM32, som skôr odporcom tých peripheral driverov, alebo ako to volá Microchip. Išiel som 100% vlastným kódom priamo na registre. Pekne ako sa to robí aj v assembleri.

Treba dať #include na .h súbor kde sú definované registre MCU, a potom jednoducho register_name = register_value;
0

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 982
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: programovanie v c

Príspevok od používateľa budvar10 » 04 Nov 2021, 13:34

romiadam napísal:
04 Nov 2021, 08:13
Mam to teda deklarovat v oboch ? Alebo len v tmr1.c?
Musí byť v každom, v ktorom sa použije. Dá sa to dať samozreme aj do headera a potom #include "nejaky.h".
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: programovanie v c

Príspevok od používateľa jirka.jirka. » 04 Nov 2021, 13:40

Přes ten #include "nejaky.h" se mi to zdá lepší, než do každého souboru. Pak se proměnná odstraní a je to prolezené, že to je na půl dne, než to člověk odstraní.

Jinak někdy ani není nutná extern, stačí ji zabalit do funkce a vrátit. Ale to je na každém, jak to udělá. Řešení je mraky. :thumbup:
0

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4415
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: programovanie v c

Príspevok od používateľa romiadam » 04 Nov 2021, 14:45

Toto je prerusenie ktore nie je v main.c (vektor prerusenia nie je v main.c, tak to generuje MCC). Neviem ako by sa do dalo zabalit do funkcie v main.c bez piuzitia extern. (Len zacinam s C)

Mam dve moznosti:
1. Bud prerusenie napisem manualne v main.c a problem sa vyriesi. Manualne nastavit periferiu a jeho orerusenie mi trva 10-20 minut a mozem na niktory z registrov zabudnut nastavit a potom hladat chybu preco periferia neide
2. Pouzivat MCC kde v grafickom rozhrani sa nezabudne na nic, a ak viem co znamenaju tie nastavovacie bity (netreba studovat datasheet), tak cele nastavenie periferie trva cca 20 sekund.

Preferujem cez to MCC, len musim vyriesit ten hore spominany problem. Vecer to doma vyskusam a dam vam vediet. Dakujem za informacie.
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: programovanie v c

Príspevok od používateľa peterple » 04 Nov 2021, 20:27

Ešte taká malá ale podstatná drobnosť. Premenné ktoré chceš používať v prerušení a aj v hlavnom programe musia v defíniciach (asi aj deklaráciách) obsahovať slovíčko volatile. Bez toho sa budeš hodne čudovať prečo ti to nechodí. V princípe ide o to že kompilátor musí zabezpečiť správne načítavanie premennej z pamäte do pracovných registrov.

No a potom je tu ešte problém s atomickosťou ak to je 8 bitový CPU. Tak tú si musíš pri premenných dlhších ako 1 byte riešiť sám.

Vieš ako spieva Richad Muller - Nebude to také ľahké drahá ...

Edit: pozerám že zatiaľ tam máš iba 1 bytové premenné. Tak atomickosť riešiť nemusíš. Ale bacha ako náhle by si chcel používať dlhšie tak už to riešiť musíš. Inak sa tam budú objavovať záhadné náhodilé zblbnutia.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok