Posted on Leave a comment

How to use Mini STM32 v3.0 USB Port as Virtual Com Port

To use USB port of the mini STM32 v3. We need to configure the USB port and for that, we have to look at the schematics.

You can view the Full schematic here https://www.exasub.com/development-kit/mini-stm32-v3-0/mini-stm32-v3-0/

From the schematics, we see that there are three pins associated with the USB port.
1. PA11
2. PA12
3. PD2

The Pins PA11 and PA12 are
PA11 – USB D-
PA12 – USB D+

These two pins will be configured by the stm32cube ide when you enable the USB device.

PD2 should be configured as GPIO pin.
Because the USB FS implementation says to pull up the D+ line to 3.3V.
The pull up is performed by the S8550 PNP transistor.
So by making the PD2 pin LOW, we enable the USB FS, since it makes the D+ pull up.

We also need to select the Communication Device Class as Class For FS IP.

After configuring the cube mx project. we can proceed to generate code.

The code needs to add the following header file

/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "string.h"
/* USER CODE END Includes */

and then in the main() function. you can write this code in while loop

  /* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  /* USER CODE END 2 */


/* USER CODE BEGIN WHILE */
uint8_t *data = "Hello World from USB CDC\r\n";
  while (1)
  {
	  CDC_Transmit_FS(data, strlen(data));
	  HAL_Delay (1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

After uploading the code to your microcontroller. It will be displayed in your windows device manager as “USB Serial Device”.

You can Connect to the Com port using the serial terminal software such as YAT, Putty or CoolTerm etc.
Note: Since it is a virtual com port, you dont have to set a specific baud rate.

Posted on Leave a comment

How to use 2.8 inch LCD driver on Mini Stm32 V3.0 using STM32CubeIDE

To use the 2.8-inch LCD.

I first checked the hardware schematic to find out all the pins attached to the LCD.

The LCD has a driver ic on its flex cable.
when I read the device code from the IC. The IC is ILI9325

You can check this post here for that

Mini STM32 V3.0

After checking the schematic diagram of both the development board and the LCD. It is time to create a project in STM32 Cube IDE.

After creating the project this is what the pin arrangment looks like in the integrated cubemx of stm32cube ide.

Download the LCD Library from below

  1. Download and extract the zip file.
  2. Inside you will find a folder named “LCD28”
  3. Copy that folder and place it into the driver folder of your stm32cubeide project.
  4. Insert the following header files into your main.c file
/* USER CODE BEGIN Includes */
#include "stm32f103xb.h"
#include "stdio.h"
#include "stdlib.h"
#include "../../Drivers/LCD28/ili932x.h"

/* USER CODE END Includes */
  1. Add the following code to initialize the LCD
/* USER CODE BEGIN 2 */
  

	HAL_GPIO_WritePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin, GPIO_PIN_SET);
	LCD_Init();
	LCD_Clear(BLACK);

  /* USER CODE END 2 */
  1. Here are the list of functions you can use to make graphic on the 2.8 inch display
void LCD_Clear(uint16_t Color);
void LCD_Delay(uint32_t nCount);
void LCD_DrawPoint(uint16_t x,uint16_t y);
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void Draw_Circle(uint8_t x0,uint16_t y0,uint8_t r);
void LCD_Fill(uint8_t xsta,uint16_t ysta,uint8_t xend,uint16_t yend,uint16_t color);
uint16_t WriteOneASCII(uint8_t *pucMsk,
                              uint16_t x0,
                              uint16_t y0,
                              uint16_t color);
uint16_t WriteOneHzChar(uint8_t *pucMsk,
                               uint16_t x0,
                               uint16_t y0,
                               uint16_t color);
void WriteString(uint16_t x0, uint16_t y0,uint8_t *pcStr, uint16_t color);

Demo Program

/* USER CODE BEGIN WHILE */

	HAL_GPIO_WritePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin, GPIO_PIN_SET);
	HAL_Delay(1000);
	LCD_Init();
	LCD_Clear(BLACK);

	uint8_t *textPtr;

	// Example usage of the provided LCD functions
	LCD_Clear(0xFFFF); // Clear the LCD screen with white color

	// Draw a blue line from (10, 10) to (100, 50)
	LCD_DrawLine(10, 10, 100, 50);

	// Draw a filled rectangle from (120, 50) to (180, 150) with red color
	LCD_Fill(120, 50, 180, 150, 0xF800);

	// Draw a green circle with center at (200, 200) and radius 20
	Draw_Circle(200, 200, 20);

	// Write a string at (50, 250) with black color

	textPtr = ((uint8_t *)"Hello www.EXASUB.com");
	WriteString(50,(250),textPtr,RED);



	// Color array in the desired order
	uint16_t colors[] = {BLACK, NAVY, DGREEN, DCYAN, MAROON, PURPLE, OLIVE, LGRAY,
			DGRAY, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE};
	uint8_t numColors = sizeof(colors) / sizeof(colors[0]);

	// Index variable for cycling through colors
	uint8_t colorIndex = 0;
	while (1)
	{
		/* USER CODE END WHILE */
		textPtr = ((uint8_t *)"Hello www.EXASUB.com");
		WriteString(50,(250),textPtr,colors[colorIndex]);
		// Increment the color index and wrap around if necessary
		colorIndex = (colorIndex + 1) % numColors;
		textPtr = ((uint8_t *)"ScIeNcE TeCh EnG MaTh ");
		WriteString(10,(270),textPtr,colors[colorIndex]);

		HAL_Delay(250);


		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
Posted on Leave a comment

How to Blink LED on Mini STM32 v3.0 Discovery Board Using STM32CubeIDE

Step 2: Configure GPIO Pins

#define LED1_Pin GPIO_PIN_2
#define LED1_GPIO_Port GPIOA
#define LED2_Pin GPIO_PIN_3
#define LED2_GPIO_Port GPIOA

In the Project Explorer pane, expand the “Src” folder and open the “main.c” file. Scroll down to the main() function and add the following code to configure the GPIO pins:

/* Configure GPIO pins */
__HAL_RCC_GPIOA_CLK_ENABLE();      // Enable GPIOA clock
GPIO_InitTypeDef GPIO_InitStruct; // GPIO configuration structure
GPIO_InitStruct.Pin = GPIO_PIN_2; // Use pin 2 on GPIOA
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Push-Pull output mode
GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up or pull-down resistors
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Low speed
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Initialize GPIOA with settings

This code configures pin 2 on GPIOA as a push-pull output pin with no pull-up or pull-down resistors and low output speed.

Blink the LED using HAL_GPIO_WritePin

Add the following code inside the while(1) loop to blink the LED:

/* Blink LED */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // Turn LED on
HAL_Delay(1000); // Wait for 1 second
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // Turn LED off
HAL_Delay(1000); // Wait for 1 second

This code turns the LED on by setting the state of pin 2 on GPIOA to high, waits for 1 second, turns the LED off by setting the state of pin 2 on GPIOA to low, and then waits for 1 second again. This creates a blinking effect.

Blink the LED using HAL_GPIO_TogglePin

/* Blink LED */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2); // Toggle the state of the LED
HAL_Delay(1000); // Wait for 1 second

