cancel
Showing results for 
Search instead for 
Did you mean: 

Sending 8 -bit data from NUCLEO-F401RE to Basys 3 FPGA using UART

archana95in
Associate II
#include "main.h"
#include "stm32f4xx_hal.h"
 
 
UART_HandleTypeDef huart2;
 
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
 
char buffer[8];
int i = 6;
 
int main(void)
 
  HAL_Init();
 
 
  /* Configure the system clock */
  SystemClock_Config();
 
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
 
  while (1)
  {
 
HAL_UART_Transmit(&huart2, (uint8_t*)buffer, sprintf(buffer, "%d", i), 0);
 
  }
 
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /**Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
 
static void MX_USART2_UART_Init(void)
{
 
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
 
static void MX_GPIO_Init(void)
{
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
}
 
void Error_Handler(void)
{
}
 
#ifdef  USE_FULL_ASSERT
 
void assert_failed(uint8_t *file, uint32_t line)
{ 
 
}

I am trying to send a 8 bit data(ASCII) from Nucleo-F401RE to Basys 3 FPGA(display the result on LED's) using UART. I have configured the PA2(UART2) of Nucleo Board for transmission and one of the PMOD ports of Basys 3 as receiver. The baud rate is 9600bps.

I have tested the transmitter and receiver code of Nucleo and FPGA independently using Teraterm and they seem to work without any issues.

However when I am sending data from Nucleo to FPGA using a jumper for connecting PA2 of Nucleo & PMOD pin of Basys 3(I am not sure if this kind of hardware connection would work), I get erratic values on the LED's of FPGA that is constantly changing. Please correct me if I'm wrong. PFA my code for VHDL Basys 3 FPGA and STM32

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
ENTITY receiver IS
   PORT (
      clk          : IN STD_LOGIC;
     reset        : IN STD_LOGIC;
      RxD          : IN STD_LOGIC;
      RxData       : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
   );
END receiver;
 
ARCHITECTURE behavioural OF receiver IS
   SIGNAL shift               : STD_LOGIC;
   SIGNAL state               : STD_LOGIC;
   SIGNAL nextstate           : STD_LOGIC;
   SIGNAL bitcounter          : STD_LOGIC_VECTOR(3 DOWNTO 0);
   SIGNAL samplecounter       : STD_LOGIC_VECTOR(1 DOWNTO 0);
   SIGNAL counter             : STD_LOGIC_VECTOR(13 DOWNTO 0);
   SIGNAL rxshiftreg          : STD_LOGIC_VECTOR(9 DOWNTO 0);
   SIGNAL clear_bitcounter    : STD_LOGIC;
   SIGNAL inc_bitcounter      : STD_LOGIC;
   SIGNAL inc_samplecounter   : STD_LOGIC;
   SIGNAL clear_samplecounter : STD_LOGIC;
 
   constant clk_freq: integer := 100000000;
   constant baud_rate :integer := 9600;
   constant div_sample :integer := 4;
   constant div_counter :integer := (clk_freq/(baud_rate*div_sample));
   constant mid_sample : integer := (div_sample/2);
   constant div_bit : integer := 10;
 
BEGIN
 
   RxData <= rxshiftreg(8 DOWNTO 1);
 
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (reset = '1') THEN
            state <= '0';
            bitcounter <= "0000";
            counter <= "00000000000000";
            samplecounter <= "00";
         ELSE
            counter <= counter + "00000000000001";
         if (counter>= div_counter - 1) then 
               counter <= "00000000000000";
               state <= nextstate;
               IF (shift = '1') THEN
                  rxshiftreg <= (RxD & rxshiftreg(9 DOWNTO 1));
               END IF;
               IF (clear_samplecounter = '1') THEN
                  samplecounter <= "00";
               END IF;
               IF (inc_samplecounter = '1') THEN
                  samplecounter <= samplecounter + "01";
               END IF;
               IF (clear_bitcounter = '1') THEN
                  bitcounter <= "0000";
               END IF;
               IF (inc_bitcounter = '1') THEN
                  bitcounter <= bitcounter + "0001";
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS;
 
 
 
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         shift <= '0';
         clear_samplecounter <= '0';
         inc_samplecounter <= '0';
         clear_bitcounter <= '0';
         inc_bitcounter <= '0';
         nextstate <= '0';
         CASE state IS
            WHEN '0' =>
               IF (RxD = '1') THEN
                  nextstate <= '0';
               ELSE
                  nextstate <= '1';
                  clear_bitcounter <= '1';
                  clear_samplecounter <= '1';
               END IF;
            WHEN '1' =>
               nextstate <= '1';
               IF (samplecounter = (mid_sample - 1)) THEN
                  shift <= '1';
               END IF;
               IF (samplecounter = (div_sample - 1)) THEN
                  IF (bitcounter = (div_bit - 1)) THEN
                     nextstate <= '0';
                  END IF;
                  inc_bitcounter <= '1';
                  clear_samplecounter <= '1';
               ELSE
                  inc_samplecounter <= '1';
               END IF;
            WHEN OTHERS =>
               nextstate <= '0';
         END CASE;
      END IF;
   END PROCESS;
  end behavioural;

4 REPLIES 4

So put a scope on the signal. Right now you're sending ASCII character '6' repeatedly.

You should be able to see the USART output via the NUCLEO VCP. Watch for pin conflicts on the shield USART pins vs VCP

Make sure the boards have a common ground.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Alex R
Senior

Also check that the signal voltage levels match (that is, both work at the same voltage (3.3V typically, but it can be different for each

@Alex R​ Hi , I checked the voltage levels on pins of both the FPGA and Nucleo and they seem to match (3.3V).

Hi @Community member​ , I see the character 6 via the Nucleo VCP. I also made sure the boards have a common ground. I'm using USART2 ; Pin PA2 to transmit from Nucleo to FPGA. However, the issue persists. Any other suggestions ?