Skocz do zawartości

STM32F303K8T6 zawiesza się po przerwaniu od Rx (UART)


Vroobee

Pomocna odpowiedź

Witam,

przychodzę z problemem natury dość dziwnej. Może ktoś będzie wiedział o co chodzi. Mianowicie wykorzystując przerwanie od UART przesyłając znak jakikolwiek w stronę procka (np. wpisując w terminalu) procek się zawiesza. Tą samą (własną) bibliotekę przepisałem wykorzystałem na STM32F103RBT6 i wszystko jest ok. Może ktoś z Was znajdzie jakiś błąd jeśli chodzi o ten typ procków (STM32F3). Poniżej dołączam kody:

#include "stm32f30x.h"

#include <stdbool.h>

#include "Delay/delay.h"
#include "RCC_Init/rcc_init.h"
#include "GPIO_Init/gpio_init.h"
#include "USART_STM32/usart_stm32.h"

#define LED_ON	GPIO_SetBits(GPIOB, GPIO_Pin_3)
#define LED_OFF	GPIO_ResetBits(GPIOB, GPIO_Pin_3)
void LED_TOG(uint32_t time);

uint32_t counter;

char data = 0;


int main(void)
{
systick_conf;

rcc_init();
gpio_init();
nvic_init();

usart_init(USART2, 115200);

usart_puts(USART2, "\r\nDevice ready ...\r\n");
_delay_ms(500);


while(1){
	if (odebranoDane == true){
		usart_puts(USART2, buforRx);
		odebranoDane = false;
	}
}
}

void LED_TOG (uint32_t time){
LED_ON;
_delay_ms(time/2);
LED_OFF;
_delay_ms(time/2);
}

void gpio_init(void){
GPIO_InitTypeDef gpio;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB,  ENABLE);

GPIO_StructInit(&gpio);


//********************USART  ***********************
//USART Rx
gpio.GPIO_Pin = GPIO_Pin_15;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_7);

//USART Tx
gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7);

//*****************GPIO**********************
//LED_NUCLEO
gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOB, &gpio);

}
void nvic_init(void){
NVIC_InitTypeDef nvic;
//EXTI_InitTypeDef exti;


#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


//USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

nvic.NVIC_IRQChannel = USART2_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;


NVIC_Init(&nvic);
}



#include "usart_stm32.h"



#include <stdlib.h>
#include <string.h>
#include <stdbool.h>



char buforRx[bufLength] = {0};
char bufRxIndex = 0;

char buforTx[bufLength] = {0};
char bufTxIndex = 0;
bool odebranoDane = false;



void usart_init ( USART_TypeDef* USARTx, uint32_t BAUDRATE){

USART_InitTypeDef usart;

if (USARTx == USART1){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
} else if (USARTx == USART2){
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
}


USART_StructInit(&usart);

// ---------- USART CONFIGURATION ------------

usart.USART_BaudRate = BAUDRATE;


#if USART_WORD_LENGTH == 0
usart.USART_WordLength = USART_WordLength_8b;
#endif
#if USART_WORD_LENGTH == 1
usart.USART_WordLength = USART_WordLength_9b;
#endif


#if USART_PARITY == 0
usart.USART_Parity = USART_Parity_No;
#endif
#if USART_PARITY == 1
usart.USART_Parity = USART_Parity_Even;
#endif
#if USART_PARITY == 2
usart.USART_Parity = USART_Parity_Odd;
#endif

#if USART_STOP == 0
usart.USART_StopBits = USART_StopBits_1;
#endif
#if USART_STOP == 1
usart.USART_StopBits = USART_StopBits_2;
#endif
#if USART_STOP == 2
usart.USART_StopBits = USART_StopBits_1_5;
#endif


#if USART_HARDWARE_FLOW_CRTL == 0
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
#endif
#if USART_HARDWARE_FLOW_CRTL == 1
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS;
#endif
#if USART_HARDWARE_FLOW_CRTL == 2
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_CTS;
#endif
#if USART_HARDWARE_FLOW_CRTL == 3
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
#endif

#if USART_MODE_RX_ENABLE == 1 && USART_MODE_TX_ENABLE == 1
usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
#endif
#if USART_MODE_RX_ENABLE == 1 && USART_MODE_TX_ENABLE == 0
usart.USART_Mode = USART_Mode_Rx;
#endif
#if USART_MODE_RX_ENABLE == 0 && USART_MODE_TX_ENABLE == 1
usart.USART_Mode = USART_Mode_Tx;
#endif

//--------------------------------------------------

USART_Init(USARTx, &usart);

#if USART_Rx_IT_ENABLE == 1
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
#endif


USART_Cmd(USARTx, ENABLE);

}




void usart_putc ( USART_TypeDef* USARTx, char c){
   while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
   USART_SendData(USARTx, c);
}

void usart_puts ( USART_TypeDef* USARTx, const char *s  ) {
   while ( *s )
   	usart_putc (USARTx, *s++);
}

void usart_putint ( USART_TypeDef* USARTx, int value, int radix ){
char string [17];

itoa (value, string, radix);

usart_puts(USARTx, string);
}