This code toggles the state of pin 2 on GPIOA (which is connected to an LED on the Mini STM32 board) and then waits for 1 second before toggling it again. This creates a blinking effect.

HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_Delay(1000);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);

Code to Blink both LED’s

HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_Delay(1000);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);

The first line toggles the state of an LED connected to the LED1_GPIO_Port and LED1_Pin. The second line waits for 1000 milliseconds (1 second) using the HAL_Delay() function. The third line toggles the state of another LED connected to the LED2_GPIO_Port and LED2_Pin.

Posted on Leave a comment

General Timer based on RTC using stm32f103rb

This timer uses stm32 internal rtc peripheral to display time.

The initialization code is generated using CUBEMX which is embedded inside the CUBE IDE.

/* USER CODE BEGIN WHILE */
	
	RTC_TimeTypeDef readTime;	// RTC Time structure
	RTC_DateTypeDef readDate;	// RTC Date structure
	uint8_t time_hou_var[2];
	uint8_t time_min_var[2];
	uint8_t time_sec_var[2];

	while (1)
	{


    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		/*  function to read time from RTC shadow register */
		    HAL_RTC_GetTime(&hrtc, &readTime, RTC_FORMAT_BIN);

		/* function to read date from RTC shadow register	*/
		    HAL_RTC_GetDate(&hrtc, &readDate, RTC_FORMAT_BIN);

		    itoa(readTime.Hours,(char *)time_hou_var,10);
		    textPtr = ((uint8_t *)(time_hou_var));
		    LCD_Fill(0, 40, 240, (40 + 1)+30, WHITE);
		    WriteString(10,(40*1)+10,textPtr,RED);

		    textPtr = ((uint8_t *)":");
		    WriteString(40,(40*1)+10,textPtr,GREEN);

		    itoa(readTime.Minutes,(char *)time_min_var,10);
		    textPtr = ((uint8_t *)(time_min_var));
		  //  LCD_Fill(0, 40, 240, (40 + 1)+30, WHITE);
		    WriteString(45,(40*1)+10,textPtr,RED);

		    textPtr = ((uint8_t *)":");
		    WriteString(70,(40*1)+10,textPtr,GREEN);

		    itoa(readTime.Seconds,(char *)time_sec_var,10);
		    textPtr = ((uint8_t *)(time_sec_var));
		    //   LCD_Fill(0, 40, 240, (40 + 1)+30, WHITE);
		    WriteString(75,(40*1)+10,textPtr,RED);

		    HAL_Delay(1000);

		    if(HAL_GPIO_ReadPin (GPIOA, KEY1_Pin))
		    {
		    	// Set The LED ON!
		    	HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_SET);

		    }
		    else
		    {
		    	// Else .. Turn LED OFF!
		    	HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_RESET);
		    	//HAL_GPIO_WritePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin, GPIO_PIN_RESET);
		    	HAL_GPIO_TogglePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin);
		    }
}

