Skocz do zawartości

[STM32F4] Procesor zawiesza się zamiast przechodzić do wykonania przerwania USART


ziober

Pomocna odpowiedź

Hej, mam problem z przerwaniem od USART1 na procesorze STM32F407VET6. Zamiast obsługi przerwania procesor się "zawiesza", czyli pewnie wskakuje do jakiegoś while(1), natomiast nie mam pojęcia gdzie i dlaczego, bo wydaje mi się że wszystko jest skonfigurowane poprawnie (przykładowe programy posprawdzane po kilka razy). Na oscyloskopie widać, że kanał TX działa poprawnie (nie wykorzystuje przerwania przy nadawaniu), oraz ze otrzymuję dane na kanale RX.

void init_USART1(void){

/* This is a concept that has to do with the libraries provided by ST
 * to make development easier the have made up something similar to
 * classes, called TypeDefs, which actually just define the common
 * parameters that every peripheral needs to work correctly
 *
 * They make our life easier because we don't have to mess around with
 * the low level stuff of setting bits in the correct registers
 */
GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX
USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization
NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)

/* enable APB2 peripheral clock for USART1
 * note that only USART1 and USART6 are connected to APB2
 * the other USARTs are connected to APB1
 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* enable the peripheral clock for the pins used by
 * USART1, PB6 for TX and PB7 for RX
 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

/* This sequence sets up the TX and RX pins
 * so they work correctly with the USART1 peripheral
 */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Pins 6 (TX) and 7 (RX) are used
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 			// the pins are configured as alternate function so the USART peripheral has access to them
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;		// this defines the IO speed and has nothing to do with the baudrate!
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;			// this defines the output type as push pull mode (as opposed to open drain)
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;			// this activates the pullup resistors on the IO pins
GPIO_Init(GPIOA, &GPIO_InitStruct);					// now all the values are passed to the GPIO_Init() function which sets the GPIO registers

/* The RX and TX pins are now connected to their AF
 * so that the USART1 can take over control of the
 * pins
 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); //
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

/* Now the USART_InitStruct is used to define the
 * properties of USART1
 */
USART_InitStruct.USART_BaudRate = 115200;				// the baudrate is set to the value we passed into this init function
USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1;		// we want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No;		// we don't want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
USART_Init(USART1, &USART_InitStruct);					// again all the properties are passed to the USART_Init function which takes care of all the bit setting


/* Here the USART1 receive interrupt is enabled
 * and the interrupt controller is configured
 * to jump to the USART1_IRQHandler() function
 * if the USART1 receive interrupt occurs
 */
 // enable the USART1 receive interrupt
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt

NVIC_InitStructure.NVIC_IRQChannel = 37;		 // we want to configure the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		 // this sets the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			 // the USART1 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure);							 // the properties are passed to the NVIC_Init function which takes care of the low level stuff

// finally this enables the complete USART1 peripheral
USART_Cmd(USART1, ENABLE);

//ESP8266 PD and RST pins
GPIO_InitTypeDef gpio2;

GPIO_StructInit(&gpio2);
gpio2.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
gpio2.GPIO_Mode = GPIO_Mode_OUT;
gpio2.GPIO_OType = GPIO_OType_PP;
gpio2.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &gpio2);

GPIO_SetBits(GPIOA, GPIO_Pin_11);
GPIO_SetBits(GPIOA, GPIO_Pin_12);
}
void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){
	SetLed(SLED2);
	// wait until data register is empty
	while( !(USARTx->SR & 0x00000040)  );
	USART_SendData(USARTx, *s);
	*s++;
	ResetLed(SLED2);
}
}
void USART1_IRQHandler(void){

SetLed(SLED3);
// check if the USART1 receive interrupt flag was set
	if( USART_GetITStatus(USART1, USART_IT_RXNE) ){

		static uint8_t cnt = 0; // this counter is used to determine the string length
		char t = USART1->DR; // the character from the USART1 data register is saved in t

		/* check if the received character is not the LF character (used to determine end of string)
		 * or the if the maximum string length has been been reached
		 */
		if( (t != '\n') && (cnt < MAX_STRLEN) ){
			received_string[cnt] = t;
			cnt++;
		}
		else{ // otherwise reset the character counter and print the received string
			//cnt = 0;
			//USART_puts(USART1, received_string);
		}
	}
}

// Dodane

Z tego co udało mi się jeszcze zbadać, procek się zawiesza, bo wskakuje do HardFault_Handlera, nie wskakuje natomiast ani razu do USART1_IRQHandler, ponieważ miałbym wtedy zapaloną diodkę.

Link do komentarza
Share on other sites

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Pins 6 (TX) and 7 (RX) are used

Na pewno nie pomyliłeś numerów pinów, bo komentarz mówi co innego.

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;			// this activates the pullup resistors on the IO pins

Piny UART nie powinny mieć pull-upu.

Link do komentarza
Share on other sites

Nie jestem pewny co robi funkcja get_it_status bo zazwyczaj bawie się rejestrami ale na pewno po if(get....) powinna się znaleźć linijka czyszcząca flagę przerwania

Link do komentarza
Share on other sites

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.