[STM32F429] Generare 1MHz su una GPIO
Buongiorno a tutti,
sto provando a giocare un po' con una scheda STM32F429I-DISC0 che avevo recuperato un po' di anni fa e non avevo ancora avuto modo di provare per davvero. Ho un po' di esperienza con i micro ad 8 bit (HC11 e PIC16F), ma non ho mai usato veramente gli STM32.
Premetto che sono un principiante nel campo, la risposta RTFM mi va benone, mi basta essere indirizzato un pochino perché districarmi in migliaia di pagine in PDF non è affatto facile, per il momento.
Premetto anche che per complicarmi la vita sto usando un sistema di sviluppo molto basilare su macOS, composto in pratica da un makefile (ben lontano dall'essere perfetto) e da una versione della libreria HAL che sono riuscito a far funzionare molti anni fa e che non ho mai avuto il coraggio di aggiornare perché temo di passare ore a correre dietro a file. Non ho mai utilizzato STM32CubeMX per problemi legati al sistema operativo che uso (prima non esisteva per macOS, poi l'ultima versione richiede un OS più recente di quello che sto usando ora). Effettuo il flash tramite St-link da linea di comando:
Per il momento, sono riuscito a scrivere cosettine sul display, far lampeggiare LED, controllare GPIO senza far scorrere troppo sangue. Ora dovrei generare un clock a 1 MHz su un piedino GPIO (mi farebbe comodo PE3, per esempio) e vi devo sincronizzare un po' di avvenimenti (mandare altri segnali, caricare dati su un data bus, etc...).
Finora ho trovato esempi o tutorial su come eseguire un interrupt periodicamente. Non credo che sia il modo migliore per generare un segnale a 1 MHz, ma ho provato questa via comunque senza successo. Ecco la configurazione, ispirata da un tutorial sulla HAL che dovrebbe far lampeggiare un led sulla scheda a 1 Hz:
Qui il codice completo, alquanto work in progress:
https://github.com/DarwinNE/MIDI2SwinSI ... src/main.c
Anche se il tutto viene compilato correttamente e l'error handler non è chiamato durante l'esecuzione , la funzione HAL_TIM_PeriodElapsedCallback qui di seguito non viene mai chiamata:
A questo punto vorrei sapere:
- Per che motivo HAL_TIM_PeriodElapsedCallback non funziona nel codice di cui sopra? Anche se non è il modo migliore per generare 1 MHz mi rimane comunque la curiosità di risolvere questo problema perché potrebbe essermi utile in futuro applicare questa tecnica.
- Quale strategia sarebbe la migliore da implementare per generare 1 MHz e sincronizzare a richiesta altre modifiche su uscite GPIO?
- A termine che strategia sarebbe la migliore da implementare per aggiornare la HAL (val la pena/non val la pena/meglio cambiare libreria/meglio cambiare hobby)
Grazie

sto provando a giocare un po' con una scheda STM32F429I-DISC0 che avevo recuperato un po' di anni fa e non avevo ancora avuto modo di provare per davvero. Ho un po' di esperienza con i micro ad 8 bit (HC11 e PIC16F), ma non ho mai usato veramente gli STM32.
Premetto che sono un principiante nel campo, la risposta RTFM mi va benone, mi basta essere indirizzato un pochino perché districarmi in migliaia di pagine in PDF non è affatto facile, per il momento.
Premetto anche che per complicarmi la vita sto usando un sistema di sviluppo molto basilare su macOS, composto in pratica da un makefile (ben lontano dall'essere perfetto) e da una versione della libreria HAL che sono riuscito a far funzionare molti anni fa e che non ho mai avuto il coraggio di aggiornare perché temo di passare ore a correre dietro a file. Non ho mai utilizzato STM32CubeMX per problemi legati al sistema operativo che uso (prima non esisteva per macOS, poi l'ultima versione richiede un OS più recente di quello che sto usando ora). Effettuo il flash tramite St-link da linea di comando:
- Codice: Seleziona tutto
st-flash write Display.bin 0x8000000
Per il momento, sono riuscito a scrivere cosettine sul display, far lampeggiare LED, controllare GPIO senza far scorrere troppo sangue. Ora dovrei generare un clock a 1 MHz su un piedino GPIO (mi farebbe comodo PE3, per esempio) e vi devo sincronizzare un po' di avvenimenti (mandare altri segnali, caricare dati su un data bus, etc...).
Finora ho trovato esempi o tutorial su come eseguire un interrupt periodicamente. Non credo che sia il modo migliore per generare un segnale a 1 MHz, ma ho provato questa via comunque senza successo. Ecco la configurazione, ispirata da un tutorial sulla HAL che dovrebbe far lampeggiare un led sulla scheda a 1 Hz:
- Codice: Seleziona tutto
void TB_init(void)
{
/*##-1- Configure the TIM peripheral #######################################*/
/* -----------------------------------------------------------------------
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM3CLK = 2 * PCLK1
PCLK1 = HCLK / 4
=> TIM3CLK = HCLK / 2 = SystemCoreClock /2
To get TIM3 counter clock at 10 kHz, the Prescaler is computed as following:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /10 kHz) - 1
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
Each time the core clock (HCLK) changes, user had to update SystemCoreClock
variable value. Otherwise, any configuration based on this variable will be incorrect.
This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
----------------------------------------------------------------------- */
/* Compute the prescaler value to have TIM3 counter clock equal to 10 kHz */
uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;
/* Set TIMx instance */
TimHandle.Instance = TIMx;
/* Initialize TIM3 peripheral as follows:
+ Period = 10000 - 1
+ Prescaler = ((SystemCoreClock/2)/10000) - 1
+ ClockDivision = 0
+ Counter direction = Up
*/
TimHandle.Init.Period = 10000 - 1;
TimHandle.Init.Prescaler = uwPrescalerValue;
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/*##-2- Start the TIM Base generation in interrupt mode ####################*/
/* Start Channel1 */
if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
__HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
BSP_LED_On(LED3);
}
Qui il codice completo, alquanto work in progress:
https://github.com/DarwinNE/MIDI2SwinSI ... src/main.c
Anche se il tutto viene compilato correttamente e l'error handler non è chiamato durante l'esecuzione , la funzione HAL_TIM_PeriodElapsedCallback qui di seguito non viene mai chiamata:
- Codice: Seleziona tutto
/**
* @brief Period elapsed callback in non blocking mode
* @param htim: TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
BSP_LED_Toggle(LED3);
}
A questo punto vorrei sapere:
- Per che motivo HAL_TIM_PeriodElapsedCallback non funziona nel codice di cui sopra? Anche se non è il modo migliore per generare 1 MHz mi rimane comunque la curiosità di risolvere questo problema perché potrebbe essermi utile in futuro applicare questa tecnica.
- Quale strategia sarebbe la migliore da implementare per generare 1 MHz e sincronizzare a richiesta altre modifiche su uscite GPIO?
- A termine che strategia sarebbe la migliore da implementare per aggiornare la HAL (val la pena/non val la pena/meglio cambiare libreria/meglio cambiare hobby)
Grazie

