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 » 04 Nov 2021, 22:59

Cavte. Pokrocil som.
Toto vsetko (zvyraznene) mi vygeneruje MCC:
image.png
Tak som vytvoril v projekte v hlavnom adresari projektu Blink_LED.X subor globalvar.h kde som len dopisal/prepisal zvyraznene riadky (zbytok MPLAB vygeneroval sam)
image.png
A potom som do tmr1.c musel pridat
#include "C:\Users\Adam\MPLABXProjects\Blink_LED.X\globalvar.h"
a do handlera toto
image.png
a uz to chodi. :applause:

Mam este otazku: Neda sa ta absolutna cesta C:\Users\Adam\MPLABXProjects\Blink_LED.X\ zapisat nejako inak (relativne) aby som pri presune projektu do ineho PC nemusel projekt ukladat do presne stanoveneho adresara popr. prepisovat cestu vo vsetkych *.h suboroch kde sa pouzivaju globalne premenne?
Problem je ze globalvar.h je v nad adresari subora tmr1.c (vid obrazok) a nie v tom istom adresari popr v dalsom podadresari.

peterple, nestras ma s tou atomiskostou.... ( :) )

Ja som zatial nepouzil volatile a blikac mi ide aj bes toho volatile. Mam aj napriek tomu ze to ide, pouzit volatile?
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, 23:10

relativne sa cesta zapisovať dá. Nesmieš začínať menom disku a opačným lomítkom. Ak chceš ísť o poschodie nahor tak to je dve bodky za sebou. napr

Kód: Vybrať všetko

..\..\headerFiles\atd
Vidím že varovanie neberieš vážne. volatile si si tam nepridal. Ide to znamená že sa ti to podarilo skompilovať? Alebo už máš odskúšané že v hlavnom programe 100% pracuješ s datami ktoré pred chvíľlou prerušenie zmenilo?
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

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, 23:16

Ako chceš. nepouži, ale buď pripravený na problém s aktuálnosťou dát z prerušenia v hlavnom programe. Ak kompilátor si bude myslieť že premenná sa nezmenila nemusí ju za určitých okolností načítavať opäť z pamäte, ale ju zachová v registroch. A môže sa to stať až neskôr. Teraz tie premenné môže trvale držať v registroch (tzv automatické) a v takom prípade sa problém neukáže.
Atomickosť je potvora. Ak ju vieš riešiť v asm, tak ju rovnako treba riešiť v C. Inak sa môžeš tešiť napr .na generálsky efekt. Písať kód s prerušeniami, nie je sranda.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

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 » 05 Nov 2021, 00:15

relativne sa cesta zapisovať dá. Nesmieš začínať menom disku a opačným lomítkom. Ak chceš ísť o poschodie nahor tak to je dve bodky za sebou. napr

Kód: Vybrať všetko

..\..\headerFiles\atd
vedel som ze nieco take existuje... diki super. (zapisujem si toto)
image.png
image.png (6.26 KiB) 4036 zobrazení
Funguje to. :applause:
Vidím že varovanie neberieš vážne. volatile si si tam nepridal. Ide to znamená že sa ti to podarilo skompilovať? Alebo už máš odskúšané že v hlavnom programe 100% pracuješ s datami ktoré pred chvíľlou prerušenie zmenilo?
Ale beriem ta vazne. Len som to skusal ci to pojde aj bez toho volatile. Bol som zvedavy. Uz to tam je a ide to aj s tym.
image.png
Tiez si toto zapisujem. :thumbup:
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.
Co tymto myslis? Co je atomickost pri 16bitovych cislach?
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 » 05 Nov 2021, 18:28

Dajme tomu že máš počítadlo v prerušení čo počíta od 0 - 300 (0x012C) v nejakej 16 bitovej premennej. Hlavný program to číslo napr vypisuje na displej. Otázka je môže vypísať číslo väčšie ako 300? Odpoveď - Áno ak tú hodnotu nečíta atomicky - teda ako keby jedinou inštrukciou. Vezmime si takýto scenár
  1. je tam hodnota 255 (0x00FF)
  2. hlavný program si prečíta dolný byte - teda 0xFF
  3. v tomto momente nastane prerušenie a teda hodnota sa zmení na 256 (0x0100) a vraciame sa späť do hlavného programu
  4. hlavný program prečíta horný byte - teda 0x01
  5. hlavný program si myslí že hodnota je 0x01FF teda 511.
  6. čo urobí ďalej je vo hviezdach. Záleží na tom ako robustne to programátor napísal lebo hodnota je zjavne mimo max hranicu (robustnosť = schopnosť programu správne pracovať aj pri nesprávnych vstupoch)
