STM32 HAL - vysvetlenie kodu

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

Moderátori: psichac, Moderátori

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 22 Jan 2020, 21:00

Dvakrát po sebe

Kód: Vybrať všetko

USART->CR1 =
Na toto pozor, prvá hodnota sa prepíše druhou. Nevypínate si bity ktoré ste už zapli?

EDIT: No presne. 0x0C zapnete TE,RE. A potom 0x01 síce zapnete perifériu, ale zároveň vypnete aj odosielanie aj príjem. A je to v keli.
Takže nejako takto(píšem z hlavy).

Kód: Vybrať všetko

USART2->CR1 |= USART_CR1_TE | USART_CR1_RE;
USART2->CR1 |= USART_CR1_UE;
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 22 Jan 2020, 21:15

Funguje. Ked tak rozmyslam, tak som skusal aj debug a je pravda, ze som si vsimol ye tie bity zrazu sa dali do nuly. Chce to este cvik. Neviem si este zviknut na pouzivanie |=.
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 22 Jan 2020, 21:21

Áno, je to trošku náročnejšie na rozmýšlanie. Ja idem skoro vždy cez |= a &=, aby som neprepisoval čo nechcem. Nevýhoda je, už neraz som sa popálil na reset hodnotách - tak ako vy minule na GPIOx->MODER.

Debugger je super vec. Keď si všimnete nečakanú zmenu bitov, sú dve možnosti. Buď chyba v kóde, alebo to môže robiť hardware - vtedy treba prísť na to prečo.
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 02 Feb 2020, 16:38

Cely den sa trapim s USART. Mam taky jednoduchy kod, ktory mi nechce fungovat. V preruseni inkrementujem rxIndex a teda zapisujem do rxBuf prijate znaky. Prerusenie funguje. Problem je, ze v loop-e sledujem ci je rxIndex vacsi ako 0 a zaroven je prazdny register TXE. Ak je pravda, tak by malo vypisat znak. Mam taky pocit, ze ten rxIndex sa asi nezvacsuje. Dalsi problem, ktory som si vsimol, ze ked som si chcel vypisat hodnotu rxIndex na USART2, tak mi to posiela znaky a nie cislo.

Prosim admina o premenovanie vlakna na STM32 CMSIS.

Kód: Vybrať všetko

while(1)
{
if ((rxIndex > 0) && (USART2 -> ISR & 0x0080))
		{
			USART2 ->TDR = rxBuf[rxIndex];
			
		}

}

void USART2_IRQHandler(void)
{
	
	if (USART2 -> ISR & 0x20)
	{
		rxBuf[rxIndex] = USART2 ->RDR;
		rxIndex++;
		
		if ((rxBuf[rxIndex] == '\r') || (rxBuf[rxIndex] == '\n'))
		{
			
			rxIndex = 0;
			
		}
		
		
	}
	
}
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 02 Feb 2020, 18:12

V tom while nemôže byť zápis do TDR, viete si predstaviť ako rýchlo chŕlite na usart dáta? Lepšie miesto by bolo v tom isr.

Keď ste dali len:

Kód: Vybrať všetko

USART2->TDR = rxIndex;
Toto nemôže fungovať, číslo musíte previesť na string a po znakoch.
Uvedomte si čo sa deje na opačnej strane, prijaté byty sa dekódujú na jednotlivé znaky podľa ASCII.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa peterple » 02 Feb 2020, 19:36

Ako vieš že prerušenie funguje?
Prečo si myslíš že sa ti neikremementuje index? Máš ho označený ako volatile?
Prečo nepoužívaš symbolické mená pre bitové príznaky. Si si istý že používaš správne hex hodnoty? (nepoznám STM). Napr. maskrtnik ti to už naznačil ako sa to robí.

Kód: Vybrať všetko

         while (!(USART1->ISR & USART_ISR_TXE)) ;
         USART2->TDR = 'b';
