Warning: Illegal string offset 'name' in [path]/includes/functions.php on line 6439
Atmelis un C -
+
1 2 3 4 5 ...

thread: Atmelis un C

  1. #21
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    Pag, tad man tas F_CPU jāliek iekš speciāli šādiem mērķiem (un varbūt arī citiem mērķiem) veidota main.h un iekš main.c/cpp jāraksta #include <main.h>? Un vispār visus #define , kas man pašlaik ir main.c/cpp jānes uz main.h?

  2. #22
    Senior Member
    Sep 2006
    Riga
    3,053

    Jā, ja mainīgais ir "konfigurācija" programmai.
    Vēl ir tāda nianse, ka Makefile un t.t. kompilatoram var padot defines no konfigurātora compile-with-debug, compile-release un t.t.
    https://gcc.gnu.org/onlinedocs/gcc/P...r-Options.html


    To pašu F_CPU var padot kā parametru
    :
    gcc -DF_CPU=0x000....
    attiecīgi var uztaisīt kompilēšanas profilus:
    "compile 16Mhz atmel graphics LCD"
    "compile 8Mhz atmel 16*2 LCD"
    "compile 8Mhz atmel 16*4 LCD"

    tālāk ar defines iekš koda jau būs darbs ar predefinētām konstantēm un kods strādās zibenīgi.


    Ja ir makefile, tad ar make --configure var visādus pigorus nodefinēt nemainot kodu
    include + define + makefile ir spēks. Viss liels open-source uz tā dzīvo.

  3. #23
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    Paldies! Nu tagad viss ir daudz skaidrāks. Forums tomēr rullē.
    Tas makefile un visas citas gudrības man vēl priekšā, bet nu mācīties nekad nav par vēlu.

    edit: yesss!!! viss rullē bez warningiem.


    Priecīgus Ziemassvētkus!
    Lai spēks ir ar Jums!

  4. #24
    Moderator
    Jan 2009
    Rīga
    4,413

    Cik saparatu, tad makefile aizvieto visu arduino ide un avr studio kopā ņemtu. Vajadzīga tā figņa (nezinu kā saucās), kura māk izpildīt makefile, C kompilators, linkeris (laikam winavr komplekts) un avrdude. Tālāk rakstam C kaut ar notepac (neērti) un dev sistēma gatava. Ka'dreiz pamēģināšu copy/paste no arduino un sakomplektēt savu uzparikti vienā folderī ar kuru kompilēt C priekš AVR. Tīri sporta pēc. Dzīvē noderēs.

    Kas attiecas uz "skeletu" Delfīnu. Skelets tāpēc Delfīns savulaik pazuda no foruma un tagad reinkarnējās. Ļoti vērtīgus padomus par C. Lasu un mācos. Gandīz tik pat labi kā Jurkins. Teorētiski. Vēlreiz liels paldies par mini lekcijām, svarīgu, trāpīgu un interesantu info par C.

  5. #25
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    Tā, mož kādam noder:
    Atkal daru "TO" - izdomāju, ka vajag iemācīties iemest c/cpp projektā asmu, tikai nevis inline, bet gan atsevišķā failā.

    Ierakstu savā main.c failā:
    :
    extern void asm_us_delay(uint16_t us);
    Ierakstu assmblera failā:
    :
    .global asm_us_delay
    .section .text
    asm_us_delay:
        sbiw R25:R24, 1
        brne asm_us_delay
    ret
    Izrādās, ka gcc manu mainīgo us met uz reģistru pāri R25, R24. Nu un rakstu kā ierasts sbiw R25:R24, 1. A bet šis (maita) raksta angliski rupjības un neiet.
    Izrādās, ka jāraksta sbiw R24, 1, bet šis skaita nost no reģistra pāra. Bet, ja rakstītu visu projektu asmā, tad būtu jāraksta kā pirmajā variantā. Nu sviesc!
    :
    .global asm_us_delay
    .section .text
    asm_us_delay:
        sbiw R24, 1
        brne asm_us_delay
    ret
    Un viss ok.

  6. #26
    Senior Member
    Jun 2006
    Cēsu novads
    986

    Izrādās, ka arī asmā nav obligāti rakstīt reģistru pāri, pietiek ar jaunāko reģistru. Pirms kāda laika ar zināmu pārsteigumu šādu lietu konstatēju. C un asm veiksmīga apvienošana ir lieta, kas arī mani stipri interesē. Ir diezgan muļķīgi visu darīt asmā, kā to pašreiz daru, bet īsti nezinu kā to, ko tagad taisu asmā, izdarīt C, nepazaudējot kontroli pār atmiņas sadalījumu un reģistru izmantošanu.

  7. #27
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    O, velns! Vajadzēs pamēģināt. Es jau gan esmu iesācējs gan vienā, gan otrā, bet nu, domāju(ceru), ka tas netraucēs.

  8. #28
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    Nu ko, veiksmīgu un ražīgu visiem Jauno 2016-to.
    A bet es jau pirmajā dienā uzprasījos uz problēmas.
    Divas vienkāršas funkcijas.
    :
    void set_adc_channel(uint8_t channel)
    {
        ADMUX &=~((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3));
        ADMUX |= channel;
    }
    uint8_t get_adc_channel(void)
    {
        return ADMUX&((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3));
    }
    ADC kanālu uzstāda ok, bet, kad es gribu dabūt, kurš ADC kanāls dotajā brīdī ir aktīvs:
    :
    #define ADC1 1
    ...
    ...
    if (get_adc_channel==ADC1)
    {
    ...
    met brīdinājumu "comparison between pointer and integer" un, saprotams, ka neko nesalīdzina.
    Kur ir pointeris? ADMUX takš ir lasāms reģistrs, izmēģināju arduino IDE.
    :
    Serial.println(ADMUX&((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3)),BIN)
    Skaisti parāda, kurš MUX bits kād ir.

    edit: Pats lohs esmu . Azmirsu mazas, mazītiņas iekaviņas.
    :
    #define ADC1 1
    ...
    ...
    if (get_adc_channel()==ADC1)
    {
    ...

  9. #29
    Senior Member
    Nov 2009
    Jēkabpils
    2,046

    Labs vakars!
    Es jau saprotu, ka man nav nekādas sajēgas, kā tiek realizēts 'float' un noteikti iziešu cauri šai tēmai arī, bet varbūt var tā uz pirkstiem:
    :
    float a = 52.96;
    uint8_t temp1 = (uint8_t) a;
    a = 100*a - 100*((float)temp1);
    dod 96, bet
    :
    float a = 52.96;
    uint8_t temp1 = (uint8_t) a;
    a = 100*(a - ((float)temp1));
    dod 95.99...

  10. #30
    Senior Member
    Apr 2007
    2,087

    Tik daudz grābekļu, uz kuriem uzkāpj gandrīz katrs, kurš sāk apgūt C. Daudz ko no tā varētu novērst, lasot C "tēvu" grāmatu (Kernighan & Ritchie, kuri ir arī piedalījušies Unix izveidē).

    Mēģināšu izskaidrot mistēriju par .h failiem:

    1) C kompilatoram ir pavisam pie kājas .h faili. Patiešām. Kompilators strādā tikai un vienīgi ar .c failiem. Tehniski .h faili ir tikai ērta vienošanās, kas atvieglo dzīvi. Nav nekādu noteikumu par to, kā .h faili būtu jāsauc un vai tiem vispār ir jāeksistē.
    2) #include direktīva gluži vienkārši tās vietā ievieto norādīto failu. Nav nekādas īpašas maģijas ar .h failiem, tikpat labi var rakstīt:

    :
    #include <vecmaminas_pensija.txt>
    #include <cits_c_fails.c>
    
    void funkcija() {
    #include "funkcijas_kods"
    }
    3) Pirms katra jauna funkcijas izsaukuma C kompilators grib redzēt šīs funkcijas deklarāciju (jebkur kompilētajā tekstā, bet pirms izsaukuma):

    :
    void deklaracija();   // šī ir funkcijas deklarācija, kas pasaka tikai to, kā šo funkciju izsaukt
    
    // bla bla bla, kaut vai miljons rindiņu 
    
    void izsaukums() {
      deklaracija();
    }
    4) sekas no 1-3 punkta ir tādas, ka ir loģiski funkciju deklarācijas salikt .h failos un tad tos iekļaut .c failos. Piemēram, iekļaujot "stdio.h" failu, attiecīgais .c fails "uzzina" par daudzām jaunām funkcijām.

    5) no katra C faila kompilators izveido .obj (.o) failu, kurš satur definēto funkciju mašīnkodu. Šos OBJ failus pēc vēlmes var apvienot .lib vai .a failos, kas vienkārši satur daudzus OBJ failus (vienkāršoti).

    6) liekot programmu kopā (linkeris) tiek apvienoti norādītie OBJ un LIB faili (kas satur mašīnkodu). Šajā brīdī kompilators sāk meklēt, vai visas funkcijas, kas tiek izsauktas, ir sameklējamas, un tai skaitā pēc noklusējuma meklē main() funkciju. Ja kāda funkcija ar tādu pašu nosaukumu ir realizēta vairākos OBJ failos, rodas konflikts. Ja kāda funkcija, kas tiek izsaukta (pēc tās deklarācijas), nav atrodama nevienā no norādītā failu komplekta, tad arī rodas linkera kļūda un programmu nevar uzbūvēt.

    Tāpēc viss, ko jūs lasāt par to, kas kurā failā ir jāliek, ir blēņas - nav tādu noteikumu, ir vienkārši rīcība un tās sekas. Ir gadījumi, kad C failā vajag iekļaut C failu. Vai ASM failu. Vai citur automātiski ģenerētu koda gabalu. Iesaku iziet cauri kompilatora loģikai, un viss kļūs skaidrs, kurā failā kas ir jāliek!

+