Pozor niekedy môže tento scenár nastať aj pri 1bytových premenných. To vtedy ak sa robí postup R-M-W
teda Read - Modify - Write
Príkladom je napr premenná flags, v ktorej je viacej príznakov. Tam bez atomickej operácie R-M-W môžeš napr vymazať príznak ktorý si nechcel vymazať, ak ťa to preruší za inštrukciou Read, alebo Modify. Zase zvyčajne prúser ako mraky z pohľadu algoritmu.
Obe veci dávajú väčší alebo menší nábeh na vytvorenie generálskeho efektu. Veľa krát som ja už počul:
Ale doma mi to 100% fungovalo.
No a na záver ďalšie varovanie. To že označíš v C premennú ako volatile nerieši atomický prístup. Ten sa robí ako procesor vie. Najčastejšie u jednoduchých chrobákoch, zakázaním prerušenia na dobu čítania premennej. Nie som PICak takže na ukážku ako sa číta long int na arduine
https://github.com/zkemble/millis/blob/ ... millis.cpp

Kód: Vybrať všetko

// Get current milliseconds
millis_t millis_get()
{
	millis_t ms;
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
		ms = milliseconds;
	}
	return ms;
}
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Dumitru
Stály člen
Stály člen
Príspevky: 370
Dátum registrácie: 06 Nov 2011, 22:19
Vek: 32

Re: programovanie v c

Príspevok od používateľa Dumitru » 07 Nov 2021, 11:38

Ahoj ďakujem za vysvetlenie a týka sa to len premenných ktorých hodnotu meníme v prerušeniach ? alebo to platí globálne pre všetky premenne ktoré sú viac ako 8bit , pre 8 bitový procesor.
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 » 07 Nov 2021, 16:03

Netýka sa to všetkých premenných. Len ak je to potrebné. Atomic blok je nato, aby akákoľvek časť programu, ktorá nie je vykonateľná v jedinej inštrukcii a mohla by byť ovplyvnená prerušením, sa vykonala bez prerušenia a tak bola zabezpečená korektnosť dát a procesu. @peterple to celkom pekne vysvetlil.
Vpodstate ide o zákaz prerušenia v danej časti programu.

Volatile slúži na to, aby kompilátor nemohol optimalizovať premennú. Premenná je tak vždy pred operáciou čítaná z RAM a v prípade zmeny, je po operácii uložená do RAM. Nedôjde tak k tomu, že by bola držaná len výhradne v registroch. Toto je potrebné pre premenné, s ktorými sa narába v prerušeniach.
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 » 07 Nov 2021, 16:28

Ja som to riesil v ASM tak, ze som na tu chvilocku kde to bolo rizikove, zakazal prerusenie.
Cize som vlastne riesil atomickost, len som o tom nevedel. :)

Takze strucne povedane, ak nieco robime v hlavnom programe, co sa neda vykonat jednou instrukciou, a moze to byt ovplyvnene hocikedy v preruseni a nemame na tym kontrolu, tak to treba riesit v atomickom bloku? Chapem spravne?
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 » 07 Nov 2021, 17:39

Áno. Ako som písal, nepoznám PIC ale pravdepodobne to bude veľmi podobné. ATOMIC_BLOCK je makro so zakázaním prerušení na začiatku a povolením prerušení na konci. Tak to je v avr gcc.
Mimochodom, skús pozrieť v tom IDE, či tam máš po kompilácii ASM prepis alebo debug. Predpokladám, že to MPLAB bude mať. Ak poznáš ASM môže to byť pre teba celkom zaujímavé porovnať kód v C++ vs. ASM.
0

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 » 07 Nov 2021, 18:14

Len pre úplnosť dodám, že volatile a atomickosť, treba riešiť aj pre viacjadrové mašiny, a pre realtime OS kde môže bežať viacero vlákien. Ale to sme asi mimo 8 bit architektúry PIC a AVR.

Ešte jedno strelenie do nohy môže byť použitie nereentrantnej funkcie v prerušení. Niektoré C funkcie také sú. Ale dúfam že také strašnosti v prerušení nikoho normálneho nenapadne používať.
Reentrantná funkcia je taká ktorú možno prerušiť a znova ju zavolať a aj prvé aj druhé volanie zbehne OK. Prípadne funkcia môže zavolať sama seba.

Fajn že v asm si to používal. Takže budeš vedieť nájsť miesta kde je to potrebné robiť aj v C.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

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 » 08 Nov 2021, 22:35

dobrý večer prajem.
Snažím sa rozbehať komunikáciu SPI na procesore PIC16F1705
Stále nemôžem prísť na chybu. Pokúšal som sa pomocou generátora mcc nastaviť SPI s nádejou
že pochopím nastavenie tohoto mcu.
Nerozumiem ale tejto funkcii ktorú mi generátor zostavil.
Nie som zas až tak zdatný programátor. Budem veľmi vďačný ak mi niekto vysvetlí daný zápis z generátora.

Kód: Vybrať všetko

typedef struct { 
    uint8_t con1; 
    uint8_t stat;
    uint8_t add;
    uint8_t operation;
} spi_configuration_t;

//con1 == SSPxCON1, stat == SSPxSTAT, add == SSPxADD, operation == Master/Slave
static const spi_configuration_t spi_configuration[] = {   
    { 0x0, 0x0, 0x1, 0 }
};

void SPI_Initialize(void)
{
    //Setup PPS Pins
    SSPCLKPPS = 16;
    SSPDATPPS = 17;
    RC0PPS    = 16;
    RC3PPS    = 18;
    //SPI setup
    SSP1STAT = 0x00;
    SSP1CON1 = 0x00;
    SSP1ADD = 0x01;
    TRISCbits.TRISC0 = 0;
    SSP1CON1bits.SSPEN = 0;
}

bool SPI_Open(spi_modes_t spiUniqueConfiguration)
{
    if(!SSP1CON1bits.SSPEN)
    {
        SSP1STAT = spi_configuration[spiUniqueConfiguration].stat;
        SSP1CON1 = spi_configuration[spiUniqueConfiguration].con1;
        SSP1CON2 = 0x00;
        SSP1ADD  = spi_configuration[spiUniqueConfiguration].add;
        TRISCbits.TRISC0 = spi_configuration[spiUniqueConfiguration].operation;
        SSP1CON1bits.SSPEN = 1;
        return true;
    }
    return false;
}
rozumiem že mám vyvolať funkciu SPI_initialize(); ale neviem ako mám použiť SPI_Open.
Veľmi pekne ďakujem za radu.
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 » 09 Nov 2021, 06:27

To je hrozný paškvíl, musel som si to dať do kompilátoru či to normálne prejde...
typedef struct {
uint8_t con1;
uint8_t stat;
uint8_t add;
uint8_t operation;
} spi_configuration_t;
...vytvorý definíciu typu štruktúry spi_configuration_t.
//con1 == SSPxCON1, stat == SSPxSTAT, add == SSPxADD, operation == Master/Slave
static const spi_configuration_t spi_configuration[] = {
{ 0x0, 0x0, 0x1, 0 }
};
vytvorí jednoprvkové pole štruktúr spi_configuration_t a inizializuje prvý prvok s hodnotami 0,0,1,0.
t.j. [0].con1 = 0, [0].stat=0...atď
bool SPI_Open(spi_modes_t spiUniqueConfiguration)
{
if(!SSP1CON1bits.SSPEN)
{
SSP1STAT = spi_configuration[spiUniqueConfiguration].stat;
SSP1CON1 = spi_configuration[spiUniqueConfiguration].con1;
SSP1CON2 = 0x00;
SSP1ADD = spi_configuration[spiUniqueConfiguration].add;
TRISCbits.TRISC0 = spi_configuration[spiUniqueConfiguration].operation;
SSP1CON1bits.SSPEN = 1;
return true;
}
return false;
}
táto funkcia potrebuje vstupný parameter spi_modes_t, predpokladám že to bude enumerácia. Kedže potom vyvoláva z poľa štruktúr spi_configuration_t potrebný prvok a to poľe je len jednozmerné, do úvahy pripadá len 0-tá enumerácia, nech je to čokľvek....

V podstate by si to mohol zmeniť na (ak teda niečo iné niekde nemení ešte štruktúru spi_configuration_t, ale kedže je označená ako const...):

Kód: Vybrať všetko

