Skocz do zawartości

[C] [STM32f4 discovery] wolna komunikacja po USART


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 to post
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 to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.