Mega8 UART prijem string – Mikrokontroléry – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Mega8 UART prijem string – Mikrokontroléry – Fórum – Programujte.comMega8 UART prijem string – Mikrokontroléry – Fórum – Programujte.com

 

TD
~ Anonymní uživatel
28 příspěvků
23. 10. 2015   #1
-
0
-

Zdravím, Mam menší problem s primem alebo s uloženim retazcem stringu do pole kere dalej možem v main využit a spracovavat. Ked primam jeden char tak to ide ale ked chcem prijat retazek už to nerobí nic. sem  koncoch :/ a sem začatečnik robil sem to pomocou datasheetu plus neco z netu tak ked to bude cele zle snad ma neukamunejete

    #include <avr/io.h>  
    #include <util/delay.h>
	#include <stdlib.h>
	#include <stdio.h>    
    #include <avr/interrupt.h>  
      
    #include "uart.h"
	#include "lcd.h"  
      
    int main(){  
          
		  char pole[16];
		  char text[32];
        
        uart_init(4800);
		lcd_init(LCD_DISP_ON);  
      
        lcd_clrscr();
	    lcd_gotoxy(0,1);
        lcd_puts(" Funguju a Ahoj");
	    _delay_ms(2000);
        lcd_clrscr();



        while(1){
		  
            uart_getc(pole);

            sprintf(text,"hodnota:%c",pole);  
            lcd_clrscr();  
            lcd_gotoxy(0,0);  
            lcd_puts(text);
			_delay_ms(2000);
			 
        }  
      
        return 0;  
    }  
ISR(USART_RXC_vect)
{

	
	if (rx_pos == BUF_SIZE) rx_pos = 0;

	if(rx_stav != RX_UKONCENE){
		
		rx_buff[rx_pos] = UDR;	
	
		//ak prisiel ukoncovaci znak
		if ((rx_buff[rx_pos] == '\r')|(rx_buff[rx_pos]=='\n')){	
			rx_buff[rx_pos+1] = '\0';	
			rx_stav = RX_UKONCENE;	
		}else{			
			rx_pos++;	 
		}
	}
}
unsigned char uart_gets(char* rx_pole){
	
	if(rx_stav == RX_UKONCENE) {
		strcpy(rx_pole, rx_buff);
		rx_stav = RX_NEUKONCENE;
		rx_pos = 0;
		
		return 1;	

	}else{
		rx_pole = 0;
		return 0;	
	}

}
Nahlásit jako SPAM
IP: 89.103.90.–
23. 10. 2015   #2
-
0
-

Nevím, jak máš deklarované proměnné rx_ ... Zasahuje se do nich při obsluze přerušení a tak by to mělo být s použitím modifikátoru volatile: 

volatile int číslo;


Překladač pak neoptimalizuje a čte hodnotu přímo z paměti kde je proměnná umístěná. Jinak bych ISR asi trochu zjednodušil, v komunikaci bych použil jen jeden ukončovací znak: 

if ( ++rx_pos < BUFF_SIZE)  {
   //pokracuju v prijmu
   rx_buff[rx_pos] = UDR;
   if (rx_buff[rx_pos] == '\r')  {
      //konec prijmu
      rx_buff[rx_pos] = 0;
      hotovo = 1;
   }
}
else  {
   //buffer je plny
}

Je třeba si uvědomit, že ISR bývá časově kritická. Procesor musí za dobu příjmu znaku (je určena rychlostí přenosu - baudrate) stihnout provést celou ISR vč. návratu do hl. programu. Dále je třeba se podívat, zda některý z příznaků přerušení se nemusí nulovat softwarově.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:2903:56...–
KIIV
~ Moderátor
+43
God of flame
23. 10. 2015   #3
-
0
-

#2 hlucheucho
U ATMega8 se priznak vynuluje pri precteni UDR, takze neni treba nic nulovat.

Dale, pokud bude posilat \r\n z terminalu, tak mu to bude delat paseku na zacatku retezce v dalsim kole, takze bych to tam klidne nechal oboje.

A u rx_buff[rx_pos] = 0; radeji pouzivam  '\0'. Je pak naprosto jasne, ze tam chtel autor dat konec retezce.

