WCH32v003 RISC-V MCU

Všetko čo sa týka mikropočítačov + Sekcia Arduino

Moderátori: psichac, Moderátori

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa budvar10 » 03 Apr 2024, 08:22

Tou definiciou funkcie vo funkcii myslis to , ze rutiny Print_On_Lcd volam LCD_PrintXY?
To by sa nemalo?
To čo si opravil. Mal si definiciu funkcie vo vnútri main. Volanie je samozrejme OK.
Aspoň že si tam dal komentár. Inak to nie je to celkom jasné. Podľa mňa je lepšie, ak urobíš opravu do ďalšieho príspevku.
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 03 Apr 2024, 10:27

Len tak pre zaujmavosť som sa raz stretol v knižnice od Wiznetu

kde namiesto

Kód: Vybrať všetko


uint8_t val1[4];
uint32_t val2;

val1[0] = (uint8_t) val2 >> 24;
val1[1] = (uint8_t) val2 >> 16;
val1[2] = (uint8_t) val2 >> 8;
val1[3] = (uint8_t) val2 >> 0;

to robili pomocou pointrov takto :

Kód: Vybrať všetko



uint8_t val1[4];
uint32_t val2;

val1[0] = (uint8_t)(*((uint8_t *)(&val2) + 3));
val1[1] = (uint8_t)(*((uint8_t *)(&val2) + 2));
val1[2] = (uint8_t)(*((uint8_t *)(&val2) + 1));
val1[3] = (uint8_t)(*((uint8_t *)(&val2) + 0));

to by ma nikdy v živote nenapadlo :D ale možno to je bežne len ja som to videl prvý krát a tak isto vykonávali aj zápis do premennej :D
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 03 Apr 2024, 14:41

Nuž a tu by som potreboval nejak ozrejmiť akú výhodu má v tom mojom skúšobnom kóde používať pointre, keď ten kód funguje identicky aj v prípade, že pointre vynechám viď:

Kód: Vybrať všetko

#include "debug.h"
#include "i2c_LCD.h"

u_char str_val[16];

   // rutina na vypis na LCD
    void Print_On_Lcd (int ptr){
    sprintf(str_val,"VAR=%3d",ptr);
    LCD_PrintXY(0, 0,str_val);
    }

int main(void){
    SystemCoreClockUpdate();
    Delay_Init();
    LCD_Config();

    int x = 800; // zapis do premennej x hodnotu 800 dec
    int y = 13;  // zapis do premennej y hodnotu  13 dec

    while(1){
    Print_On_Lcd(x); // vypis na LCD hodnotu premennej x
    Delay_Ms(2000);
    Print_On_Lcd(y); // vypis na LCD hodnotu premennej y
    Delay_Ms(2000);
   }
}
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 03 Apr 2024, 14:54

Lennox napísal:
03 Apr 2024, 14:41
Nuž a tu by som potreboval nejak ozrejmiť akú výhodu má v tom mojom skúšobnom kóde používať pointre, keď ten kód funguje identicky aj v prípade, že pointre vynechám viď:

Kód: Vybrať všetko

#include "debug.h"
#include "i2c_LCD.h"

u_char str_val[16];

   // rutina na vypis na LCD
    void Print_On_Lcd (int ptr){
    sprintf(str_val,"VAR=%3d",ptr);
    LCD_PrintXY(0, 0,str_val);
    }

int main(void){
    SystemCoreClockUpdate();
    Delay_Init();
    LCD_Config();

    int x = 800; // zapis do premennej x hodnotu 800 dec
    int y = 13;  // zapis do premennej y hodnotu  13 dec

    while(1){
    Print_On_Lcd(x); // vypis na LCD hodnotu premennej x
    Delay_Ms(2000);
    Print_On_Lcd(y); // vypis na LCD hodnotu premennej y
    Delay_Ms(2000);
   }
}



V tvojom kóde v podstate žiadnu výhodu ale ak by si mal pole napríklad 1kb tak bez pointrov by si musel ho cele poslať do funkcie teda alokovať dalši 1kb a takto pošleš len jeden uint32 s adresou a ďalej už len ju inkrementuješ napríklad a čítaš hodnoty ktoré potrebuješ . Menej náročne na pamäť a rýchlejšie