char usart_getc ( USART_TypeDef* USARTx ){
char c;

if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE)){
	c = USART_ReceiveData(USARTx);
}

return c;
}


#if USART_Rx_IT_ENABLE == 1

void USART2_IRQHandler (void){
volatile unsigned long int delay;

if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
	buforRx[bufRxIndex] = USART_ReceiveData(USART2);
	if(buforRx[bufRxIndex] == 0x0D){
		odebranoDane = true;
		while (bufRxIndex < bufLength){
			buforRx[bufRxIndex] = 0;
			bufRxIndex++;
		}
		bufRxIndex = 0;
	} else {
		if(buforRx[bufRxIndex] != 0x0D){
			bufRxIndex++;
			if(bufRxIndex > bufLength){
				bufRxIndex = 0;
			}
		}
	}
}
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET){
	USART_SendData(USART2, buforTx[bufTxIndex++]);
	for (delay = 0; delay < 150000; delay++);
	if(buforTx[bufTxIndex - 1] == 0x0D){
		USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
		bufTxIndex = 0;
	}
}
}

#endif

PARAMETRY USART:

#define bufLength	32

extern char buforRx[bufLength];
extern char bufRxIndex;

extern char buforTx[bufLength];
extern char bufTxIndex;
extern bool odebranoDane;


//----------- USART CONFIGURATION ------------

#define USART_Rx_IT_ENABLE 			1			// 0 - DISABLE
											// 1 - ENABLE

#define USART_WORD_LENGTH			0			// 0 - USART_WordLength_8b
											// 1 - USART_WordLength_9b

#define USART_PARITY					0			// 0 - USART_Parity_No
											// 1 - USART_Parity_Even
											// 2 - USART_Parity_Odd

#define USART_STOP					0			// 0 - USART_StopBits_1
											// 1 - USART_StopBits_2
											// 2 - USART_StopBits_1_5

#define USART_HARDWARE_FLOW_CRTL		0			// 0 - USART_HardwareFlowControl_None
											// 1 - USART_HardwareFlowControl_RTS
											// 2 - USART_HardwareFlowControl_CTS
											// 3 - USART_HardwareFlowControl_RTS_CTS

#define USART_MODE_RX_ENABLE			1			// 0 - Rx DISABLE
											// 1 - Rx ENABLE

#define USART_MODE_TX_ENABLE			1			// 0 - Tx DISABLE
											// 1 - Tx ENABLE

Link do komentarza
Share on other sites

Zawiesza w sensie gdy w pętli głównej miga diodą to po przyjęciu przerwania dioda już nie miga 😃 a co dokładnie Cię interesuje jako informacja z debugera (nie wywala żadnego błędu, po prostu procek jakby przestaje pracować)

Link do komentarza
Share on other sites

po prostu procek jakby przestaje pracować

Uuu a to ciekawe.

Tak na poważnie to musisz sprawdzić co się dokładnie dzieje, żadnej magii tam nie ma.

Uruchom program w trybie Debug, wciśnij 'Continue' (albo coś w tym stylu, by się program wykonywał), wymuś to zawieszenie, wciśnij 'Pause' i napisz co się pojawia (w sensie w którym miejscu w kodzie 'będzie' procesor).

EDIT: ja obstawiam brak czyszczenia flagi i ciągłe wywoływanie przerwania USART2_IRQHandler, ale nie chcę Ci psuć zabawy 😉

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

Jak coś jeszcze dodać to proszę o dopisanie skąd co wpisać. Wygląda na to że to coś z Watchdogiem i wpada w jakiś Infinite_Loop

[ Dodano: 18-03-2018, 22:10 ]

W sensie jest opcja, że to błąd w bibliotece ?

Link do komentarza
Share on other sites

Masz wywołanie Default_Handler. Wygląda na to, że nie zdefiniowałeś jakiegoś przerwania, które jest wywoływane. Więc przy zgłoszeniu przerwania wykonywanie wpada w pętlę nieskończoną, żeby nie narobić bałaganu.

Na 99.99% nie błąd w bibliotece. Pokaż drzewko projektu (strukturę plików).

[ Dodano: 18-03-2018, 22:18 ]

Postaw breakpoint na początku USART2_IRQHandler (na pierwszym if-ie) i sprawdź, czy w ogóle funkcja jest wykonywana chociaż raz.

Link do komentarza
Share on other sites

Przesyłam cały folder z programem, może jest jeszcze coś co przeoczyłem 🙂 dziękuję za chęć pomocy.

[ Dodano: 19-03-2018, 10:08 ]

OK znalazłem błąd ... w startup_stm32.s jest funkcja USART IRQ zatytułowana:

USART2_EXTI26_IRQHandler (!!!)

a nie jak miałem wcześniej zapisane:

USART2_IRQHandler

Dlatego nie mógł wejść do przerwania 🙂 dzięki za zwrócenie uwagi na bibliotekę startup_stm32.s

USART_STM32F3.zip

Link do komentarza
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.