Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser
En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.
Topic "[Programmation] en C sur des STM32"
Flux RSS des posts récents dans ce topic ( Flux Atom)
Bonjour à toutes et à tous,
je suis maintenant l' heureux possesseur d' un Nucleo 32 f303k8,
j' essais de modifier un code fournit par ST dans STMCube_FW_F3V1.4.0,
c' est l' exemple PWMout.
J' ai du mal à comprendre ces lignes:
1 2 3 4 5 6 7 | /* Set the pulse value for channel 2 */
sConfig.Pulse = PULSE2_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_2) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
|
sConfig est le synonyme de struct TIM_OC_InitTypeDef de la librairie stm32f3xx_hal_tim.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /**
* @brief TIM Output Compare Configuration Structure definition
*/
typedef struct
{
uint32_t OCMode; /*!< Specifies the TIM mode.
This parameter can be a value of @ref TIMEx_Output_Compare_and_PWM_modes */
uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
uint32_t OCPolarity; /*!< Specifies the output polarity.
This parameter can be a value of @ref TIM_Output_Compare_Polarity */
uint32_t OCNPolarity; /*!< Specifies the complementary output polarity.
This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
@note This parameter is valid only for TIM1 and TIM8. */
uint32_t OCFastMode; /*!< Specifies the Fast mode state.
This parameter can be a value of @ref TIM_Output_Fast_State
@note This parameter is valid only in PWM1 and PWM2 mode. */
uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
} TIM_OC_InitTypeDef;
|
Je comprends à peu près cette structure. Mon souci vient plutôt du fait que je ne comprends pas comment pouvoir
utiliser chaque canal du Timer indépendamment les uns des autres. je mets le code en entier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | #include "main.h"
/** @addtogroup STM32F3xx_HAL_Examples
* @{
*/
/** @addtogroup TIM_PWMOutput
* @{
*/
/* Private typedef -----------------------------------------------------------*/
#define PERIOD_VALUE (uint32_t)(444 - 1) /* Period Value */
#define PULSE1_VALUE (uint32_t)(PERIOD_VALUE/2) /* Capture Compare 1 Value */
#define PULSE2_VALUE (uint32_t)(PERIOD_VALUE*37.5/100) /* Capture Compare 2 Value */
#define PULSE3_VALUE (uint32_t)(PERIOD_VALUE/4) /* Capture Compare 3 Value */
#define PULSE4_VALUE (uint32_t)(PERIOD_VALUE*12.5/100) /* Capture Compare 4 Value */
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Timer handler declaration */
TIM_HandleTypeDef TimHandle;
/* Timer Output Compare Configuration Structure declaration */
TIM_OC_InitTypeDef sConfig;
/* Counter Prescaler value */
uint32_t uhPrescalerValue = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void Error_Handler(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
/* STM32F3xx HAL library initialization:
- Configure the Flash prefetch
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 64 MHz */
SystemClock_Config();
/* Configure LED3 */
BSP_LED_Init(LED3);
/* Compute the prescaler value to have TIM2 counter clock equal to 16000000 Hz */
uhPrescalerValue = (uint32_t)(SystemCoreClock / 16000000) - 1;
/*##-1- Configure the TIM peripheral #######################################*/
/* -----------------------------------------------------------------------
TIM2 Configuration: generate 4 PWM signals with 4 different duty cycles.
In this example TIM2 input clock (TIM2CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM2CLK = 2 * PCLK1
PCLK1 = HCLK / 2
=> TIM2CLK = HCLK = SystemCoreClock
To get TIM2 counter clock at 16 MHz, the prescaler is computed as follows:
Prescaler = (TIM2CLK / TIM2 counter clock) - 1
Prescaler = (SystemCoreClock /16 MHz) - 1
To get TIM2 output clock at 36 KHz, the period (ARR)) is computed as follows:
ARR = (TIM2 counter clock / TIM2 output clock) - 1
= 443
TIM2 Channel1 duty cycle = (TIM2_CCR1/ TIM2_ARR + 1)* 100 = 50%
TIM2 Channel2 duty cycle = (TIM2_CCR2/ TIM2_ARR + 1)* 100 = 37.5%
TIM2 Channel3 duty cycle = (TIM2_CCR3/ TIM2_ARR + 1)* 100 = 25%
TIM2 Channel4 duty cycle = (TIM2_CCR4/ TIM2_ARR + 1)* 100 = 12.5%
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f3xx.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
----------------------------------------------------------------------- */
/* Initialize TIMx peripheral as follows:
+ Prescaler = (SystemCoreClock / 16000000) - 1
+ Period = (444 - 1)
+ ClockDivision = 0
+ Counter direction = Up
*/
TimHandle.Instance = TIMx;
TimHandle.Init.Prescaler = uhPrescalerValue;
TimHandle.Init.Period = PERIOD_VALUE;
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimHandle.Init.RepetitionCounter = 0;
if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/*##-2- Configure the PWM channels #########################################*/
/* Common configuration for all channels */
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
/* Set the pulse value for channel 1 */
sConfig.Pulse = PULSE1_VALUE; // Comment le compilateur //sait de quelle "Channel" il s' agit???
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
/* Set the pulse value for channel 2 */
sConfig.Pulse = PULSE2_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_2) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
/* Set the pulse value for channel 3 */
sConfig.Pulse = PULSE3_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_3) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
/* Set the pulse value for channel 4 */
sConfig.Pulse = PULSE4_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_4) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
/*##-3- Start PWM signals generation #######################################*/
/* Start channel 1 */
// if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
// {
/* PWM Generation Error */
// Error_Handler();
// }
/* Start channel 2 */
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_2) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
/* Start channel 3 */
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_3) != HAL_OK)
{
/* PWM generation Error */
Error_Handler();
}
/* Start channel 4 */
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_4) != HAL_OK)
{
/* PWM generation Error */
Error_Handler();
}
while (1)
{
/*On commence les tests
* -Cablage:
* - TIM2_CH1 : PA.5 (Arduino A4) -->REDLED
- TIM2_CH2 : PA.1 (Arduino A1) -->GREENLED
- TIM2_CH3 : PA.2 (Arduino A7) -->BLUELED
- TIM2_CH4 : PA.3 (Arduino A2) -->
* */
/*On commnce par faire varier la led rouge
* avec les #define PULSEX_VALUE
* On les remplacera par des fonctions d' incrémentaions par la suite
* */
sConfig.Pulse = PULSE1_VALUE;
HAL_Delay(2000);
sConfig.Pulse = PULSE2_VALUE;
HAL_Delay(2000);
sConfig.Pulse = PULSE3_VALUE;
HAL_Delay(2000);
sConfig.Pulse = PULSE4_VALUE;
HAL_Delay(2000);
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
static void Error_Handler(void)
{
/* Turn LED3 on */
BSP_LED_On(LED3);
while (1)
{
}
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSI)
* SYSCLK(Hz) = 64000000
* HCLK(Hz) = 64000000
* AHB Prescaler = 1
* APB1 Prescaler = 2
* APB2 Prescaler = 1
* PLLMUL = RCC_PLL_MUL16 (16)
* Flash Latency(WS) = 2
* @param None
* @retval None
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* HSI Oscillator already ON after system reset, activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
{
/* Initialization Error */
while(1);
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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)
{
/* Initialization Error */
while(1);
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
Comment puis-je faire pour m' adresser directement à chaque canal? Je suis conscient que ma tentative n' est pas complète, qu'il faut:
Créer une fonction "change PWMx" recevant le paramètres du "Channel" concerné.
Cette fonction désactivera le timer,
lui donnera le nouveau rapport cyclique,
et redémarrera le timer.
La façon de procéder n' est peut-être pas la meilleur…
Si vous avez des pistes ou des remarques, n' hésitez pas à m' en faire part.
Merci d' avance.
Derniére modification le
#114 |
Bonjour,
Je ne comprend pas ton problème en fait …
Tu utilises :
1 | HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_2)
|
En détail :
HAL_TIM_PWM_ConfigChannel
: la fonction qui permet de configurer le mode PWM d'un canal d'un timer,TimHandle
: la structure qui contient les info du timer cible,sConfig
: la structure qui contient les info du canal cible,TIM_CHANNEL_2
: le canal cible,
Tout est là, le timer et sa config, le canal et sa config …
Qu'est ce qui pose problème avec le code de ton message ?
#115 |
Bonjour Skywodd,
c' est le fait que ce soit dans un if:
1 2 3 4 5 6 | sConfig.Pulse = PULSE1_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
|
ce que je ne comprends pas, c' est que l' appel de la fonction puisse se faire dans la condition du IF. Je vais essayer ça sans le IF, encore merci pour ta disponibilité.
Je te tiens au courant.
#116 |
ce que je ne comprends pas, c' est que l' appel de la fonction puisse se faire dans la condition du IF.
C'est tout à fait faisable
Tant que la fonction retourne une valeur qui peut être testé dans le if, ça passe.
Ici le but est de tester si le retour de la fonction est différent de HAL_OK
qui correspond à "pas d'erreur".
#117 |
En fait, pour ma compréhension,si je le formule de cette manière: le simple fait d' appeler la fonction dans un If, on rentre dans la fonction, et à sa sortie, on la teste pour voir si il n' y a pas d' erreurs. Fallait le savoir un truc pareil!! En tout cas c' est super pratique et intelligent comme façon de coder.
En fait, ça rejoint un peu ce que tu dis dans ton article "Pour l'amour du C, n'utilisez pas les fonctions atoi, atol, atof et dérivées", il faut sécuriser son code avec ce genre de test.
Du coups, j' ai réussi avec le IF:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | while (1)
{
/*On commence à jouer au con
* -Cablage:
* - TIM2_CH1 : PA.5 (Arduino A4) -->REDLED
- TIM2_CH2 : PA.1 (Arduino A1) -->GREENLED
- TIM2_CH3 : PA.2 (Arduino A7) -->BLUELED
- TIM2_CH4 : PA.3 (Arduino A2) -->
* */
/*On commnce par faire varier la led rouge
* avec les #define PULSEX_VALUE
* On les remplacera par des fonctions d' incrémentaions par la suite
* */
sConfig.Pulse = PULSE1_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
HAL_Delay(2000);
sConfig.Pulse = PULSE2_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
HAL_Delay(2000);
sConfig.Pulse = PULSE3_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
HAL_Delay(2000);
sConfig.Pulse = PULSE4_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
HAL_Delay(2000);
}
|
Et ça fonctionne!!
Pour la suite, je me pencherai un peu plus sur la fonction Error_Handler(), En gros si il y a erreur, la led 3 s' allume.
J' apprécie beaucoup ta pédagogies, ta patiences, et ta disponibilités, lorsque j' ai commencé avec les µC (Arduino, mais ça on s' en doute), je n' avais aucune connaissance, et grace à tes articles et tutos sur Skyduino, j' ai pu progresser sur pal mal de point, tu fais un très bon travail, grand merci à toi.
#118 |
En fait, pour ma compréhension,si je le formule de cette manière: le simple fait d' appeler la fonction dans un If, on rentre dans la fonction, et à sa sortie, on la teste pour voir si il n' y a pas d' erreurs.
C'est exactement ça.
Ça ce passe comme avec des parenthèses dans un calcul de math. Quand tu as 2 * (1 + 2)
, tu fais d'abord 1 + 2
, puis 2 * 3
. Ici tu fais d'abord l'appel à la fonction, qui te retourne une valeur, que tu test pour obtenir un booléen, et qui conditionne ensuite l'action du if.
Fallait le savoir un truc pareil!! En tout cas c' est super pratique et intelligent comme façon de coder.
Ce genre de petite astuce est très pratique et évite bien des soucis.
En fait, ça rejoint un peu ce que tu dis dans ton article "Pour l'amour du C, n'utilisez pas les fonctions atoi, atol, atof et dérivées", il faut sécuriser son code avec ce genre de test.
Toujours sécuriser son code. Un code non testé (dans tous les sens du terme) est un code cassé par design.
En informatique, la question n'est pas de savoir si un programme va planter, car il plantera toujours un jour, mais de savoir si le plantage sera bien détecté et géré (voir corrigé).
J' apprécie beaucoup ta pédagogies, ta patiences, et ta disponibilités, lorsque j' ai commencé avec les µC (Arduino, mais ça on s' en doute), je n' avais aucune connaissance, et grace à tes articles et tutos sur Skyduino, j' ai pu progresser sur pal mal de point, tu fais un très bon travail, grand merci à toi.
Et un grand merci à toi de me lire. Sans lecteur je n'irai pas bien loin
#119 |
Et un grand merci à toi de me lire. Sans lecteur je n'irai pas bien loin
C' est un plaisir
Bien maintenant que je peux jouer avec le rapport cyclique, il faut que je trouve le moyen de créer des couleurs défini et les affecter au rapport cyclique. J' utilise une banale diode RGB à cathode commune.
Je compte en faire un tutoriel, n' ayant pas encore de blog ou de site, je me demandais si ça t' ennuierais si je pouvais le poster sur ton site? J' ai aussi un astuce à partager sur l' utilisation des exemples "STM32Cube_FW_F3V1.4.0" avec SW4STM32 sous Linux, pour l' instant le fichier de configuration de SW4STM32 comportes des erreurs sur les chemins d' inclusions, je pense mettre ça dans la section Tutoriels et cours avec comme titre: [Astuce] Utilisé les exemples "STM32Cube_FW_Fxxx" avec SW4STM32 sous linux Si ça ne te dérange pas, bien sûre. La solution m' a été apporté sur le forum de openSTM32.
Derniére modification le
#120 |
Bien maintenant que je peux jouer avec le rapport cyclique, il faut que je trouve le moyen de créer des couleurs défini et les affecter au rapport cyclique. J' utilise une banale diode RGB à cathode commune.
par weetoz
N'importe quel logiciel de dessin (même paint) permet d'exporter une couleur en RGB888 hexadécimal.
Envoi simplement les valeurs R, G, B dans les registres PWM du timer et t'es bon
Si tu veux faire les choses bien, tu peux même passer les valeurs R, G, B dans une table de correction gamma. La correction gamma permet de corriger la non linéarité de l’œil par rapport à la perception de la luminosité. Ça évite d'avoir des couleurs délavées / blanchâtres.
J'ai prévu un tutoriel sur le sujet (mais en version Arduino), à la limite je vais le commencer aujourd'hui pour la publication du samedi (j'avais pas encore de sujet de prévu)
Je compte en faire un tutoriel, n' ayant pas encore de blog ou de site, je me demandais si ça t' ennuierais si je pouvais le poster sur ton site? (…) Si ça ne te dérange pas, bien sûre.
par weetoz
Aucun soucis, le forum dispose d'une section rien que pour ça, fait toi plaisir
Si tu veux faire des titres / sommaires, envoi moi un MP avant de publier ton tutoriel, je te débloquerai les limitations d'affichage.
#121 |
Merci Skywodd,
je vais commencer tout de suite à faire des essais pour l' utilisation de l' archive STM32Cube_FW_F3_V1.4.0.zip.
Désolé, je vais faire "péter" les notifs dans la soirée, normalement, pour ce petit article, je ne vais pas aller bien loin dans la présentation, juste quelque "Edit" sans trop abuser.
Pour le tuto, j' ai encore du boulot, j' y reviendrais…
#123 |
Si tu veux faire les choses bien, tu peux même passer les valeurs R, G, B dans une table de correction gamma. La correction gamma permet de corriger la non linéarité de l’œil par rapport à la perception de la luminosité. Ça évite d'avoir des couleurs délavées / blanchâtres.
Je vais essayer la table fourni par Adafruit, ça devrai nettement améliorer les choses.
N'importe quel logiciel de dessin (même paint) permet d'exporter une couleur en RGB888 hexadécimal. Envoi simplement les valeurs R, G, B dans les registres PWM du timer et t'es bon
En gros, envoyer directement les valeurs RGB dans HAL_TIM_PWM_ConfigChannel de chaque chaine?
Pour l' instant, je ne vois pas encore comment, il me parait plus aisé d' envoyer les valeurs 8bits dans chaque Canal TIM…
J'ai prévu un tutoriel sur le sujet (mais en version Arduino), à la limite je vais le commencer
aujourd'hui pour la publication du samedi (j'avais pas encore de sujet de prévu)
Du coup, je vais attendre que ce soit soit sortie, comme ça je ferais juste l' adaptation sur le STM32
avec une présentation des Timers et leurs quelques possibilités d' utilisations.
#124 |
Je vais essayer la table fourni par Adafruit, ça devrai nettement améliorer les choses.
par weetoz
Si tu as besoin d'une table de correction Gamma différente, je fourni un script de génération avec l'article de Samedi
En gros, envoyer directement les valeurs RGB dans HAL_TIM_PWM_ConfigChannel de chaque chaine?
Pour l' instant, je ne vois pas encore comment, il me parait plus aisé d' envoyer les valeurs 8bits dans chaque Canal TIM…
par weetoz
Tu changes simplement le "pulse" des canaux adéquats par les valeurs respectives R, G et B (en passant par la table de correction gamma si besoin).
Si c'est la valeur sur 8 bits qui pose problème : valeur_32b = valeur_8b << 24;
, valeur_24b = valeur_8b << 16;
, valeur_16b = valeur_8b << 8;
.
#125 |
Si tu as besoin d'une table de correction Gamma différente, je fourni un script de génération avec l'article de Samedi
J' suis impatient!!
Si t' as envie de rigoler, jusqu' à ce matin, j' envoyais mes valeurs en pourcentage…
bon, j' ai bu ma tisane et sa va mieux, pour exemple:
avant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void Blue_Fade_Half_Up(void){ // de 50% à 100%
int i;
for (i = 50; i <= 100; i++) {
sConfig.Pulse = gamma[i];
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_3) != HAL_OK)
{
//Configuration Error
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_3) != HAL_OK)
{
// PWM Generation Error
Error_Handler();
}
HAL_Delay(delaisBoucleUp/*-(rapportCyclique*2)*/);
}Blue_Full();HAL_Delay(delaisBoucleUp);
}
|
après:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void Blue_Fade_Half_Up(void){
int i;
for (i = 127; i <= 255; i++) {
sConfig.Pulse = gamma[i];
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_3) != HAL_OK)
{
//Configuration Error
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_3) != HAL_OK)
{
// PWM Generation Error
Error_Handler();
}
HAL_Delay(delaisBoucleUp/*-(rapportCyclique*2)*/);
}Blue_Full();HAL_Delay(delaisBoucleUp);
}
|
Bon, faut que je retape toutes mes 'petites' fonctions…
Bonne journée.
[Edite]
Je ne me suis pas pris la tête, à manipuler les champs de bits, j' ai déclaré mon tableau en 32 bits,
je sais, niveau optimisation du code, je repasserais.
Derniére modification le