Edit:
Tak tiež môžeš pozívať pointre na funkcie, a napríklad napísať nejaký univerzálny C kod pre spracovanie dat z periferie (templomer/vlhkomer/tlakomer....) , a funkcie pre hardverovu komunikáciu cez spi/i2C/uart ukázať cez pointer ďalej ak použiješ iný chip stačí len napísať hardvérové funkcie.


tu je príklad z mojej knižnice kde som si takto SPI komunikáciu spravil cez pointre teraz mi stačí napísať na ktoromkolvek mcu týchto 6 funkcii v inite ukázať ich adresu a bude to pracovať bez toho aby som knižnicu nejako upravoval.

Kód: Vybrať všetko

.h subor
extern void (*w5500_CS_SET)(void);   // toggle down pin SCSn , Chip Select for SPI bus , Low: selected
extern void (*w5500_CS_RESET)(void); // switched up pin SCSn , Chip Select for SPI bus , High: deselected

extern void (*w5500_RST_SET)(void);   // toggle down pin RSTn , Reset Chip, Low: selected
//Active low RESET should be held low at least 500 us for W5500 reset
extern void (*w5500_RST_RESET)(void); // switched up pin RSTn , Reset Chip, High: deselected

extern void (*w5500_delay_ms)(uint32_t); // delay function

extern void (*w5500_SPI_Transmit_Receive) (uint16_t*, uint16_t*,const uint16_t);

Kód: Vybrať všetko


void w5500_func_init (void)
{
    //pointer  to spi HW function
    w5500_delay_ms = delay_ms;
    w5500_RST_SET = w5500_rst_set;
    w5500_RST_RESET = w5500_rst_reset;
    w5500_SPI_Transmit_Receive = w5500_spi_transmit_receive;

    w5500_hardware_reset(); // hw reset w5500 chip
    w5500_delay_ms(5000);
    w5500_sw_reset();      // sw reset w5500 chip
    w5500_delay_ms(100);
}

0
Naposledy upravil/-a Dumitru v 03 Apr 2024, 15:13, upravené celkom 4 krát.

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 03 Apr 2024, 15:01

Aha, jasne takto to už dáva zmysel. Idem vymyslieť nejaký príklad kde zadefinujem jednorozmerné pole a skúsim hodnoty z neho čítať pomocou pointra. Ď.

Tak takto nejako som to. Pomocou pointra ukazujem na dáta z pola ktoré rutinou LCD_CGRAM_Write zapisujem do CGRAM LCD.

Kód: Vybrať všetko

#include "debug.h"
#include "clcdi2c.h"

u_char str_val[16];

// Pole custom znak pre LCD na poziciu v CGRAM
u_char patern1 [8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04,0x00}; //zvoncek
//.patern2
//........
//.patern6
u_char patern7 [8] = {0x11,0x1B,0x1B,0x04,0x04,0x11,0x0E,0x04}; //cert

// rutina zapisu do CGRAM LCD
void LCD_CGRAM_Write(u_char location, u_char *ptr){
    u_char i;
    if (location < 8) {
    LCD_WriteCommand(0x40 + (location*8));
    for (i = 0; i < 8; i++)
    LCD_WriteData(ptr[i]);
  }
}

// rutina na vypis na LCD
   void Print_On_Lcd (int *ptr){
   sprintf(str_val,"VAR=%3d",*ptr);
   LCD_PrintXY(0, 0,str_val);
   }

int main(void){
    SystemCoreClockUpdate();
    Delay_Init();
    LCD_Config();

    LCD_CGRAM_Write(1,patern1); // custom znak zvoncek, nahranie do CGRAM
    LCD_CGRAM_Write(7,patern7); // custom znak cert,    nahranie do CGRAM

    while(1){
    int x = 800; // zapis do premennej x hodnotu 800 dec
    int y = 13;  // zapis do premennej y hodnotu  13 dec

    LCD_SetCursor(0,1); LCD_WriteData(1); // vypis custom znak zvoncek na LCD
    LCD_SetCursor(2,1); LCD_WriteData(7); // vypis custom znak cert na LCD

    Print_On_Lcd(&x); // vypis na LCD hodnotu premennej x (referencia na x)
    Delay_Ms(2000);
    Print_On_Lcd(&y); // vypis na LCD hodnotu premennej y (referencia na y)
    Delay_Ms(2000);
   }
}
Budem rád keď kuknete na kód a skorigovali ak by sa dalo ináč lepšie.
0
Naposledy upravil/-a Lennox v 03 Apr 2024, 15:44, upravené celkom 1 krát.

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa budvar10 » 03 Apr 2024, 15:36

Pointer môže byť kontraproduktívny, keďže potrebuje zvyčajne vykonať viac operácii ako odovzdanie premennej, čo ide cez stack. Ak je to jednoduchá dátova premenná char, int, atď. Ale ako píše Dumitru, výhoda je napr. pri poliach, znakových reťazcoch a pod.
Tam máš funkciu sprintf a všetky jej podobné pracujú s pointrami. Dáš jej adresu (pointer) znakového reťazca, povedzme 4B (32-bit) a reťazec môže mať hocikoľko, napr. 300B, Funkcia pôjde znak po znaku, kým znak nebude 0.
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 03 Apr 2024, 21:26

Ešte na jednu vec som si zvykol v Basicu a to používať každy bit z 8.bitovej premennej ako rôzne indikátory (flagy). Tak som skúsil niečo podobné aj v C v rámci cvičenia s pointremi.
Teraz sa už asi ostrielaní harcovníci rehocú ale pre mňa je to nové. A možno to niekomu aj pomôže :mrgreen:

Kód: Vybrať všetko

#include "debug.h"
#include "clcdi2c.h"
#include "string.h"

u_char str_val[16];

typedef struct{
        u_char Bit0: 1;
        u_char Bit1: 1;
        u_char Bit2: 1;
        u_char Bit3: 1;
        u_char Bit4: 1;
        u_char Bit5: 1;
        u_char Bit6: 1;
        u_char Bit7: 1;
        }FlagTyp;

        FlagTyp Flag;

void Print_On_Lcd (u_char *ptr){
     sprintf(str_val,"Bit5=%d",*ptr);
     LCD_PrintXY(0, 0,str_val);
}

int main(void){
    SystemCoreClockUpdate();
    Delay_Init();
    LCD_Config();

    memset(&Flag, 0, sizeof(Flag)); // nuluj vsetky Flag bity
    Flag.Bit5 = 1; // Flag Bit5 na 1

    u_char a = 1;

    while(1){
        if (Flag.Bit5 == 1) {
        Print_On_Lcd(&a);
        }
        Delay_Ms(2000);
       }
    }


0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 03 Apr 2024, 22:19

Ak mcu ma dostatok pamäte tak prečo nie :) osobne by som použil ale maskovanie

Kód: Vybrať všetko


#define GET_BIT0 ( status_flag & (1 << 0) )
#define GET_BIT1 ( status_flag & (1 << 1) )
#define GET_BIT2 ( status_flag & (1 << 2) )
#define GET_BIT3  ( status_flag & (1 <<3 ) )
#define GET_BIT4  ( status_flag & (1 <<4 ) )
#define GET_BIT5  ( status_flag & (1 << 5 ) )
#define GET_BIT6  ( status_flag & (1 << 6 ) )
#define GET_BIT7  ( status_flag & (1 << 7 ) )

#define SET_BIT0 ( status_flag |= (1 << 0) )
#define SET_BIT1 ( status_flag |=  (1 << 1) )
#define SET_BIT2 ( status_flag |=  (1 << 2) )
#define SET_BIT3  ( status_flag |=  (1 << 3 ) )
#define SET_BIT4  ( status_flag |=  (1 << 4 ) )
#define SET_BIT5  ( status_flag |=  (1 << 5 ) )
#define SET_BIT6  ( status_flag |=  (1 << 6 ) )
#define SET_BIT7  ( status_flag |=  (1 << 7 ) )

#define CLEAR_BIT0 ( status_flag &=~(1 << 0) )
#define CLEAR_BIT1 ( status_flag &=~(1 << 1) )
#define CLEAR_BIT2 ( status_flag &=~(1 << 2) )
#define CLEAR_BIT3  ( status_flag &=~(1 << 3 ) )
#define CLEAR_BIT4  ( status_flag &=~(1 << 4 ) )
#define CLEAR_BIT5  ( status_flag &=~(1 << 5 ) )
#define CLEAR_BIT6  ( status_flag &=~(1 << 6 ) )
#define CLEAR_BIT7  ( status_flag &=~ (1 << 7 ) )

#define CLEAR_ALL status_flag = 0x00 // nuluj vsetky Flag bity


uint8_t status_flag = 0x00;

0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 03 Apr 2024, 22:45

No tak takto s makrami je to elegantné. Idem vyskúšať.

Jo, funguje to. Zo zaujímavosti som porovnal veľkosť skompilovaného kódu jedného aj druhého a výsledok bol rovnaký.
Ale zápis s makrom sa mi páči viac.

Ja sa to C dokonca asi aj nakoniec naučím :lol:
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa budvar10 » 04 Apr 2024, 07:29

Obidva spôsoby sú ekvivalentné. Bitové pole je pre C++ prirodzenejšie, maska pre C. Je to ale asi aj vec vkusu.

Nastaviť celý byte cez memset je brutal. Dá sa to rovno priradením 0. Dobré je však vedieť, že každá globálna premenná je automaticky nastavená na 0 v prológu programu, teda mimo "užívateľskej" časti. V tvojom prípade Flag je globálna.
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 04 Apr 2024, 19:37

budvar10 napísal:
04 Apr 2024, 07:29
Nastaviť celý byte cez memset je brutal.
To ma pobavilo :D
Takto to bude asi lepšie.:

Kód: Vybrať všetko

FlagTyp Flag = {0}; //nuluj vsetky bity 
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa budvar10 » 05 Apr 2024, 07:09

Áno takto, ale písal som, že ten príkaz tam nemusíš dávať. Je to globálna premenná, tak je automaticky inicializovaná na 0 pred vsupom do main.

Memset je vhodné pre väčší rozsah, napr. polia.

Niekedy je dobré vygenerovať a pozrieť si ASM, ale to už je pokročilejšie programovanie. Hlavne ak to robíš pre MCU, kde nie je dosť zdrojov.
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 05 Apr 2024, 12:48

Atlan napísal:
18 Mar 2024, 15:18
Zbezne som na to pozrel. Fast flash.
Bude stacit vyrobit pole o 64prvkoch (tj 64 32bit premenych) natrepad to pola premene ktore chceme ulozit, zapis sa prevedie z celym polom naraz. Teda najprv sa zmaze velkost celeho pola v flash, a potom sa nalsedne cele zapise (je mozne vykonat kontrolu vymazania a kontrolu korektneho zapisu ak by trebalo asi to vynecham)

Takze nehrozi ziadne zapisovanie po jednej premenej ako je zvykom u klasickej eeprom.

Tak ze ak mas nejake premene, vsetky priprav na zapis a naraz budu zapisane. Ak je to nutne vykonaj zapis do 2 stranok pamete. V pripade krachu prvej stranky nacitas data z tej druhej. Alebo pouzijes predvolene hodnoty. Tak ze doporucujem vykonat crc na datach a zapisat to na zaciatok pola. Aby si vedel skontrolovat ci je vsetko ok.

ENC_Count*0.20017)*10;
To by malo ist napisat 20017/1000 tym padom nemusis mat float a veci stym suvisiace
Ahoj chcel by som sa spýtať prečo je nutne pred každým zápisom cele dáta vymazať a následne ich prepísať ? Prečo nemôžeš ukázať na ktorú adresu to chceš zapísať a prepísať len tu ?
0

Atlan
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1152
Dátum registrácie: 01 Feb 2008, 00:00
Bydlisko: Kosice okolie

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Atlan » 05 Apr 2024, 14:23

Lebo je to flash a nie eeprom. Odpoved hladaj v datasheete uP.
Vzorovy priklad je po blokoch - strankach. Mne to takto staci,nicomu to nevadi. Malokedy sa eeprom prepise viac ako 500x pri domacom pouzivani za cely zivitnost zariadenia. Ak potrebujes viac zapisov eprom stoji 10centov.

Zvycajne za zapisuje po blokoch, nacitaju sa do ram skontrokuje crc a zapise do flash.
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 22 Apr 2024, 19:39

