Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Problem z funkcją printf()

Piotr Kania 11 Mar 2009 22:36 1964 10
  • #1 11 Mar 2009 22:36
    Piotr Kania
    Poziom 15  

    Skonfigurowałem sprzętowo uart w atmega8, chciałem użyć funkcji printf i scanf do odbierania i wczytywania danych ale one nie działają . Używam Programmers Notepad [WinAVR]

    to moje boblioteki w tym programie

    Code:

    #include <avr/io.h>
    #include <avr/iom8.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <string.h>
    #include <stdio.h>
    #define F_CPU 8000000UL


    Czy ktoś wie jaka jest przyczyna, oto przykład użycia

    printf("%s%d\n", SMSSEND, n);

    0 10
  • #2 12 Mar 2009 00:24
    kaktus_c++
    Poziom 18  

    Jeśli SMSSEND to *char , a n to int , to printf powinno zadziałać.
    Ale czy printf działa przy uarcie?
    Nie kozystałem z uarta i nie wiem , ale mam biblioteczkę z funkcjami do wysyłania tekstu przez uart.

    0
  • #3 12 Mar 2009 01:08
    KowalD
    Poziom 17  

    po tym jak juz skonfigurowales uart to musisz pamietac, ze funkcja printf wykorzystuje do wyswietlania znakow funkcje putchar (chyba ;))... wiec ona musi byc odpowiednia :)... nie wiem, czy kompilator da Ci je przedefiniowac... tu masz profesionalny przyklad jak podmienic standardowe wejscie/wyjscie: http://www.nongnu.org/avr-libc/user-manual/gr..._stdio.html#g4c04da4953607fa5fa4d3908fecde449

    ale moze i tak zadziala... dopisz do programu: fdevopen(uart_putc, uart_getc,0); gdzie uart_putc to wskaznik do funkcji, ktora potrafi wyslac znak przez uart (czyli musisz napisac funkcje uart_putc(char c); ), a uart_getc analogicznie ;)...

    takie jest moje zdanie, ale moge sie mylic :D...

    0
  • #4 12 Mar 2009 01:19
    shg
    Specjalista techniki cyfrowej

    Tak krócej, bez wywoływania funkcji, zresztą nie wiem, czy one są zaimplementowane w całości, a to na pewno działa, a że zasoby są statyczne, to zajmuje mniej miejsca:

    Code:
    FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
    
    int main(void)
    {
       stderr = stdout = stdin = &uart_str;
    }


    Do tego na przykład taka funkcja, wersja okrojona do granic możliwości:
    Code:
    int uart_putchar(char c, FILE *stream)
    
    {
      loop_until_bit_is_set(UCSRA, UDRE);
      UDR = c;
      return 0;
    }

    Funkcję do odbierania znaków (uart_getchar) sam sobie wymyśl, a jeżeli nie potrzebujesz to NULL w makrodefinicji u góry, a jako flagi podaj _FDEV_SETUP_WRITE.
    Używanie printf(); do takiej pierdółki to moim zdaniem jak strzelanie do much z armaty, no chyba że masz też jakieś bardziej rozbudowane konstrukcje.

    0
  • #5 12 Mar 2009 10:31
    Piotr Kania
    Poziom 15  

    Ja mam obsługę uart w ten sposób

    Code:

    void initrs232(void)
    {
    UCSRC=(1<<URSEL) | (1<<UPM1) | (1<<UCSZ1) | (1<<UCSZ0); //
    UBRRL=51; // 51prędkość 9600 dla 8MHz
    UCSRB=(1<<RXEN) | (1<<TXEN);  //(1<<RXCIE) |
    sei();
    }
    void nadajznak(char dana1) //wyślij znak
    {
    while(!(UCSRA&(1<<UDRE))); //czekaj na wysłanie poprzedniej danej
    UDR=dana1;
    }
    unsigned char odbierz(void) //dobierz
    {
    while(!(UCSRA&(1<<RXC)));
    return UDR;
    }

    void wyslijstring( char *text )  //wyświetl napis
    {
    while(*text)
      nadajznak(*text++);
    }

    i to mi działa ale próbowałem na printf

    Mówiąc krótko potrzebuje wysłać smsa :) i trzeba wydać komendę wyslijstring("AT+CMGS=20"); i to działa ale chciałem to tak zrobić żeby podawać w funkcji tekst do wysłania. Trzeba obliczyć ilość znaków i podać jako argument AT+CMGS= . Umiem policzyć te znaki ale jak tą zmienną wysłać przez uart?

    0
  • #6 12 Mar 2009 13:29
    kaktus_c++
    Poziom 18  

    nie wiem czy dobrze kumam, ale możesz przecież zamienić sobie tą wartość 20 na string za pomocą itoa(20) i go wysłać.

    0
  • #7 12 Mar 2009 21:27
    Piotr Kania
    Poziom 15  

    no a jak to by miało dokładniej wyglądać to użycie itoa bo to jest pomysł nawet niezły

    Dodano po 7 [minuty]:

    zrobiłem próbnie tak

    Code:

    char buffer[3];
    wyslijstring("AT+CMGS=");  // wysyła sms do satiego
    char n=20;
    wyslijstring(itoa(n,buffer,10));
    nadajznak(0x0D);


    i działa ale daje mi takie coś
    rs232.c:88: warning: implicit declaration of function 'itoa'
    rs232.c:88: warning: passing argument 1 of 'wyslijstring' makes pointer from integer without a cast

    0
  • Pomocny post
    #8 12 Mar 2009 21:50
    kaktus_c++
    Poziom 18  

    może więc zrób tak

    Code:
    char buffer[3];
    
    wyslijstring("AT+CMGS=");  // wysyła sms do satiego
    char n=20;
    itoa(n,buffer,10);
    wyslijstring(buffer);
    nadajznak(0x0D);


    I jeszcze dodać trzeba chyba #include <stdlib.h> na początku

    0
  • #9 12 Mar 2009 21:52
    zumek
    Poziom 39  

    Brak prototypu dla funkcji itoa() - stdlib.h
    Zobacz jak wygląda prototyp funkcji itoa(), a będziesz miał odpowiedź na drugie ostrzeżenie.

    0
  • #10 12 Mar 2009 23:03
    Piotr Kania
    Poziom 15  

    dodałem tylko stdlib.h i ruszyło bez problemów. Teoretycznie powinno być
    char * itoa ( int value, char * str, int base );

    ale dziąła

    Code:

    char buffer[3];
    wyslijstring("AT+CMGS=");  // wysyła sms do satiego
    char n=20;
    wyslijstring(itoa(n,buffer,10));
    nadajznak(0x0D);


    jak już czepiamy się wszystkiego to nich ktoś powie dlaczego tak jest dobrze

    0
  • #11 12 Mar 2009 23:43
    Freddie Chopin
    Specjalista - Mikrokontrolery
TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo