sprintf cause my program stop working in keil - c

This is my main function and I don't know why when I simulate it in proteos I figured that the code runs up to sprintf and next lines doesn't run and when I comment it the "salam" printed on lcd
I use mingw compiler and I have installed all librarys
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 */
char q[5] = "salam" ;
int a = 6541;
//float b = a/7;
LCD1602_Begin8BIT(RS_GPIO_Port,RS_Pin,E_Pin,D0_GPIO_Port,D0_Pin,D1_Pin,D2_Pin,D3_Pin,D4_GPIO_Port,D4_
Pin,D5_Pin,D6_Pin,D7_Pin);
LCD1602_setCursor(1,1);
//snprintf(q, 20, "%10d", 1234567);
//LCDCHAR_Puts(0, 0, q);
//char command1[50], command2[50]; // Added
//char *temp[] = {NULL, command1, command2, NULL}; // Modified
//temp[0]="sum";
LCD1602_print("mahdi kahrizi");
LCD1602_2ndLine();
sprintf(q,"%d",a);
LCD1602_print(q);

the problem starts from here.
char q[5] = "salam" ;
q is too short to store this word. It has to be at least 6 chars long.
It is Undefined Behaviour as you write outside the array bounds.
When you change the length of the q to be longer
snprintf(q, sizeof(q), "%d", a);

Related

Sending data using USB CDC (STM32)

I'm using NucleoF413ZH and STM32CubeIDE. I have 16 microphones, each connects to one ADC channel and thanks to the use of DMA it directs data to the memory. However, I would like to do a cross-correlation of the signals, so I came to the conclusion that I would send the data to the PC or RPi 4b, and I would do the calculations there. But the problem for me is sending so much data from the memory. I try to use CDC_TRANSMIT_FS but I cant send all 16 channel measurements, also transmision is very slow.
Is there any way to send whole array of 16 elements, or even better 16xM elements, so maybe it will be faster? I need 16mic x10bit x44.1khz ~= 7Mbit/s =882KBytes/s, also i can reduce some mics to 12 of them. Here is my code (full in link https://pastebin.pl/view/6059edc8 ):
Also, sorry if something is not good grammatically, English is my second language and I'm still learning
/* USER CODE BEGIN PV */
uint16_t Pomiar[16]; // measurments 16x1
char msg[10];
uint8_t DataToSend[40]; //
uint8_t MessageCounter = 0; //
uint8_t MessageLength = 0; // Msg lngth
/* USER CODE END PV */
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1, (uint16_t*)Pomiar, 16);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// CDC_Transmit_FS((uint8_t*)Pomiar, (512));
//++MessageCounter;
//MessageLength = sprintf(DataToSend, "Wiadomosc nr %d\n\r", MessageCounter);
// MessageLength = sprintf(DataToSend, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n\r", Pomiar[0],Pomiar[1],Pomiar[2],Pomiar[3],Pomiar[4],Pomiar[5],Pomiar[6],Pomiar[7],Pomiar[8],Pomiar[9],Pomiar[10],Pomiar[11],Pomiar[12],Pomiar[13],Pomiar[14],Pomiar[15]);
MessageLength = sprintf(DataToSend, "%d:%d:%d:%d\n\r", Pomiar[0],Pomiar[1],Pomiar[2],Pomiar[3]);
CDC_Transmit_FS(DataToSend, MessageLength);
//HAL_Delay(1);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
usart settings
static void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
// huart3.Init.BaudRate = 115200;
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
// huart3.Init.BaudRate = 115200;
huart3.Init.BaudRate = 921600;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
sprintf is very slow and you are sending ASCII 5 digits per ADC sample. You can send raw hex data 2 bytes per sample to save bandwidth like this
CDC_Transmit_FS(Pomiar, sizeof(Pomiar));

STM32 using CubeMX and STMStudio: 'int main()' doesn't work

