Anteprima
Vedrai una selezione di 5 pagine su 19
Laboratorio 4 Pag. 1 Laboratorio 4 Pag. 2
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio 4 Pag. 6
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio 4 Pag. 11
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio 4 Pag. 16
1 su 19
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

HAL_UART_Receive_IT(&huart2, (uint8_t *)&receivedChar, sizeof(receivedChar));

// Check if data has been received

if (correctlyReceivedData == 1)

{ correctlyReceivedData = 0; // Reset the receive flag

// Handle the received character

switch (receivedChar)

{

case '1': // Toggle the LED (GPIOA pin 5)

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

HAL_UART_Transmit_IT(&huart2, (uint8_t *)"LED Toggled\r\n", sizeof("LED Toggled\r\n"));

break;

case '2': // Send pushbutton status over UART

if (button_state == 0)

{ HAL_UART_Transmit_IT(&huart2, (uint8_t *)"PUSHBUTTON PRESSED\r\n", sizeof("PUSHBUTTON

PRESSED\r\n"));

}

else

{ HAL_UART_Transmit_IT(&huart2, (uint8_t *)"PUSHBUTTON RELEASED\r\n", sizeof("PUSHBUTTON

RELEASED\r\n"));

}

break;

case '3': // Show the menu again

HAL_UART_Transmit_IT(&huart2, (uint8_t *)welcomeMessage, sizeof(welcomeMessage));

break;

default: // Handle invalid options

HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Invalid Option\r\n", sizeof("Invalid Option\r\n"));

break;

}

}

}

}

/* UART transmission complete callback */

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

{ correctlySentData = 1; // Set the transmission complete flag

}

/* UART reception complete callback */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{ correctlyReceivedData = 1; // Set the reception complete flag

}

NOTE: The two callback functions have a control role, verifying whether the transmission and

reception was successful, using the variables correctlySentData and correctlyReceivedData.

Finally, we proceeded on to the execution of the project using the "Serial_Interface_v2» program

to allow communication between the PC and the NucleoBoard. One thing to pay attention to is

that the Baud_rate of the two signals is equal, in order to have a correct transmission. Below

are the results obtained:

The program functions correctly: it toggles the pin if you send 1 from the PC, reads the

pushbutton status if you send 2 and rewrites the initial menu with 3.

4.2 & 4.3 Measure and simple analysis of the frequency and duty

cycle of an external square waveform

The objective of Exercise 4.2 is to measure the frequency and duty cycle of an external square

wave using the Input Capture functionality of the TIM3 timer. The calculated values must be

sent to the PC via serial communication. User interaction is done by sending commands: '1' to

obtain the frequency and '2' for the duty cycle.

Exercise 4.3 is an extension of the previous one. In addition to calculating and communicating

frequency and duty cycle values, the program must determine and store the maximum and

minimum frequency values detected since start-up. The user can request these values by

sending the commands '3' (maximum frequency) and '4' (minimum frequency).

Given the close correlation between the two exercises, they are treated in an integrated way,

with a particular focus on the additional functionalities required by exercise 4.3.

We started with the flowchart:

NOTE: The additions for exercise 4.3 are in orange.

Key variables such as PERIOD, HIGH_TIME, MAX_FREQ, MIN_FREQ, PSC, and flags

(FIRST_EDGE, SECOND_EDGE, THIRD_EDGE) are initialized in the flowchart for detecting

signal edges. The pin for Input Capture (PIN6) is configured in "alternate function" mode, and

the TIM3 timer is set to detect rising and falling edges, allowing duty cycle and frequency to be

calculated. Interrupts are enabled for TIM3 and UART.

During operation:

FIRST_EDGE: The first rising edge saves time in FIRST_TIME and triggers detection of the

• next edge.

SECOND_EDGE: The next falling edge records SECOND_TIME, from which HIGH_TIME

• is calculated.

THIRD_EDGE: The new rising edge saves THIRD_TIME and allows us to calculate the

• period (PERIOD), frequency and duty cycle, completing the cycle.

For Exercise 4.3, the minimum (MIN_FREQ) and maximum (MAX_FREQ) frequency values are

updated if the calculated frequency is lower or higher than the current values, respectively.

UART communication allows us to receive commands from the user and send a certain piece

of data depending on the command.

Then, we passed on to the configuration:

Configuration of the Timer with a frequency of 84MHz from the Clock Configuration,

• enabling of Timer 3 (CH1) and the relative Interrupt, configuration of the USART2 and the

relative Interrupt as in the last exercise;

Configuration of Timer 3 parameters: PSC = 27, to reduce the frequency of the Timer by

• always having an integer and avoiding too high a number of OVFs, polarity sensitive to

both edge;

Configuration of PINA6 in alternate function as it is connected to channel 1 of Timer 3,

• the one used

From the manual we used the following HAL functions:

HAL_TIM_IC_Start_IT(): starts the Input Capture mode on TIM3, channel 1, with

• interrupts enabled;

HAL_TIM_IC_CaptureCallback(): callback function triggered when an Input Capture

• event occurs. Reads and processes the captured timer value;

HAL_TIM_ReadCapturedValue(): reads the captured value from the specified timer

• channel;

HAL_UART_Receive_IT(): initiates non-blocking UART reception with interrupts;

• HAL_UART_Transmit_IT(): initiates non-blocking UART transmission with interrupts;

• HAL_UART_TxCpltCallback(): callback triggered when UART transmission is

• completed;

HAL_UART_RxCpltCallback(): callback triggered when UART reception is completed;

• HAL_TIM_PeriodElapsedCallback(): callback triggered when the timer counter

• overflows;

HAL_GPIO_ReadPin(): reads the state of the specified GPIO pin (high or low).

From here we wrote the code (in orange the part related to exercise 4.3):

#include "main.h"

#include <stdio.h>

#include "string.h"

volatile uint16_t firstEdgeTime = 0;

volatile uint16_t secondEdgeTime = 0;

volatile uint16_t thirdEdgeTime = 0;

volatile uint16_t highTime = 0;

volatile uint16_t period = 0;

volatile int ovf = 0;

volatile int dutyCycle = 0;

volatile int frequency = 0;

volatile int correctlySentData = 0;

volatile int correctlyReceivedData = 0;

char receivedChar;

volatile int first_edge = 0;

volatile int second_edge = 0;

volatile int third_edge = 0;

char freq_str[30];

char dc_str[30];

char maxFreq_str[30]; // For the maximum frequency

char minFreq_str[30]; // For the minimum frequency

volatile int maxFrequency = 0;

volatile int minFrequency = 201;

int main(void)

{ HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); // Input Capture on PA6

while (1)

{ if (third_edge == 1)

{ snprintf(freq_str, sizeof(freq_str), "Frequency: %d Hz\r\n", frequency);

// Configure UART interface to receive a character

HAL_UART_Receive_IT(&huart2, (uint8_t *)&receivedChar, sizeof(receivedChar));

// Check if a character has been received

if (correctlyReceivedData == 1)

{ correctlyReceivedData = 0; // Reset the reception flag

// Handle the received character

switch (receivedChar)

{ case '1':

snprintf(freq_str, sizeof(freq_str), "Frequency: %d Hz\r\n", frequency);

// Transmit the frequency string via UART

HAL_UART_Transmit_IT(&huart2, (uint8_t *)freq_str, strlen(freq_str));

break;

case '2':

snprintf(dc_str, sizeof(dc_str), "Duty Cycle: %d%%\r\n", dutyCycle);

HAL_UART_Transmit_IT(&huart2, (uint8_t *)dc_str, strlen(dc_str));

break;

case '3': // Maximum frequency

snprintf(maxFreq_str, sizeof(maxFreq_str), "Max Frequency: %d Hz\r\n", maxFrequency);

HAL_UART_Transmit_IT(&huart2, (uint8_t *)maxFreq_str, strlen(maxFreq_str));

break;

case '4': // Minimum frequency

snprintf(minFreq_str, sizeof(minFreq_str), "Min Frequency: %d Hz\r\n", minFrequency);

HAL_UART_Transmit_IT(&huart2, (uint8_t *)minFreq_str, strlen(minFreq_str));

break;

default:

HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Invalid Option\r\n", sizeof("Invalid Option\r\n"));

break;

}

}

}

}

}

/* Callback for Input Capture */

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{ if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)

{ if (first_edge == 0)

{ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == 1)

{ firstEdgeTime = ovf * 65535 + HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

first_edge = 1;

third_edge = 0;

}

else

{ first_edge = 0;

}

}

else if (second_edge == 0)

{ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == 0)

{ secondEdgeTime = ovf * 65535 + HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

highTime = secondEdgeTime - firstEdgeTime; // High time

second_edge = 1;

}

}