bool SPI_Open()
{
    if(!SSP1CON1bits.SSPEN)
    {
        SSP1STAT = 0;
        SSP1CON1 = 0;
        SSP1CON2 = 0x00;
        SSP1ADD  = 1;
        TRISCbits.TRISC0 = 0;
        SSP1CON1bits.SSPEN = 1;
        return true;
    }
    return false;
}
..husté to je :biggrin:
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 » 09 Nov 2021, 09:53

no ešte som našiel v spi.h toto

Kód: Vybrať všetko

/* SPI interfaces */
typedef enum { 
    SPI_DEFAULT
} spi_modes_t;
vidím že nie som sám čo si išiel na tom oči vyočiť ... ale veľmi pekne ďakujem za ochotu sa tým prelúskať aj za vysvetlenie.
Nerád používam ten generátor. Radšej si vždy prejdem datasheet aby som mal svoj kód pod kontrolou. Toto bol už zúfalý krok, pretože sa trápim s tou komunikáciou snáď už dva týždne a nie to rozbehať. Pri iných mcu mi to beží bez problémov.
Vo svojom nastavení podľa datasheetu som skúšal cez debuger pozrieť SSP1BUF a do neho mi SPI vkladá dáta. Ale problém je ako keby nechceli vyliezť z výstupu SDO.
Skúšal som na pin SDO pripojiť led ktorá bliká pri prenose dát. Ináč som to otestovať nevedel. Je ešte nejaký chronologický spôsob ako postupne hľadať príčinu? osciloskop nemám :-(
Po nete na rôznych fórach tiež mali problémy to rozbehať ale nikde som nenašiel či sa im to nakoniec aj podarilo.
V každom prípade skúsim ešte na tvrdo prepísať funkciu SPI_Open tak ako si mi napísal.
Ešte raz ďakujem
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 » 09 Nov 2021, 10:17

Bolo to tu asi aj spomenuté, skúsil by som Proteus, tam odsimulovať MCU, vieš si tam potom vyčítať ako bola SPI jednotka inicializovaná, čo sa s ňou deje a dopátrať sa k problému...
Teraz niesom doma, ak mi večer pošleš HEX, tak sa ti nato pozriem...
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 » 09 Nov 2021, 10:42

Som tiež v práci. Môžem ti večer poslať hex. Ale nechcem ťa tiež otravovať aby si celý večer strávil nad mojím problémom. Isto vieš stráviť večer príjemnejšie :-)
Zrejme nastavím mód sebauspokojenia, vezmem kladivo z mcu spravím rešeto
a siahnem po nejakom menej tvrdohlavom procesore :-)
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 » 09 Nov 2021, 10:51

Rozbiehal som SPI na STM a Atmel a nikdy som nemal extra problémy.
Teda raz, keď som v nejakých revíziach k jednému MCU nevšimol že pri istej kombinácii premapovaných vstupov sa nemohol daný vstup použiť pre SPI, ktorý som mal presne tak nastavený... tiež som to šiel vtedy rozkusať...
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 » 09 Nov 2021, 11:33

možno je aj problém v nastavení vstupov a výstupov SPI. Zatiaľ som mal vždy mcu kde SDI, SD0, SCK boli na konkrétnych pinoch mcu.V tomto procesore sú ale voliteľné. No skúšal som ich nastaviť na rôzne piny ale nepomohlo. Led mi vždy reagovala keď som skúšal vypínať alebo zapínať výstup SDO na rôznych pinoch.
toto je z datasheetu umiestnenie pinov
Obrázok
tie by som mal nasataviť v registri pre vstup REGISTER 12-1: xxxPPS
Obrázok
a pre výstup REGISTER 12-3: RxyPPS
Obrázok
čiže ich mám nastavené na

Kód: Vybrať všetko

    SSPDATPPS=0b000010001;// SDI na RC1 vstup register 12-1: xxxPPS
    RC0PPS=0b00010000;//SCK na RC0 vystup register 12-3: RxyPPS
    RC2PPS=0b00010010;//SD0 na RC2 vystup register 12-3: RxyPPS
skúsim ešte ako si písal, zmeniť piny na ktorých bude nastavená periféria SPI. Možno že to pomôže
Prílohy
mapa.JPG
12-1.JPG
12-3.JPG
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 » 09 Nov 2021, 20:43

Už mi to funguje.
Mal som zle nastavené konfiguračné bity procesora. Normálne som na seba naštvaný za tak premárnený čas. :(
Ďakujem ešte raz všetkým
0

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