logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Problem z funkcją printf()

Piotr Kania 11 Mar 2009 22:36 2225 10
  • #1 6269581
    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
    
    #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);
  • #2 6270016
    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.
  • #3 6270095
    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...
  • #4 6270112
    shg
    Poziom 35  
    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:
    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:
    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.
  • #5 6270671
    Piotr Kania
    Poziom 15  
    Ja mam obsługę uart w ten sposób
    
    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?
  • #6 6271254
    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ć.
  • #7 6273744
    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
    
    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
  • Pomocny post
    #8 6273968
    kaktus_c++
    Poziom 18  
    może więc zrób tak
    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
  • #9 6273984
    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.
  • #10 6274405
    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
    
    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
REKLAMA