The code uses itoa() function which needs stdlib.h header file.

itoa() function in C language converts the integer into ASCII digits which are stored in a buffer.

itoa( integar_to_be_converted, Buffer_to_store_conversion, Base_system);

You can choose the base system in itoa function. For conversion to decimal number system, you enter 10

for binary, you can write 2.

for hexadecimal, you can write 16.

and so on.

Posted on Leave a comment

Do not connect microcontroller pins to the VGA monitor directly

I tried to generate VGA signal on stm32f103

I used two timers, the TIMER 2 generate the horizontal sync and then the second timer TIMER 3 is configured in gated slave mode which generates the vertical sync.

Then I used HAL_SPI_TRANSMIT_DMA function inside the timer 2 interrupt handler.

I in a hurried manner connected the video signal to the monitor directly. And that has burned the image onto the monitor.

I connected the green video signal directly from the stm32f103 to the VGA connector.

image is now burned in the monitor.

Posted on 3 Comments

Mini STM32 V3.0

This development board has an STM32F103RB microcontroller. In this development board,

  • 8 Mhz Crystal
  • 32.768 Khz Crystal
  • 2.8 inch TFT-LCD Touch screen.
    The screen is a TFT-LCD Panel driven by the ili9325 driver.
  • PL2303 USB to Serial IC
  • User Programmable USB port
  • battery holder
  • Potentiometer
  • JTAG Port for debug and programming
  • 2 User programmable LED (both Red Colour)
  • 2 User configurable Push button
  • Boot 0 Button
  • Reset Button
  • AMS117 3.3 V LDO

Mini STM32 Schematic Diagram

2.8 inch TFT LCD Schematic

You can develop a program for this board using Keil, IAR or STM32 Cube IDE

You can program the microcontroller by holding the BOOT0 button and then while holding the boot button pressing the RESET button.
Which enable you to program the microcontroller using UART.

You will need STM32 Cube Programmer to upload hex files into the microcontroller

You can also program the Board using the JTAG port.

You can use the below application note for that.

How to use the ST-LINK/V2-1 in STM32L476G-DISCO Board to program the STM32 on an external application board

How To / Guides

Posted on Leave a comment

How to redirect printf() to USART in STM32f103RB using STM32Cube IDE

Printf() function can be redirected to USART and also towards SWO.

Here you will see how to redirect printf() to USART in STM32f103RB

You need to rewrite this code in your main.c file

/*
* Function Name: _write
* Function Description: Redirect the printf() statement towards the UART using the HAL_UART_Transmit
Author: Abhay

*/
int _write(int fd, char* ptr, int len) {
    HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY);
    return len;
}

If you have created your project using STM32CubeMX or STM32 Cube IDE, then you can rewrite it in between USER CODE BEGIN 0 as shown

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int _write(int fd, char* ptr, int len) {
    HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY);
    return len;
}
/* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}

After adding the code, connect the uart to your laptop or computer using serial to USB adapter and open serial Terminal application like YAT.
Then you will be able to see printf message over there.

Posted on Leave a comment

How to use the ST-LINK/V2-1 in STM32L476G-DISCO Board to program the STM32 on an external application board

Here is the video showing all the steps.

ST-Link V2-1 on STM32L476G-Disco Board

To use the ST-LINK/V2-1 to program the STM32 on an external application board (out of the STM32L476VGT6 onboard), remove the two jumpers from CN3 as shown in the above figure in red, and connect the board to the CN4 software debug connector according to Table.
Make sure the jumpers JP6.3V3, and JP5.OFF are set.
JP3, must be ON if CN4 pin 5 (NRST) is used in the external application board.

PinCN4 FunctionJTAG PIN NumberJTAG NameNote
1VappVDD from ApplicationDo not Connect Vapp to JTAG.
2SWCLKSWD Clock9TCK
3GNDGround1 to 9GND
4SWDIOSWD data input/output7TMS
5NRSTRESET of target MCU15nSRST
6SWORESERVED

Note: Do not connect Vapp to JTAG on the external board unless you know about the power domain of the external board.
Power the board separately.

You can use STM32CubeProgrammer to read the memory and also write the hex file into the microcontroller.

Here I am using mini stm32 v3.0 as an example.

The mini stm32 v3.0 has an STM32F103RB microcontroller along with a JTAG interface for programming and debugging.