A jeste dale: cekani v mainu je tam dost nebezpecne, obzvlaste, pokud bys stihl vicero prikazu behem doby cekani, tak o ne prijdes, protoze se zapisou do bufferu za ukoncovaci znak (v puvodnim programu by to delalo kdo vi co, obzvlaste, pokud by prikaz byl delsi. Proste lepsi by byl kruhovy buffer)

#1 TD
take neni od veci kontrolovat navratovy stav, kdyz uz ho tam mas. Takhle ti to bude opakovat stale dokola to same (jelikoz jsi v puvodnim programu nezapisoval ukonceni retezce na jeho prvni pozici, ale jen vynuloval kopii adresy toho retezce tim rx_pole = 0; !)
 

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
23. 10. 2015   #4
-
0
-

Pokud je komunikace Master (jednočip) - Slave (měrka tlaku, regulátor, GSM modul) pak toto jednoduché řešení stačí. Délka odpovědi je předem známá a nic jiného samo od sebe nepříjde. Jiná situace je být jako slave na sběrnici. Tam se to často řeší předepsaným klidem na sběrnici před a po komunikaci, např. Modbus má u Omronu po komunikaci předepsaných 6,7 ms. I v takovém případě kruhový buffer není nutný, je to dost času s daty něco udělat, stačí to i na uložení do EEPROM. Použití kruhového bufferu má nějakou režii - pracnost, strojový čas Pokud by hrozilo, že nestihnu převzít celou zprávu a být připraven na příjem nové, zvolil bych buď větší výkon MCU (to už jsem párkrát dělal) nebo hardwarové řízení toku (k tomu jsem nikdy sáhnout nemusel). Na 8051 snaha o dokonalé řešení vedla většinou ke stavu, kdy MCU nestíhal nic jiného. To mne vedlo k vytváření celé komunikace přímo na míru s vypuštěním některých věcí, které se v konkrétních podmínkách vyskytnout nesmí (dvojznak na konci - není ve striktně předepsaném komunikačním protokolu) nebo nejsou potřeba (kruhový buffer - v klidu po komunikaci zvládnu zpracovat, pokud je klid porušen, je to jen smetí které stačí ignorovat).

Pokud chodí na konci zprávy "dvojznak", pak by to chtělo upravit stavový automat příjmu zprávy tak, aby nedocházelo k interpretaci druhého ukončujícího znaku jako přijetí prázdného řetězce.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:2903:56...–
KIIV
~ Moderátor
+43
God of flame
23. 10. 2015   #5
-
0
-

Mel jsem spise na mysli:

        while(1){
            uart_getc(pole);
	    /// ...
	    _delay_ms(2000);
        }

Proste ze ten buffer vybira jednou za 2 sekundy. Kdyby procesor jen uspal do IDLE, tak po zpracovani ISR se mu bude vykonavat dal i zbytek while po sleep_cpu. Taky nema v uart_get zakazane preruseni, teoreticky taky muze prijit dalsi znak mezi nastavenim NEUKONCENE a nastaveni rx_pos. No proste je tu spousta rizik.

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
23. 10. 2015   #6
-
0
-

#5 KIIV
Toho jsem si nevšiml  . Opravdu je vhodnější provést po návratu z obsluhy přerušení alespoň jednu iteraci hl. smyčky programu a na jejím konci "spát" v Idle do dalšího přerušení.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:2903:56...–
TD
~ Anonymní uživatel
28 příspěvků
23. 10. 2015   #7
-
0
-

no ty RX mam takto  

#define RX_UKONCENE 1
#define RX_NEUKONCENE 2


a ked sem upravil main tak mi to funguje ...  

while(1){  
        
        if(uart_gets(pole)){  
        
       lcd_clrscr();
        lcd_gotoxy(0,0);
	   lcd_puts(pole);
       uart_puts(pole);
	   
        }     
    }  

Nejak nechapem vaše myšlenkove pochody kde tam mam neco zle

Nahlásit jako SPAM
IP: 89.103.90.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 5 hostů

Podobná vlákna

Uart příjem z AVR — založil Ghulas

Příjem z COM portu — založil radar.sm

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý