Skocz do zawartości

[C] [STM32f4 discovery] wolna komunikacja po USART


Pomocna odpowiedź

Napisano

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);
}

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?

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