I'm learning to code on STM32F429ZI Nucleo board and I've been trying to read temperature from ADC1 temperature sensor using STMStudio.
The code I found in one of tutorials didn't work so I tried checking value of "check" variable at various parts of code and then I've noticed that, not only the value of "check" variable doesn't change anywhere inside the main function, but also the STMStudio doesn't see any variables declared inside of the main function.
Any idea why is that?
I've tried different code which uses button to light up LED to check if the board is ok and it worked just fine.
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
uint16_t SenseADC;
float check = 0;
float Temperature;
float Vsense;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
/* 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();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start(&hadc1);
check = 2;
const float V25 = 0.76; // [V]
const float Vsupply = 3.0; // [V]
const float ADCResolution = 4095;
const float avg_slope = 0.0025; // [V/deg. C]
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK){
check = 3;
SenseADC = HAL_ADC_GetValue(&hadc1);
Vsense=(SenseADC*Vsupply)/ADCResolution;
Temperature = (Vsense - V25)/avg_slope + 25;
HAL_ADC_Start(&hadc1);
}
}
}
The compiler must have noticed that the check variable is only written and never read, and optimized away the writes as having no purpose. For debugging purposes, you can declare it as volatile to force all writes to get through to memory.
The const values in the program are likewise victims of the optimization, the compiler has used the values directly in the code, possibility precalculating parts of the expressions.

stm32f051r8t6 TIM14 interrupt handler not working after reset

I am using STM32CubeMX to generate code into IAR, and I am using a stm32f051r8t6 microcontroller,
The problem I am having is that when first loading the code onto the chip, it all works perfect, however after pressing restart on either the board or IAR debugger, the TIM14 interrupt handler is not entered, but as soon as I leave the debugger and enter again, it starts working until I press restart. Has anybody come across this problem before? My code is below
static void MX_TIM14_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM14)
{
HAL_GPIO_WritePin(GPIOA, USART1_TE_Pin, GPIO_PIN_SET);
}
}
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_DMA_Init();
MX_ADC_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_TIM14_Init();
HAL_TIM_Base_Start(&htim14);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
FslBufferControl();
MimModeCheck();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 47999;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 1;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}
You need to add to enable the interrupt.
MX_TIM14_Init();
HAL_NVIC_EnableIRQ(TIM14_IRQn); // <----------------------------
HAL_TIM_Base_Start(&htim14);
Just check the IRQn TIM14 UG event number. They are defined in the IRQn_Type enum type defined in the STM32F___.h file where ___ is the model of your micro (you will find it in the include folder)

MCU as SPI Slave, read data

I have an master which i cant control it just sends clock with data. I congifured my stm32f4 as full-duplex slave. And i managed to synchronize them with HAL function:
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)spi_buffer, (uint8_t *)spi_buffer, 16, 2000);
// receive 16 bytes then send them for debugg
Im sending from slave the bytes which i get from master, in purpose of debugging,
and the data is same, so its perfectly synchronized and seems like slave reading all data master sends. Here is the images(sorry cant dowload it with stackoverflow cuz i low on points):
https://imgur.com/wa6rF5J - ocsillo's image
https://imgur.com/a/ZVCPaNT - zoomed up
The problem is that i dont know how to read that data, its 16bytes which i need somehow to read without slowing the spi down. All my attempts to do that are failed.
Thw whole code are:
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_DMA_Init();
MX_USB_DEVICE_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint8_t collect_bits[16] = {0};
char string_array[21] = {0};
uint8_t spi_buffer[16] ={0} ;
uint8_t flag_when_start_print = 0;
spi_buffer[0] = 5;
uint8_t spi_transmit[16] = {0};
HAL_SPI_Init(&hspi1); //init spi
while (1)
{
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)spi_buffer, (uint8_t *)spi_buffer, 16, 2000);
if (spi_buffer[0] == 0xFE) // just tring to catch 0xFE, doesnt work
{
sprintf(string_array, "%X", spi_buffer[0]); // just simple convertation for PC output
CDC_Transmit_FS((uint8_t*)string_array, sizeof(string_array)); // print result. }
}
}
The important fact that the beggining of the messge i want to catch is always starts with 0xFE0010, so after those bytes i need to read next 13bytes

Writing data to micro SD card from microcontroller STM32F401RET6

I am using the board Nucleo F401RE based on micro-controller STM32F401RET6. I connected to the board a Micro SD slot, and interested in writing data to the SD Card and read data from it. I used the software STM32CubeX to generate code and in particular the SD library with built-in functions. I tried to write a simple code which writes an array to a specific array and tries to read the same data afterwords. The code is as follows:
uint32_t to_send[512] = {1, 2, 3, 4, 5};
uint32_t to_receive[512];
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SDIO_SD_Init();
char buffer[14] = "Hello, world\n";
uint64_t address = 0x00;
HAL_SD_ErrorTypedef write_result = HAL_SD_WriteBlocks(&hsd, to_send, address, 512, 1);
HAL_SD_ErrorTypedef read_result = HAL_SD_ReadBlocks(&hsd, to_receive, 0x00, 512, 1);
HAL_UART_Transmit(&huart2, (uint8_t *) &write_result, 1, 1000);
HAL_UART_Transmit(&huart2, (uint8_t *) &read_result, 1, 1000);
while (1)
{
//HAL_UART_Transmit(&huart2, (uint8_t *)buffer, 14, 1000);
HAL_UART_Transmit(&huart2, (uint8_t *)to_receive, 512, 1000);
}
Though, I don't succeed in writing the data, the function HAL_SD_WriteBlocks() returns the value SD_CMD_CRC_FAIL, which means that : "Command response received (but CRC check failed)". What am I missing ? I checked the hardware configuration many times and the micro SD card is correctly connected to the microcontroller. I can add the implementation of the HAL built-in functions if needed. Thank you.
Make sure that your sdio clock is within valid limits (see function SystemClock_Config):
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 8
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
When using the defines above when initialize the clock (RCC_OscInitTypeDef) the SDIO clock will be 336 / (7*2) = 25Mhz
(Given that PLL_M is the same as the HSE / HSI)
If the frequency is too high (>50Mhz) then perhaps you will get errors in the communication which will explain your symptoms.
I didnt use usart for my project, i write the value to sd card and read the value ,
you must arrange the code for your expectations, my code is
#include "main.h"
#include "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
/* USER CODE BEGIN PV */
/* Private variables --------------------------------------------------------*/
uint8_t to_send[512] = "sener suat sd card";
uint8_t to_receive[512];
uint8_t sener[3]={7,5,4};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* 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_SDIO_SD_Init();
/* USER CODE BEGIN 2 */
uint32_t address = 0x55;
HAL_SD_MspInit(&hsd);
HAL_SD_Init(&hsd);
HAL_SD_WriteBlocks(&hsd,to_send,address,1,500);
HAL_Delay(100);
HAL_SD_ReadBlocks(&hsd,to_receive,address,1,500);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
}

Resources