else if (third_edge == 0)

{ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == 1)

{ thirdEdgeTime = ovf * 65535 + HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

period = thirdEdgeTime - firstEdgeTime;

dutyCycle = (highTime * 100) / period; // Duty cycle in percentage

frequency = (84000000 / (27 + 1)) / period;

third_edge = 1;

// Update maximum and minimum frequency

if (frequency > maxFrequency)

{ maxFrequency = frequency;

}

if (frequency < minFrequency)

{ minFrequency = frequency;

}

}

}

}

}

/* UART Transmission Complete Callback */

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

{ correctlySentData = 1; // Set the transmission complete flag

}

/* UART Reception Complete Callback */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{ correctlyReceivedData = 1; // Set the reception complete flag

}

/* Timer Overflow Callback */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{ ovf = ovf + 1;

}

NOTE: OVFs are taken into account in the calculation of EdgeTime to avoid incorrect

calculations in the presence of one or more OVFs between one front and another. Attention

should also be paid to the calculation of frequency such as:

= =

(+1)∙

84 = 27.

We finally moved on to the execution of the program, we used a signal generator to create a

square wave with a frequency of 70 Hz and a duty cycle of 60%. Through the

"Serial_Interface_v2" program, commands '1' and '2' were sent to request the microcontroller

to calculate and return the frequency and duty cycle. The values received were correct,

confirming the good functioning of the system.

Next, we changed the frequency to 100 Hz to test MAX_FREQ and MIN_FREQ values. By sending

commands '3' and '4', the system correctly reported the maximum and minim

Dettagli
Publisher
A.A. 2024-2025
19 pagine
SSD Ingegneria industriale e dell'informazione ING-INF/01 Elettronica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher michelw16 di informazioni apprese con la frequenza delle lezioni di Electronic system for mechatronics e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Politecnico di Torino o del prof Chiaberge Marcello.