2019-04-10 04:27 AM
#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;
2019-04-10 05:20 AM
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.
2019-04-10 07:15 AM
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
2019-04-10 11:38 PM
@Alex R Hi , I checked the voltage levels on pins of both the FPGA and Nucleo and they seem to match (3.3V).
2019-04-10 11:41 PM
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 ?