I have a push button PC13 and my LED PA5. I want to push my button so that the current state (on, off and toggle) switches to the next one. So for example: The LED is currently on, I push a button, LED switches off, I push the button again and it toggles, I push the button again and it stays on, and so on. When I debug this the counter variable switches to the desired number I am currently at and while I debug this it works perfectly fine. However, as soon as I upload it to the board it doesn't work like in debug state. It is on and then toggles and every additional button push doesn't change.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
int counter = 0;
while (1)
{
int stateOfPushButton = 0;
if (!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1){ //Check if button pressed
HAL_Delay(5); //check for bounce
if (!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1){
stateOfPushButton = 1;
}
}
counter = (counter + stateOfPushButton)%3;
if(counter == 0){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET); //Led Switch On
}
else if(counter == 1){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_RESET); //Led Switch Off
}
else{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // Led toggled
HAL_Delay(1000);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
EDIT:
I added a delay function to check for bounces in the button, proposed by #Jose and the problem persists.
EDIT 2:
It works better, although not ideal, when decreasing the delay function. I guess, my interrupt gets into conflict with the delay function.
The problem was as I suspected in the second EDIT that my interrupt gets into conflict with the delay function in toggle mode. This is due to the circumstance that the while loop continues to loop over and always gets caught in the second delay function. This makes interrupting very hard, since you need to time the interrupt always when in toggle mode it is not caught in the delay function.
To avoid this, simply increase the first delay function, which is responsible to avoid signal bounces, so that it gets longer than the second delay function in toggle mode.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
int counter = 0;
while (1)
{
int stateOfPushButton = 0;
if (!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1){ //Check if button pressed
HAL_Delay(1000); //check for bounce
if (!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1){
stateOfPushButton = 1;
}
}
counter = (counter + stateOfPushButton)%3;
if(counter == 0){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_RESET); //Led Switch Off
}
else if(counter == 1){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET); //Led Switch On
}
else{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // Led toggled
HAL_Delay(20);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Related
I have a small program running on stm32wb55. It tests the TIM2 timer with a delay function called wait_us(). The program runs correctly when I compile it with Keil uVision 5, but when I compile it with STM32CubeIDE it gets stuck in the function get_us(). Is there a bug in STM32CubeIDE?
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
extern void initialize_tim2(void);
extern void wait_us(volatile uint32_t us);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
initialize_tim2();
TIM2->CR1 |= 0x0001;
wait_us(10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOB, LD1_Pin);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
#include "stm32wbxx.h"
volatile uint32_t tim2_counter;
void initialize_tim2(void)
{
RCC->APB1ENR1 |= 0x00000001;
TIM2->CR1 = 0x0004;
TIM2->CR2 = 0x0000;
TIM2->PSC = 0;
TIM2->ARR = 32;
TIM2->DIER = 0x0001;
TIM2->CNT = 0;
NVIC_SetPriority(TIM2_IRQn, 0);
tim2_counter = 0;
}
void TIM2_IRQHandler(void)
{
TIM2->SR &= (~0x001F);
++tim2_counter;
}
uint32_t get_us(void)
{
return tim2_counter;
}
void wait_us(volatile uint32_t us)
{
volatile uint32_t tickstart, now, IRQ_status;
// Get current interrupt status of TIM2 and enable it.
// Needs to be done with all interrupts disabled to prevent race condition?
__disable_irq();
IRQ_status = NVIC_GetEnableIRQ(TIM2_IRQn);
NVIC_EnableIRQ(TIM2_IRQn);
__enable_irq();
tickstart = get_us();
now = tickstart; //<-processing never reaches here under STM32CubeIDE.
while((now - tickstart) < us)
{
now = get_us();
}
// Return to previous interrupt status of TIM2.
// Needs to be done with all interrupts disabled to prevent race condition?
__disable_irq();
if(0 == IRQ_status)
{
NVIC_DisableIRQ(TIM2_IRQn);
}
else
{
NVIC_EnableIRQ(TIM2_IRQn);
}
__enable_irq();
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM6_Init();
MX_UART7_Init();
MX_USART3_UART_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
MX_UART8_Init();
MX_SPI2_Init();
MX_SPI3_Init();
MX_SPI5_Init();
MX_I2C1_Init();
MX_RNG_Init();
MX_TIM3_Init();
MX_USB_OTG_FS_PCD_Init();
MX_RTC_Init();
MX_FMC_Init();
MX_TIM7_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart3,(uint8_t*)RX_BUFFER3,RX_BUFFER3_SIZE);
HAL_UART_Receive_DMA(&huart7,(uint8_t*)RX_BUFFER7,RX_BUFFER7_SIZE);
HAL_UART_Receive_DMA(&huart5,(uint8_t*)BW_BUFFER5, BW_BUFFER5_SIZE);
#if BW16_ENABLE
// BW16 RESET
bw16_Reset();
// BW16 Init
bw16_init(&huart5);
// BW16 Rx Buffer 더미 데이터가 있다면 제거하고 DMA 초기화
RxCntUart5 = __HAL_DMA_GET_COUNTER(huart5.hdmarx);
if(BW_BUFFER5_SIZE != RxCntUart5)
{
__HAL_DMA_DISABLE(huart5.hdmarx);
__HAL_DMA_SET_COUNTER(huart5.hdmarx, BW_BUFFER5_SIZE);
__HAL_DMA_ENABLE(huart5.hdmarx);
// memset하고 나서 데이터가 12개밖에 안 받아짐 근데 안하면 에러
// 20200907
//memset(RX_BUFFER5,0x00,sizeof(RX_BUFFER5));
}
#endif
/* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_Base_Start_IT(&htim7);
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 256);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of TcpTask */
osThreadDef(TcpTask, Tcp_Task, osPriorityIdle, 0, 256);
TcpTaskHandle = osThreadCreate(osThread(TcpTask), NULL);
/* definition and creation of Usart3Task */
osThreadDef(Usart3Task, Usart3_Task, osPriorityIdle, 0, 256);
Usart3TaskHandle = osThreadCreate(osThread(Usart3Task), NULL);
/* definition and creation of Uart7Task */
osThreadDef(Uart7Task, Uart7_Task, osPriorityIdle, 0, 256);
Uart7TaskHandle = osThreadCreate(osThread(Uart7Task), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
HAL_UART_Transmit(&huart3,"START! READY!\r\n",13,0xFFFFFFFF);
/* USER CODE END RTOS_THREADS */
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
I use stm32 If osKernelStart(); is executed in the above code, the repeat statement cannot be executed, so how can I get to the repeat statement?
This is the code to transfer the sensor value through Bluetooth communication, but I have to use another code in the while statement
As the osKernelStart() code is executed, the while statement must also be executed
Please tell me how to do it
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM6_Init();
MX_UART7_Init();
MX_USART3_UART_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
MX_UART8_Init();
MX_SPI2_Init();
MX_SPI3_Init();
MX_SPI5_Init();
MX_I2C1_Init();
MX_RNG_Init();
MX_TIM3_Init();
MX_USB_OTG_FS_PCD_Init();
MX_RTC_Init();
MX_FMC_Init();
MX_TIM7_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart3, (uint8_t*)RX_BUFFER3, RX_BUFFER3_SIZE);
HAL_UART_Receive_DMA(&huart7, (uint8_t*)RX_BUFFER7, RX_BUFFER7_SIZE);
#if BW16_ENABLE
HAL_UART_Receive_DMA(&huart5, (uint8_t*)BW_BUFFER5, BW_BUFFER5_SIZE);
// BW16 RESET
bw16_Reset();
// BW16 Init
bw16_init(&huart5);
RxCntUart5 = __HAL_DMA_GET_COUNTER(huart5.hdmarx);
if(BW_BUFFER5_SIZE != RxCntUart5)
{
__HAL_DMA_DISABLE(huart5.hdmarx);
__HAL_DMA_SET_COUNTER(huart5.hdmarx, BW_BUFFER5_SIZE);
__HAL_DMA_ENABLE(huart5.hdmarx);
}
#endif
/* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_Base_Start_IT(&htim7);
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 256);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of TcpTask */
osThreadDef(TcpTask, Tcp_Task, osPriorityIdle, 0, 256);
TcpTaskHandle = osThreadCreate(osThread(TcpTask), NULL);
/* definition and creation of Usart3Task */
osThreadDef(Usart3Task, Usart3_Task, osPriorityIdle, 0, 256);
Usart3TaskHandle = osThreadCreate(osThread(Usart3Task), NULL);
/* definition and creation of Uart7Task */
osThreadDef(Uart7Task, Uart7_Task, osPriorityIdle, 0, 256);
Uart7TaskHandle = osThreadCreate(osThread(Uart7Task), NULL);
/* definition and creation of BWdataTask */
osThreadDef(BWdataTask, bwdata_Task, osPriorityIdle, 0, 256);
BWdataTaskHandle = osThreadCreate(osThread(BWdataTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void bwdata_Task(void const * argument)
{
/* USER CODE BEGIN bwdata_Task */
/* Infinite loop */
for(;;)
{
SCB_InvalidateDCache_by_Addr ((uint32_t *)BW_BUFFER5, BW_BUFFER5_SIZE);
pos2 = __HAL_DMA_GET_COUNTER(huart5.hdmarx);
pos = BW_BUFFER5_SIZE - pos2;
if(pos != old_pos)
{
if(pos > old_pos)
{
memcpy(rx_temBuffer, &BW_BUFFER5[old_pos], pos - old_pos);
rx_size =+ pos - old_pos;
}
else
{
memcpy(rx_temBuffer, &BW_BUFFER5[old_pos], get_dma_total_size() - old_pos);
rx_size += get_dma_total_size() - old_pos;
if(pos > 0){
memcpy(&rx_temBuffer[get_dma_total_size() - old_pos], &BW_BUFFER5[0], pos);
rx_size += pos;
}
}
old_pos = pos;
if(rx_size > 0)
{
HAL_UART_Receive_DMA(&huart5, (uint8_t*)BW_BUFFER5, BW_BUFFER5_SIZE);
printf("%s\n\r", (char*)&BW_BUFFER5);
#if BW16_ENABLE
bw16_send_data (&huart5, rx_size, "1", rx_temBuffer);
#endif
}
rx_size = 0;
}
}
/* USER CODE END bwdata_Task */
}
I want to write the code above so that I can send and receive wifi, but the wifi connection is good.
However, if I send a message from the server to the client (stm32), it will be printed only once, and I receive a message after that, but it doesn't printf. It says there is a problem like below, how can I solve it?
An MPU or Execute Never (XN) default memory map access violation has occurred on an instruction fetch (CFSR.IACCVIOL, MMFAR).
It's a reaction that comes out if you send it only once below.
I'm beginer in STM32, i have a project and need to receive data from another device like arduino, and now I try transmit data from UART 3 and I receive data with UART 1. but I can't get any data. I connect TX uart 3 to RX uart 1 and TX uart 1 to RX uart 3.
/* USER CODE BEGIN PV */
int i = 0;
char bufferReceive[6], bufferTransmit[10];
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1) //current UART
{
HAL_UART_Receive_IT(&huart1, (uint8_t*)bufferReceive, 1); //activate UART receive interrupt every time
}
}
/* USER CODE END 0 */
int main(void)
{
HAL_UART_Receive_IT(&huart1, (uint8_t*)bufferReceive, 1);
while (1)
{
/* USER CODE END WHILE */`enter code here`
sprintf(bufferTransmit,"%d\n",i);
HAL_UART_Transmit(&huart3, (uint8_t*)bufferTransmit, sizeof(bufferTransmit), 1000);
HAL_Delay(500);
i++;
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
First thing your code is messy and hard to read.
Second, you are missing your entire initialization region before while(1) so your system shouldn't be doing anything.
/* USER CODE BEGIN PV */
int i = 0;
char bufferReceive[6], bufferTransmit[10];
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
HAL_UART_Receive_IT(&huart1, (uint8_t*)bufferReceive, 1);
}
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART3_UART_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t*)bufferReceive, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
sprintf(bufferTransmit,"%d\n",i);
HAL_UART_Transmit(&huart3, (uint8_t*)bufferTransmit, sizeof(bufferTransmit), 1000);
HAL_Delay(500);
i++;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
You are receiving one byte at HAL_UART_Receive_IT(&huart1, (uint8_t*)bufferReceive, 1);.
Which does not wait it simply moves onward.
Next, you transmit bufferTransmit which then causes UART1 to receive one byte and continues to receive all bytes one by one in the same memory location.
It seems you are not using i properly as you probably want something like HAL_UART_Receive_IT(&huart1, (uint8_t*)&bufferReceive[i], 1);
You do not initialize anything. Peripherals, pins, clocks etc have to be set up before they can work.
I'm trying to stop the user from pressing the button for 1 second if it has already been pressed. Can this be done without using the superloop in main.c?
My EXTI0 is in stm32f4xx_it.
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
if (HAL_GPIO_ReadPin (GPIOA,GPIO_PIN_0))
{
HAL_GPIO_WritePin (GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
TIM1_TRG_COM_TIM11_IRQHandler();
HAL_GPIO_WritePin (GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin (GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
}
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
If the user press a button you can get the syste time and save it inside a variable. if the user press again, you can check, if enough time has passed. The example is just for show the mechanism and is just one possibility to solve your problem.
int nLastPress = 0;
void EXTI0_IRQHandler(void)
{
if(nLastPress + 1 < SYSTEM_TIME_IN_SECONDS)
{
// do your stuff
nLastPress = SYSTEM_TIME_IN_SECONDS;
}
else
{
// don't handle user input
}
}