Mám v zásobe pár PCF8574 I2C expandérov, bežne ich používam na klasické LCD1602. Teraz som vyskúšal, či je možné zároveň posielať dáta aj čítať stav vstupov. Podľa internetov sa to moc nedá, tak som to vyskúšal.
Vstup 3x tlačidlo, výstup 3x LED ako indikácia stlačeného tlačidla, 1x blikanie LED a 1x PWM výstup na LED.
S týmto procákom to nielenže ide úplne v pohode, ale stíha generovať aj PWM a posielať cez I2C. Všetko nezávisle na sebe čítať stav tlačítok, blikať LEDkou. Toto by som s bežným midrange PICom nedal ani náhodou.
Som ulovil na Ali...se 100ks týchto procákov za 9.40E, teraz už pchám kade tade iba tieto špeky.
Video ako to fachčí:
https://www.youtube.com/watch?v=x239vyO ... rgonCorgon
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 22 Apr 2024, 20:27

Prečo by sa nedalo ?
Tu je projekt kde obsluhujem klávesnicu cez PC8574 meriam napätie(ADC) , meriam prúd(ADC) vypisujem na display cez PC8574 a tak tiež riadim DAC a to na obyčajnej Attiny45 na 8Mhz. Na tvojom 32bitovom 48Mhz to musi isť takto :partyman:
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 22 Apr 2024, 20:46

No počkaj, ale to všetko predsa nerobíš s jedným expandérom. Ja tu paralelne na jednom expandéry čítam 3x vstup, zároveň generujem PWM, v pravidelnom intervale blikám a tiež zapínam výstupy podľa stlačení tlačidla.
Ty tam máš zavesenú maticovú klávesnicu a LCD v 4bit móde. LCD nemusíš stále obnovovať, pošleš dáta a necháš tak. Či? z tej schémy nie je zrejmé ako máš riešené to LCD. V schéme je naznačená iba klávesnica.
0

Atlan
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1152
Dátum registrácie: 01 Feb 2008, 00:00
Bydlisko: Kosice okolie

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Atlan » 22 Apr 2024, 21:03

Kod sem nezavesis? obcas sa taka blbost na nieco moze hodit. Zbytocne vymyslat, ked uz to niekto zbuchal.

Inak ten expander bezi na 100 alebo 400khz, takze s hardverovou podporou i2c bezproblemov na hocicom.
0

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

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Dumitru » 22 Apr 2024, 21:38

Lennox napísal:
22 Apr 2024, 20:46
No počkaj, ale to všetko predsa nerobíš s jedným expandérom. Ja tu paralelne na jednom expandéry čítam 3x vstup, zároveň generujem PWM, v pravidelnom intervale blikám a tiež zapínam výstupy podľa stlačení tlačidla.
Ty tam máš zavesenú maticovú klávesnicu a LCD v 4bit móde. LCD nemusíš stále obnovovať, pošleš dáta a necháš tak. Či? z tej schémy nie je zrejmé ako máš riešené to LCD. V schéme je naznačená iba klávesnica.
Áno áno pošlem a nechám tak, vypisujem cca 4 krát za sekundu len prúd a napätie. Raz za 150-200ms keď sa mi nazberajú 530 meraní z adc vyčítam stav portov pre klávesnicu cez masku pozriem či nič nie je zatlačene, prepočítam adc na napätie a prúd, a vypíšem . Samozrejme že to čo si napísal ty by sa ťažko zvládalo beriem späť
0

Lennox
Stály člen
Stály člen
Príspevky: 291
Dátum registrácie: 12 Sep 2019, 22:51
Bydlisko: Bratislava

Re: WCH32v003 RISC-V MCU

Príspevok od používateľa Lennox » 23 Apr 2024, 18:48

Atlan napísal:
22 Apr 2024, 21:03
Kod sem nezavesis? obcas sa taka blbost na nieco moze hodit. Zbytocne vymyslat, ked uz to niekto zbuchal.
Nech sa paci.
main.c.txt
(3.25 KiB) 16 stiahnutí
PCF8574.h.txt
(6.12 KiB) 27 stiahnutí
Zdatni v C++ nech radsej neotvaraju pre zachovanie ich dusevneho zdravia :mrgreen:
0

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