Skocz do zawartości

[C] [STM32f4 discovery] wolna komunikacja po USART


niezly_patyk

Pomocna odpowiedź

Witam, mam dość dziwny problem z komunikacją.

Do uC podłączony mam enkoder liniowy, cały zakres enkodera to 1900 impulsów.

Chcę wysyłać pozycję po USART do PC i w terminalu ją odczytywać (docelowo w Matlabie).

Informację o położeniu chcę wysyłać w jednym bajcie czyli 0-255, daje mi to wystarczającą dokładność.

Przemnażam więc odpowiednio pozycję.

Problem polega na tym że jeśli impulsy zbierane są w prawo informacja jest wysyłana bez zarzutu, ale gdy zaczynam poruszać enkoder w lewo to informacja do terminala przychodzi z 2s opóźnieniem. Bardzo spowalnia mi to program.

Czy ktoś miał coś podobnego i wie jak to rozwiązać?

Konfiguracja USART:

void init_USART(void) {

/* USART out/in
 * PA2 -TX
*/
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

//Conect USART2 pin to AF2 - Tx = PA2
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

USART_InitStructure.USART_BaudRate = 256000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =
		USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);

USART_Cmd(USART2, ENABLE);
}

Zliczanie impulsów odbywa się w przerwaniu, tam też impulsy są odpowiednio przeliczane:

Kod przerwania:

void EXTI2_IRQHandler(void) {

if (EXTI_GetITStatus(EXTI_Line2) != RESET) {

	extern int imp_l;
	extern int pozycja;

//right
	if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == Bit_SET) {
		imp_l++;

	}
//left
	if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == Bit_RESET) {
		imp_l--;

	}

	pozycja = (int) (((float) 255 * (float) imp_l) / (float) 1900);
	USART_SendData(USART2, pozycja);
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
Link do komentarza
Share on other sites

Zacząłbym od wykorzystania sprzętowych możliwości uC, w tym przypadku obsługi enkoderów 😉 Czemu ma on mielić cały czas przerwania, skoro można to zrobić zupełnie bez udziału CPU?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.