Toto fungovať nebude

Kód: Vybrať všetko

      rxBuf[rxIndex] = USART2 ->RDR;
      rxIndex++;
      
      if ((rxBuf[rxIndex] == '\r') || (rxBuf[rxIndex] == '\n'))
      {
         
         rxIndex = 0;
         
      }
Vieš prečo? Lebo si si posunul index na volné miesto, takže netestuješ prijatý znak ale nejakú náhodnú hodnotu z pamäte.

Z toho istého dôvodu aj toto nepošle prijatý znak ale nejakú blbosť ktorá je na mieste ešte neprijatého znaku

Kód: Vybrať všetko

if ((rxIndex > 0) && (USART2 -> ISR & 0x0080))
      {
         USART2 ->TDR = rxBuf[rxIndex];
         
      }
}
Moja rada je. Zober si nejaký poriadny debugger pre PC a skus si naprogramovať raw príjem a vysielanie dát cez seriaky PC. Stačia ti na to dva USB serial prevodníky prepojené na kríž zapojedné do toho istého kompu. Pekne si to krokuj a pozeraj kedy a kam sa ti čo uloží. Až budeš vedieť čo sa odohráva v pamäti počítača tak potom to skús na MCU. Len neviem či ten STM nieje moc ťažký kaliber na naučenie sa základov.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 02 Feb 2020, 19:54

Podľa mňa aj stm32 v pohode. Keď sa človek nevrhne rovno na h7 a nedorazí ho to množstvo registrov.
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 02 Feb 2020, 20:25

Ja sa to teraz len ucim. V C som este nikdy nerobil, tak preto ten kod vypada tak ako je. Povodne som chcem tento MCU, STM32L011F4 programovat v mbed, ale tento MCU ma malu pamat a kod z mbed bol priliz velky. Potom som chel teda skusit programovat v HALe, ale nakoniec som zistil, tak ako mi pisal maskrtnik, ze bez nastudovania reference manualu a pochopenie registrov to jednoducho nepojde. Tak to teda skusam s registrami. Symbolicke mena mi zatial tiez moc nejdu, tak uz ked citam ten register a jeho tabulku, tak rovno bity hodim do hexu a pouzijem to. Snad casom aj tie mena budem pouzivat.
Toto fungovať nebude
Kód: Vybrať všetko
rxBuf[rxIndex] = USART2 ->RDR;
rxIndex++;

if ((rxBuf[rxIndex] == '\r') || (rxBuf[rxIndex] == '\n'))
{

rxIndex = 0;

}
Ano, uz som to zistil.
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 02 Feb 2020, 21:30

Priamo v ref manuáli sú mená registrov aj bitov. Presne ako je symbolické meno potom dohľadávam v .h súbore.
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 14 Feb 2020, 23:21

Ahojte, rstale skusam, skusam a uz neviem ako dalej. Narazil som ne jeden problem. Mam dve prerusenia, Jedno je LPUART1 a prerusenie nastane ked prijime znak z GPS modulu. Druhe prerusenie je USART2 ked prijime nejaky znak z PC. Obe prerusenia posielaju znak do TDR registra USART2. GPS posiela data kazdu sekundu. Kazdu piatu sekundu posle cca 200 znakov resp. bytov. Problem nastava, ze ked poslem z PC nejake znaky, bud ich naklikam rychlejsie atd. tak pravdepodobne nastane nejaka kolizia, pretuze MCU alebo program prestane pracovat a nefunguje ani jedno prerusenie. Neviem ako sa da toto osetrit. Poradi niekto ?

Kód: Vybrať všetko

void LPUART1_IRQHandler(void)
	
{
	while (!(LPUART1 -> ISR & USART_ISR_RXNE)){}
	
		
		while  (!(USART2 -> ISR & USART_ISR_TC)){}
		
			USART2 -> TDR = LPUART1 ->RDR;
			
			USART2 ->ICR = USART_ICR_TCCF;
		
	
	
}


void USART2_IRQHandler(void)
{
	GPIOB->ODR |= GPIO_ODR_OD6;
	char buffer[10];
	while (!(USART2 -> ISR & USART_ISR_RXNE)){}
	
		rxBuf[rxIndex] = USART2 ->RDR;
	        rxIndex++;
		
		if ((rxBuf[rxIndex-1] == 10) || (rxBuf[rxIndex-1] == 10))
		{
			
			for(i=0;i< rxIndex;i++)
			{
				
				
				while (!(USART2->ISR & USART_ISR_TC)){}
		
			             USART2 ->TDR = rxBuf[i];
			             USART2 ->ICR = USART_ICR_TCCF;
						
					
		    
	    }
			
			rxIndex = 0;
			rxFlag = 1;	
			
		}
		
	
	
}
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2563
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa maskrtnik01 » 15 Feb 2020, 08:27

Dajte si breakpoint do prerušení HardFault,BusFault atď. Keď zlyhal cpu, budeme to vedieť.

Tiež v čase keď to zblbne dajte na debuggeri pauzu, malo by to ukázať kde to visí.
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 15 Feb 2020, 10:34

No problem je, ze na tejto mojej testovacej doske nemam vyvedeny dubug. Mam vsak NUCLEO-L073RZ, tak skusim ten program prepisat a pouzit debug na tom.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa peterple » 15 Feb 2020, 11:00

Pád programu by mohlo vysvetliť toto
https://electronics.stackexchange.com/q ... n-an-stm32
Máš obslúžený aj overrun interrupt?

A teraz ako k nemu dôjde. Nuž tak že v obsluhe prerušenia prijatia znaku v prípade prijatia znaku LF (mimochodom namiesto čísla 10 sa zvykne v C používať znaková konštanta '\n') tak začneš vysielať celý nabuffrovaný riadok. Ak v tejto dobe prídu dva znaky tak to spôsobí overrun nakoľko ten prvý prijatý už nič nevyberie.

Je nemúdre v prerušeniach vykonávať akékoľvek akcie ktoré trvajú dlhý čas. Takéto veci sa riešia práve cez buffre, stavové mašiny, semafóry, mutexy a vôbec to nie je jednoduché. Začal si poriadne zložitým problémom na začiatok.

-- Spojený príspevok 15 Feb 2020, 11:07 --

Ono ešte lepšie ako buffre je na tento problém kruhová fronta. Ak to chceš naozaj naprogramovať na STM tak by si to mal najprv pochopiť ako to pracuje. To znamená že by si mal úplne do detailu pochopiť napríklad ako to má urobené Arduino v knižnici Serial, vrátane toho ako hýbať tými ukazatelmi head a tail, tak aby to bolo atomické a aby sa ti nestratil pri príjme/vysielaní v prerušení a v hlavnej slučke ani byte.
(teda potrebuješ dve kruhové fronty, jednu na príjem, jednu na vysielanie).
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 15 Feb 2020, 15:13

peterple, bohuzial, zatial netusim ako sa s overrun pracuje. Skusim to prerusenie trochu prepracovat.
0

bibibo
Pokročilý člen
Pokročilý člen
Príspevky: 625
Dátum registrácie: 05 Nov 2009, 00:00
Bydlisko: Bratislavský kraj

Re: STM32 HAL - vysvetlenie kodu

Príspevok od používateľa bibibo » 13 Apr 2020, 19:22

Ahojte, chcel by som sa vratit este k problemu prerusenia LPUART1 a USART2. Kupil som si konecene NUCLEO board s rovnakym procesorom, takze mozem teraz debugovat. Problem je, ze netusim ako odhalim moj problem. Pouzivam Keil a spustil som Dubugger a program. Poslal som nejake znaky z PC a dosiahol som pad programu alebo MCU. Netusim vsak co by som mal z toho vycitat.
0

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