Documente Academic
Documente Profesional
Documente Cultură
PLAN
*les registres
* exemple
*les registres
* exemple
* exemple
1
PARTIE VII : LUSART
* interface de lUSART
PROJET GLOBALE
2
3
4
Typedef struct
{
Typedef struct
Typedef struct
uint32_t registre1;
{
{
uint16_t registre2;
uint32_t registre1; Typedef struct
uint32_t registre1;
uint16_t registre3;
uint16_t registre2; {
uint16_t registre2;
} I2S_struct_name
uint16_t registre3; uint32_t registre1;
uint16_t registre3;
} USART_struct_name uint16_t registre2;
} DAC_struct_name
I2S uint16_t registre3;
Typedef struct
USART GPIO uint32_t registre4;
{ DAC } GPIO_struct_name
uint32_t registre1;
Typedef struct
uint16_t registre2;
{
uint16_t registreN;
STM32F4
ADC I2C
uint32_t registre1;
} ADC_struct_name
uint16_t registre2;
} I2C_struct_name
{ SPI
uint32_t registre1;
TIMER CAN
Typedef struct
uint16_t registre2; Typedef struct {
uint16_t registreN;
{ uint32_t registre1;
} TIMER_struct_name
uint32_t registre1; uint16_t registre2;
} CAN_struct_name 5
Prenons titre dexemple la structure de configuration de lhorloge (The Clock Configuration Register : RCC)
Remarque: Cette structure contient un ensemble de registres dont laccs direct se fait via un pointeur intitul RCC
6
#define RCC ((RCC_TypeDef *) RCC_BASE) LINE 1186 (du fichier STM32F4xx.h)
Chaque registre est cod sur 4 octets (32 bits) ou sur 2 octets (16 bits ). Laccs direct chaque registre de la RAM se fait via un pointeur.
Chaque registre est considr comme un tableau 16 ou 32 cases mmoires (chaque bit est une case mmoire). Chaque registre est une srie de
4 ou 2 octets dont chaquun (octet) lui correspond une seule et unique adresse dans la RAM. Ladresse dun registre est ladresse du premier
octet de ce registre. Par exemple, le registre RCC_CR contient 4 octets ayant les adresses suivantes : 0X42003800, 0X42003801, 0X42003802,
0X42003803
7
Chaque interface du microcontrleur est un circuit dont le fonctionnement dpendra de la position des switchers. Chaque switcher est pilot par
un bit appartenant un registre bien dtermin. Ces registres appartiennent la RAM du microcontrleur.
8
Ce principe est le mme pour nimporte quelle interface du microcontrleur : ADC, DAC, TIMER, I2C,SPI, etc
Vcc
Clock
PIN
Opration logique :
BITWISE AND :
9
BITWISE OR
BITWISE XOR
BITWISE NOT
10
BIT SHIFT OPERATORS
Assignment Operators
x = x + 7 equivalent x += 7
x = x | 3 equivalent x |= 3
x = x & 7 equivalent x &= 7
11
Programmation ARM
Prenons le cas dune structure contenant lensemble dun Convertisseur ADC. La manipulation de ses registres se fait via un pointeur intitul
pt_ADC. Parmi ces registres choisissons le registreSR et le registre DR.
If((pt_ADC->SR&0x02)==0)
{
Pt_ADC->DR=a;
}
Programmation classique
If(SR&0x02==0)
{
DR=a;
}
for(int i=0;i<20;i++)
{
Pt_ADC->DR+=1;
}
Programmation classique
for(int i=0;i<20;i++)
{
DR+=1;
}
12
Ajouter dautre exemple while()
Dclarations tableaux ;
int main(void)
{
Fonction_de_configuration1() ;
Fonction_de_configuration2() ;
Fonction_de_configuration3() ;
While(1)
{
Droulement_systeme() ;
}
13
STM32F407 Clocks
1. Introduction
The STM32F407 micro-controller is capable of interfacing to a large range of peripheral devices or sub-systems. These peripherals all have different
protocols and requirements. To satisfy the clock requirements for these peripheral devices the STM32F407 includes a very flexible clocking
arrangement.
Following reset the High Speed Internal Clock (HSI) will be selected. By default this clock will also be the clock to the AHB (Advanced High Speed
Bus), and the peripheral buses APBx (Advanced Peripheral Bus).
14
In contrast to many microcontrollers that have peripherals or subsystems where the clock signals are continuously active, to conserve power the
STM32F407 does not. It will therefore be the responsibility of the programmer to enable the clock to those subsystems and if necessary generate the
appropriate bus frequencies. It will be necessary to understand the requirements of the chosen peripherals as part of configuring the micro-controller
clock circuitry.
Setting the system clock: That is select HSI, HSE or the PLL as the system clock.
Setting the prescalers to provide the required bus frequencies.
The STM32F407 microcontroller system clock can come from one of three sources:
The clock control register RCC_CR will be used to enable and select the clock source while the clock configuration register RCC_CFGR will be used to
determine the final bus frequencies
Conclusion:
RCC_CR register will be used to enable and select the clock source
15
Notes:
The ARM also includes a low speed internal clock (LSI) and low speed external clock (LSE).
The LSI clock is used as part of the watch dog timer.
The LSE is used as a clock for the ARM real time clock (RTC)
The input to the PLL will be either HSI or HSE
For the STM32F407 used in the Discovery board HSI = 16MHz.
For the STM32F407 used in the Discovery board HSE = 8MHz.
The clock source is determined by the registers RCC_CR and RCC_CFGR shown below. At reset for both the STM32F107 and STM32F407 the CR (Control
Register) is 0x0000 XX83. The "3" indicates the internal 16 MHz RC oscillator (HSI) is enabled and stable. The HSE and PLL are not enabled.
16
The Clock Configuration Register: RCC_CFG
Following reset the CFGR (Configuration Register) is cleared indicating the HSI (Low Speed Internal Clock) is selected. ie RCC_CFGR:SW[1:0] = 00
SW= 00 HSI Clock selected (default value following reset). SW =01 HSE selected. SW = 10 PLL selected. SW=11 Not allowed.
After reset the internal clock (HSI) is enabled. To use the external clock it must be enabled using bit 16 in the control register and then the firmware must wait
until the hardware indicates it is ready (stable). Possible code will be:
17
Note: The SWS bits in the CFGR may be monitored to confirm which clock is being used.
Note: The STM32F407 contains a second similar PLL for the I2S (PLLI2S)
The clock source for the PLL is set using the PLLSRC bit while the PLL frequency is set by programming the PLLM, PLLN and PLLP bits in the phase lock
loop configuration register (RCC_PLLCFGR). (Reset value: 0x2400 3010)
18
This register is used to configure the PLL clock output according to the formulas:
19
Notes:
As illustrated the three bus signals (AHB, APB1 and APB2) are derived from the system clock as illustrated (Figure repeated for convenience).
The frequencies are determined by programming the configuration register (RCC_CFGR). (Figure repeated for convenience)
20
SW= 00 HSI Clock selected (default value following reset). SW =01 HSE selected. SW = 10 PLL selected. SW=11 Not allowed.
21
STM32F407 Example: Assuming that the peripheral buses are to operate at their maximum frequency then with a system clock of 168 Mhz the APB1
pre-scaler must divide the clock output of the high performance bus (HCLK) by 4. The code will be:
22
6. Peripheral Clocks for the STM Microcontrollers
With the STM devices the peripheral devices are associated with an internal buse. (APB1 and APB2). To use the the peripheral device it must be
enabled/attached to the appropriate bus. The user has the choice of setting the frequency of the individual buses. When using a peripheral device the user will
need to
The basic clock circuitry for the ARM microcontroller is shown below.
23
6.1.STM32F407 Peripheral Clock Enables
With the STM32F407 as illustrated below the peripheral clock is associated with AHB1, APB1 or APB2. (Advanced High speed Bus 1, Advanced Peripheral
Bus 1 or Advanced Peripheral Bus 2):
Figure: STM32F407 AHB1 high speed bus clock enable register (RCC_AHB1ENR)
24
Figure: STM32F407 APB2 peripheral clock enable register (RCC_APB2ENR)
1. The enable register presented in the previous section. To enable a clock a bit in the enable register is set. Clearing the bit will not result in any
action.
2. The reset register where setting a bit will clear the chosen clock. The reset registers are a set of registers that correspond to the enable
registers. (RCC_AHB1RSTR, RCC_APB1RSTR and RCC_APB2RSTR)
The circuitry is illustrated in the diagram below. To enable a clock the corresponding bit in the enable register is set while to reset/disable the same bit in the
reset register is set.
25
FIGURE: ARCHITECTURE OF THE STM32F407 CLOCK
26
Figure: REGISTERS OF THE GLOBAL STM32F407 CLOCK
27
28
LES GPIOS
I. Prsentation
Le microcontrleur STM32F407 dispose de 9 ports dentres/sorties (dnomms GPIOA GPIOI), partags avec dautres priphriques. A chaque port I/O
est associ quatre registres de configuration 32 bits (GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR et GPIOx_PUPDR), deux registres de donnes
32bits (GPIOx_IDR and GPIOx_ODR), un register de 32bits set/reset (GPIOx_BSRR), un registre 32bits de verrouillage (GPIOx_LCKR) et deux registres 32
bits pour les fonctions secondaire (Alternate function) (GPIOx_AFRH and GPIOx_AFRL).
29
III. Input floating/pull up/Pull down configurations
30
IV. OUTPUT CONFIGURATION
31
V. ALTERNATE FUNCTION CONFIGURATION
as alternate function:
32
VI. ANALOG CONGIGURATION
as analog configuration:
Note: In the analog configuration, the I/O pins cannot be 5 Volt tolerant. - analog operating voltage (VDDA) max at 3.6V
33
VII. GLOBAL GPIO CONFIGURATION (ALL CASES)
34
LES REGISTRES DE CONFIGURATIONS DUN GPIO :
Les diffrents registres utiliss pour configurer un GPIO sont regroups dans la structure ci-dessous intitule GPIO_TypeDef
typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
} GPIO_TypeDef;
Chacun des 9 GPIO ( GPIOA GPIOI) utilise la mme structure mais avec des pointeurs diffrents :
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE)
35
LES REGISTRES
36
GPIO port output speed register (GPIOx_OSPEEDR) (x = A..I)
37
GPIO port input data register (GPIOx_IDR) (x = A..I)
38
0: No action on the corresponding ODRx bit
1: Resets the corresponding ODRx bit
Note: If both BSx and BRx are set, BSx has priority.
Bits 15:0 BSy: Port x set bit y (y= 0..15)
These bits are write-only and can be accessed in word, half-word or byte mode. A read to
these bits returns the value 0x0000.
0: No action on the corresponding ODRx bit
1: Sets the corresponding ODRx bit
39
Thus part of configuring GPIOD will be the code:
40
Thus part of configuring GPIOB will be the code:
41
Thus part of configuring GPIOA will be the code:
42
PULL_UP /PULL_DOWN:
43
44
APPLICATIONS
45
#include "stm32f4xx.h"
void System_Init()
{
RCC->AHB1ENR = 0x00000001; //clock to GPIOA
RCC->AHB1ENR |= 1<<3; //Clocks for GPIOD
}
int main (void)
{
System_Init();
while (1)
{
if (GPIOA->IDR & 0x0001)
{
GPIOD->ODR = 0xF000; //turn LEDs on
}
else
{
GPIOD->ODR = 0; //LEDs off
}
}
}
Dboguer le programme ci-dessus et vrifier le contenu des registres suivants : AHB1ENR appartenant la structure RCC_TypeDef, (MODER ,PUPDR
ODR et IDR)appartenant la structure GPIO_TypeDef
46
APPLICATION 2: Clignotement de 4 leds (PD12, PD13, PD14, PD15)
47
#include "stm32f4xx.h"
}
int main (void)
{
cofiguration();
while (1)
{
GPIOD->ODR = 0xF000; //4 LEDs (PD12 PD13 PD14 PD15) : on
Delay(0xFFFFF);
GPIOD->ODR = 0x0000; //4 LEDs (PD12 PD13 PD14 PD15) : off
Delay(0xFFFFF);
}
}
Dboguer le programme ci-dessus et vrifier le contenu des registres suivants : AHB1ENR appartenant la structure RCC_TypeDef, (MODER ,PUPDR
ODR)appartenant la structure GPIO_TypeDef
48
Application 3: Registre dcalage 8 bits
49
#include "stm32f4xx.h"
__IO uint32_t i;
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{}
}
void configuration()
{
Dboguer le programme ci-dessus et vrifier le contenu des registres suivants : AHB1ENR appartenant la structure RCC_TypeDef, (MODER ,PUPDR
ODR)appartenant la structure GPIO_TypeDef
50
APPLICATION 4 : Dcalage droite et gauche progressif
But : Lclairage progressif des 7 leds (une fois droite et une fois gauche) par mise en uvre du BITSHIFT <<
51
#include "stm32f4xx.h"
__IO uint32_t i;
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{}
}
void configuration()
{
}
int main (void)
{
configuration();
while (1)
{
for(i=0;i<8;i++)
{
GPIOD->ODR=1<<i;
Delay(0xFFFFF);
}
for(i=6;i>0;i--)
{
GPIOD->ODR=1<<i;
Delay(0xFFFFF);
}
}
}
Dboguer le programme ci-dessus et vrifier le contenu des registres suivants : AHB1ENR appartenant la structure RCC_TypeDef, (MODER ,PUPDR
ODR)appartenant la structure GPIO_TypeDef
52
Application 5: Principe de masquage
But :
Le but principal de cette application est la manipulation de toutes les oprations logiques en embarqu (BITWISE NOT, BIT SHIFT, BITWISE
AND, BITWISE OR, Assignment Operators)
Ralisation :
Soit le montage suivant
53
#include "stm32f4xx.h"
__IO uint32_t i;
void Delay(__IO uint32_t nCount)
{
while(nCount--);
}
void configuration()
{
RCC->AHB1ENR = 1<<3; //Clocks for GPIOD
GPIOD->MODER = 0x55555555; //PORTD: PINs 0 15 are configured as output
GPIOD->PUPDR=0x55555555; //Actvate pull-up for each pin 0=> 15
}
Dboguer le programme ci-dessus et vrifier le contenu des registres suivants : AHB1ENR appartenant la structure RCC_TypeDef, MODER
appartenant la structure GPIO_Typedef et PUPDR appartenant la structure GPIO_TypeDef
54
APPLICATION 6 : MISE EN UVRE DES RESISTANCES DE PULL-UP ET PULL-DOWN( INPUT)
Dans cette application, on va activer les rsistances internes PULL_DOWN correspondant au PORTC ainsi que les rsistances internes
PULL_UP correspondant au PORTD
55
#include "stm32f4xx.h"
__IO uint32_t i;
void Delay(__IO uint32_t nCount)
{
while(nCount--);
}
void configuration()
{
RCC->AHB1ENR = 1<<3; //Clocks for GPIOD
RCC->AHB1ENR|=0x4; // Clocks for GPIOC
}
int main (void)
{
configuration();
while (1)
{
if((GPIOC->IDR&0x4)==0x4)
{
GPIOD->ODR=0xF000;
Delay(0xFFFFF);
}
else
{
GPIOD->ODR=0x000;
}
56
GPIOD->ODR=0x0000;
Delay(0xFFFFF);
GPIOD->ODR|=0xF0;
Delay(0xFFFFF);
GPIOD->ODR&=0x00;
Delay(0xFFFFF);
GPIOD->ODR|=0x0F;
Delay(0xFFFFF);
GPIOD->ODR&=0xE;
Delay(0xFFFFF);
GPIOD->ODR&=0xC;
Delay(0xFFFFF);
GPIOD->ODR&=0x8;
Delay(0xFFFFF);
GPIOD->ODR&=0x0;
Delay(0xFFFFF);
GPIOD->ODR=0x00FF;
Delay(0xFFFFF);
}
}
57
INTERRUPTION EXTERNE SUR LES GPIO
typedef struct
{
__IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */
__IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */
__IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */
__IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */
__IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */
__IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */
} EXTI_TypeDef;
typedef struct
{
__IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */
__IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */
__IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */
uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */
__IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */
} SYSCFG_TypeDef;
58
SYSCFG external interrupt configuration register 1 (SYSCFG_EXTICR1)
59
SYSCFG external interrupt configuration register 2 (SYSCFG_EXTICR2)
60
SYSCFG external interrupt configuration register 3 (SYSCFG_EXTICR3)
61
SYSCFG external interrupt configuration register 4 (SYSCFG_EXTICR4)
62
Interrupt mask register (EXTI_IMR)
63
Event mask register (EXTI_EMR)
64
Rising trigger selection register (EXTI_RTSR)
65
Falling trigger selection register (EXTI_FTSR)
66
Software interrupt event register (EXTI_SWIER)
67
Pending register (EXTI_PR)
68
69
LE TIMER (compteur)
Principe
*Le but principal dun TIMER est de raliser une temporisation. Un Compteur s'incrmente chaque front montant du signal qui lui est applique.
Lorsque le compteur dpasse la valeur maximale qu'il peut contenir (dborde) (par exemple : 256 pour un compteur 8 bits), un drapeau (flag en anglais) se
lve.
Ce drapeau a pour but d'indiquer au programme que le compteur a dbord (c'est a dire qu'il a fini de compter).
De la mme manire que pour la boite aux lettres, c'est au programme de rebaisser le drapeau pour recommencer un cycle de comptage (ca ne se fait pas tout
seul !).
* Un Timer doit pouvoir compter un temps dfini par le programme (par exemple 1ms, 10ms, 50ms, etc).
Pour cela, 2 paramtres peuvent tre modifies :
* La frquence du signal applique au compteur Le compteur s'incrmentera ainsi plus ou moins vite.
*Le nombre d'impulsions compter
Remarque : on peut donc faire dbuter le compteur d'une valeur non nulle pour rduire le temps de comptage.
La frquence du signal appliqu au compteur peut tre modifie via un pr-diviseur (prescaler en anglais) plac en amont du signal source
70
Exemple : pour compter 4 fois moins vite
71
STM32F4 timers
72
Le timer est compos de :
- Contrleur de dclenchement
- Un prdivisuer (Prescaler : PSC)
- Un compteur 16 bits (CNT)
- Un registre dauto-rechargement (AutoReload Register :ARR)
- Un module capture/Comparaison
Le prdiviseur divise la frquence dentre par une valeur comprise entre 1 et 65536. Le compteur sincrmente jusquau continu du registre
ARR ; repasse zro et gnre un vnement de mise jour (Update Event : UEV) et positionne le bit UIF.
Les diffrents registres utiliss pour configurer nimporte quel TIMER sont regroups dans la structure ci-dessous intitule TIM_TypeDef
typedef struct
{
__IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
uint16_t RESERVED0; /*!< Reserved, 0x02 */
__IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
uint16_t RESERVED1; /*!< Reserved, 0x06 */
__IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
uint16_t RESERVED2; /*!< Reserved, 0x0A */
__IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
uint16_t RESERVED3; /*!< Reserved, 0x0E */
__IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */
uint16_t RESERVED4; /*!< Reserved, 0x12 */
73
__IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
uint16_t RESERVED5; /*!< Reserved, 0x16 */
__IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
uint16_t RESERVED6; /*!< Reserved, 0x1A */
__IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
uint16_t RESERVED7; /*!< Reserved, 0x1E */
__IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
uint16_t RESERVED8; /*!< Reserved, 0x22 */
__IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
__IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
uint16_t RESERVED9; /*!< Reserved, 0x2A */
__IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
__IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
uint16_t RESERVED10; /*!< Reserved, 0x32 */
__IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
__IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
__IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
__IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
__IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
uint16_t RESERVED11; /*!< Reserved, 0x46 */
__IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
uint16_t RESERVED12; /*!< Reserved, 0x4A */
__IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
uint16_t RESERVED13; /*!< Reserved, 0x4E */
__IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */
uint16_t RESERVED14; /*!< Reserved, 0x52 */
} TIM_TypeDef;
Chacun des 14 TIMERS ( TIM1 TIM14) utilise la mme structure mais avec des pointeurs diffrents :
#define TIM1 ((TIM_TypeDef *) TIM1_BASE)
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
#define TIM4 ((TIM_TypeDef *) TIM4_BASE)
#define TIM5 ((TIM_TypeDef *) TIM5_BASE)
#define TIM6 ((TIM_TypeDef *) TIM6_BASE)
#define TIM7 ((TIM_TypeDef *) TIM7_BASE)
#define TIM8 ((TIM_TypeDef *) TIM8_BASE)
#define TIM9 ((TIM_TypeDef *) TIM9_BASE)
74
#define TIM10 ((TIM_TypeDef *) TIM10_BASE)
#define TIM11 ((TIM_TypeDef *) TIM11_BASE)
#define TIM12 ((TIM_TypeDef *) TIM12_BASE)
#define TIM13 ((TIM_TypeDef *) TIM13_BASE)
#define TIM14 ((TIM_TypeDef *) TIM14_BASE)
TIMx_PSC : prescaler
75
Bits 6:4 Reserved, must be kept at reset value.
76
TIMx_SR: status register
77
1: Re-initializes the timer counter and generates an update of the registers.
TIMx_CNT : counter
78
La notion dinterruption
Pour simplifier la comprhension dune interruption jai choisi larchitecture adapte par un microcontrleur PIC
79
La lever automatique du drapeau peut tre exploit de 2 manires :
Soit on lexploite pour raliser une tache lintrieur du programme principal (main) (UIE=0 quivalent TIMx->DIER = 0x00000).
80
81
Soit on lexploite pour raliser une interruption lextrieur du programme principal (main) (UIE=1 quivalent TIMx->DIER = 0x0001).
Remarque : Quand le timer dborde ARR 0x00 le flag se met automatiquement 1 (UIF=1). Ce flag restera toujours 1 tant quil nest pas
remis 0 (softwarement parlant).
82
Count-up mode overflow if TIMx_CNT reaches TIMx_ARR
On overflow event, UIF flag is set and TIMx_CNT resets to 0.
If UIE= 1 (update interrupt enabled), interrupt signal is sent to NVIC
83
84
Application :
Dans ces applications on aura recours aux registres suivant :
RCC_AHB1ENR
GPIOx_MODER
85
RCC_APB1ENR
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#define PLL_M 8
#define PLL_N 336
#define PLL_P 2
#define PLL_Q 7
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
86
}
void clock_config1()
{
RCC->CFGR|=RCC_CFGR_SW_PLL;
// Wait until the main PLL is used as system clock source.
while((RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_PLL);
}
int main()
{
clock_config();
RCC->AHB1ENR |= 0x00000008; // Enable GPIOD clock
GPIOD->MODER |= 0x55<<24; //Bits 12..15 are output
RCC->APB1ENR |= 0x00000010; // Enable TIM6 clock
TIM6->PSC = 41999; // Set prescaler to 41999
87
TIM6->ARR = 5999; // Set auto-reload to 5999
TIM6->CR1 &=0x0000; // Multiple pulse mode TIM6->CR1 &=~TIM_CR1_OPM;
TIM6->EGR |= 0x01; // Force update
TIM6->SR &= 0x0000; // Clear the update flag
TIM6->DIER |= 0x0001; // Enable interrupt on update event
NVIC_EnableIRQ(TIM6_DAC_IRQn); // Enable TIM6 IRQ
TIM6->CR1 |= 0x0001; // Enable TIM6 counter
while(1)
{
}
}
void TIM6_DAC_IRQHandler()
{
if((TIM6->SR & 0x0001) != 0)// If update flag is set
{
GPIOD->ODR |= 0x8000; // Set D15 high
Delay(0xFFFFF);
GPIOD->ODR &= 0x0;
}
APPLICATION2 : Clignotement dune LED par lusage dinterruption dun TIMER TIM6
#include "stm32f4xx.h"
int ncount1;
88
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{}
}
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
int main()
{
clock_config();
RCC->AHB1ENR |= 0x00000008; // Enable GPIOD clock
GPIOD->MODER |= 0x55<<24; //Bits 12..15 are output
RCC->APB1ENR |= 0x00000010; // Enable TIM6 clock
TIM6->PSC = 41999; // Set prescaler to 41999
TIM6->ARR = 59; // Set auto-reload to 5999
TIM6->CR1 &=0x0000; // Multiple pulse mode TIM6->CR1 &=~TIM_CR1_OPM;
TIM6->EGR |= 0x01; // Force update
TIM6->SR = 0x0000; // Clear the update flag
TIM6->DIER |= 0x0001; // Enable interrupt on update event
NVIC_EnableIRQ(TIM6_DAC_IRQn); // Enable TIM6 IRQ
TIM6->CR1 |= 0x0001; // Enable TIM6 counter
while(1)
{
}
}
void TIM6_DAC_IRQHandler()
{
89
if((TIM6->SR & 0x0001) != 0)// If update flag is set
{
ncount1++;
if(ncount1==1)
{
GPIOD->ODR |= 0x8000; // Set D15 high
}
if(ncount1==2)
{
GPIOD->ODR &= 0x0; // Set D15 high
ncount1=0;
}
}
90
APPLICATION 3: Machine dtat avec mise en jeu dinterruption
91
#include "stm32f4xx.h"
int ncount1;
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
92
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
}
int main()
{
while(1)
{
}
}
void TIM6_DAC_IRQHandler()
{
if((TIM6->SR & 0x0001) != 0)// If update flag is set
{
ncount1++;
if(ncount1==1)
{
GPIOD->ODR |= 0x8000; // Set D15 high
93
}
if(ncount1==2)
{
GPIOD->ODR = 0x4000; // Set D14 high
}
if(ncount1==3)
{
GPIOD->ODR = 0x2000; // Set D13 high
}
if(ncount1==4)
{
GPIOD->ODR = 0x1000; // Set D12 high
}
if(ncount1==5)
{
GPIOD->ODR = 0x0000; // Set D15 high
ncount1=0;
}
}
94
APPLICATION4 : Machine dtat avec mise en jeu du FLAG (sans interruption)
95
#include "stm32f4xx.h"
int ncount1;
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
96
while (!(RCC->CR & (1<<17))); //wait until HSE ready
int main()
{
clock_config(); //Freq_source=HSE
RCC->AHB1ENR = 0x00000008; // Enable GPIOD clock
GPIOD->MODER = 0x55<<24; // PD12 PD13 PD14 PD15 are output
RCC->APB1ENR = 0x00000010; // Enable TIM6 clock
TIM6->PSC = 41999; // Set prescaler to 41999 Freq_TIMER=HSE/41999
TIM6->ARR = 59; // Set auto-reload to 59 Periode_TIMER= (1/Freq_TIMER)x59
TIM6->SR = 0x0000; // Clear the update flag (UIF=0)
TIM6->DIER = 0x0000; // Disable interrupt
TIM6->CR1= 0x0001; // Enable TIM6 counter
while(1)
{
if((TIM6->SR & 0x0001) != 0)// If update flag is set (UIF=1)
{
ncount1++;
if(ncount1==1)
{
GPIOD->ODR |= 0x8000; // Set D15 high
}
if(ncount1==2)
{
GPIOD->ODR = 0x4000; // Set D14 high
}
if(ncount1==3)
{
GPIOD->ODR = 0x2000; // Set D13 high
}
if(ncount1==4)
{
GPIOD->ODR = 0x1000; // Set D12 high
97
}
if(ncount1==5)
{
GPIOD->ODR = 0x0000; // Set D15 high
ncount1=0;
}
TIM6->SR &= 0x0000; // Interrupt has been handled (UIF=0)
}
}
}
Remarque: Le dclenchement du FLAG est en liaison directe avec UDIS, URS UG (par exemple si UDIS=1 UIF=0 meme si le compteur
dborde)
La table ci-dessous, montre lensemble des PINs quon peut attribuer chaque TIMER caractris aussi par 4 chaines aux choix . On peut
slectionner 3 pins aux grand maximun pour chaque chaine.
98
99
100
LA MODULATION LARGEUR IMPULSION
typedef struct
{
101
__IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
uint16_t RESERVED0; /*!< Reserved, 0x02 */
__IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
uint16_t RESERVED1; /*!< Reserved, 0x06 */
__IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
uint16_t RESERVED2; /*!< Reserved, 0x0A */
__IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
uint16_t RESERVED3; /*!< Reserved, 0x0E */
__IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */
uint16_t RESERVED4; /*!< Reserved, 0x12 */
__IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
uint16_t RESERVED5; /*!< Reserved, 0x16 */
__IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
uint16_t RESERVED6; /*!< Reserved, 0x1A */
__IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
uint16_t RESERVED7; /*!< Reserved, 0x1E */
__IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
uint16_t RESERVED8; /*!< Reserved, 0x22 */
__IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
__IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
uint16_t RESERVED9; /*!< Reserved, 0x2A */
__IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
__IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
uint16_t RESERVED10; /*!< Reserved, 0x32 */
__IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
__IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
__IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
__IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
__IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
uint16_t RESERVED11; /*!< Reserved, 0x46 */
__IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
uint16_t RESERVED12; /*!< Reserved, 0x4A */
__IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
uint16_t RESERVED13; /*!< Reserved, 0x4E */
__IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */
uint16_t RESERVED14; /*!< Reserved, 0x52 */
} TIM_TypeDef;
102
Cette structure contient lensemble des registres qui nous permettra de configurer ce TIMER. La manipulation de ces registres se fait via un
pointeur intitul TIM3 (#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
Chaque PWM est engendr par un TIMER. En mode PWM, le priode est dfinie par le contenu du registre TIMx_ARR et le rapport cyclique
par le contenu du registre TIMx_CCR1. La sortie du comparateur OC1REF est mise au niveau haut lorsque le continu du compteur est infrieur
au continu du comparateur TIMx_CNT < TIMx_CCR1, et place au niveau bas dans le cas contraire
103
Applications de la MLI :
Dans ces applications on aura recours aux registres suivant :
RCC_AHB1ENR
RCC_APB1ENR
104
GPIOx_MODER
105
GPIO alternate function low register (GPIOx_AFRL) (x = A..I)
106
Output compare mode
Bit 15 OC2CE: Output compare 2 clear enable
107
1: Preload register on TIMx_CCR1 enabled. Read/Write operations access the preload register. TIMx_CCR1 preload value is loaded in the active register at each update event.
Note: 1: These bits can not be modified as long as LOCK level 3 has been programmed (LOCK bits in TIMx_BDTR register) and CC1S=00 (the channel is configured in output).
2: The PWM mode can be used without validating the preload register only in onepulse mode (OPM bit set in TIMx_CR1 register). Else the behavior is not guaranteed.
108
0110: fSAMPLING=fDTS/4, N=6
0111: fSAMPLING=fDTS/4, N=8
1000: fSAMPLING=fDTS/8, N=6
1001: fSAMPLING=fDTS/8, N=8
1010: fSAMPLING=fDTS/16, N=5
1011: fSAMPLING=fDTS/16, N=6
1100: fSAMPLING=fDTS/16, N=8
1101: fSAMPLING=fDTS/32, N=5
1110: fSAMPLING=fDTS/32, N=6
1111: fSAMPLING=fDTS/32, N=8
109
Bit 11 OC4PE: Output compare 4 preload enable
This bit-field defines the direction of the channel (input/output) as well as the used input.
00: CC4 channel is configured as output
01: CC4 channel is configured as input, IC4 is mapped on TI4
10: CC4 channel is configured as input, IC4 is mapped on TI3
11: CC4 channel is configured as input, IC4 is mapped on TRC. This mode is working only if an internal trigger input is selected through TS bit (TIMx_SMCR register)
Note: CC4S bits are writable only when the channel is OFF (CC4E = 0 in TIMx_CCER).
This bit-field defines the direction of the channel (input/output) as well as the used input.
00: CC3 channel is configured as output
01: CC3 channel is configured as input, IC3 is mapped on TI3
10: CC3 channel is configured as input, IC3 is mapped on TI4
11: CC3 channel is configured as input, IC3 is mapped on TRC. This mode is working only if
an internal trigger input is selected through TS bit (TIMx_SMCR register)
Note: CC3S bits are writable only when the channel is OFF (CC3E = 0 in TIMx_CCER).
110
Bits 7:4 IC3F: Input capture 3 filter
Bits 3:2 IC3PSC: Input capture 3 prescaler
Bits 1:0 CC3S: Capture/Compare 3 selection
This bit-field defines the direction of the channel (input/output) as well as the used input.
00: CC3 channel is configured as output
01: CC3 channel is configured as input, IC3 is mapped on TI3
10: CC3 channel is configured as input, IC3 is mapped on TI4
11: CC3 channel is configured as input, IC3 is mapped on TRC. This mode is working only if
an internal trigger input is selected through TS bit (TIMx_SMCR register)
Note: CC3S bits are writable only when the channel is OFF (CC3E = 0 in TIMx_CCER).
111
Bit 6 Reserved, must be kept at reset value.
112
1: Capture enabled
Bits 31:16 CCR1[31:16]: High Capture/Compare 1 value (on TIM2 and TIM5).
Bits 15:0 CCR1[15:0]: Low Capture/Compare 1 value
If channel CC1 is configured as output:
CCR1 is the value to be loaded in the actual capture/compare 1 register (preload value).
It is loaded permanently if the preload feature is not selected in the TIMx_CCMR1 register (bit OC1PE). Else the preload value is copied in the active capture/compare 1
register when an update event occurs.
The active capture/compare register contains the value to be compared to the counter TIMx_CNT and signaled on OC1 output.
If channel CC1is configured as input:
CCR1 is the counter value transferred by the last input capture 1 event (IC1).
113
TIMx capture/compare register 2 (TIMx_CCR2)
Bits 31:16 CCR2[31:16]: High Capture/Compare 2 value (on TIM2 and TIM5).
Bits 15:0 CCR2[15:0]: Low Capture/Compare 2 value
If channel CC2 is configured as output:
CCR2 is the value to be loaded in the actual capture/compare 2 register (preload value).
It is loaded permanently if the preload feature is not selected in the TIMx_CCMR register (bit OC2PE). Else the preload value is copied in the active capture/compare 2 register
when an update event occurs.
The active capture/compare register contains the value to be compared to the counter TIMx_CNT and signalled on OC2 output.
If channel CC2 is configured as input:
CCR2 is the counter value transferred by the last input capture 2 event (IC2).
Bits 31:16 CCR3[31:16]: High Capture/Compare 3 value (on TIM2 and TIM5).
Bits 15:0 CCR3[15:0]: Low Capture/Compare value
If channel CC3 is configured as output:
CCR3 is the value to be loaded in the actual capture/compare 3 register (preload value).
It is loaded permanently if the preload feature is not selected in the TIMx_CCMR register (bit OC3PE). Else the preload value is copied in the active capture/compare 3 register
when an update event occurs.
114
The active capture/compare register contains the value to be compared to the counter TIMx_CNT and signaled on OC3 output.
If channel CC3 is configured as input:
CCR3 is the counter value transferred by the last input capture 3 event (IC3).
Bits 31:16 CCR4[31:16]: High Capture/Compare 4 value (on TIM2 and TIM5).
Bits 15:0 CCR4[15:0]: Low Capture/Compare value
1. if CC4 channel is configured as output (CC4S bits):
CCR4 is the value to be loaded in the actual capture/compare 4 register (preload value).
It is loaded permanently if the preload feature is not selected in the TIMx_CCMR register (bit OC4PE). Else the preload value is copied in the active capture/compare 4 register
when an update event occurs.
The active capture/compare register contains the value to be compared to the counter TIMx_CNT and signalled on OC4 output.
2. if CC4 channel is configured as input (CC4S bits in TIMx_CCMR4 register):CCR4 is the counter value transferred by the last input capture 4 event (IC4).
Application1 : Gnration dun signal PWM with HSI CLOCK 16MHz and TIMER3 TIM3 : PA6
#include <stm32f4xx.h>
void Config_PWM(void)
{
115
TIM3->CCR1 = 0;
GPIOA->AFR[0] = 0x2000000; //set GPIOA to AF2
TIM3->BDTR|=0xc000;
TIM3->CCER|=0x01;
TIM3->EGR|=0x02;
TIM3->CR1 |= 0x1; //enable timer 3
}
int main(void)
{
unsigned int f;
Config_PWM();
while(1)
{
TIM3->CCR1++;
if(TIM3->CCR1==TIM3->ARR)
{
TIM3->CCR1=0;
}
116
110: PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT<TIMx_CCR1 else inactive. In downcounting, channel 1 is inactive (OC1REF=0) as long as
TIMx_CNT>TIMx_CCR1 else active (OC1REF=1).
117
Application 2 : Gnration dun seul signal PWM with HSE CLOCK 8MHz: PA6
#include <stm32f4xx.h>
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
void Config_PWM(void)
{ //port PA6
int main(void)
{
unsigned int f;
Config_PWM();
clock_config();
while(1)
{
118
TIM3->CCR1++;
if(TIM3->CCR1==TIM3->ARR)
{
TIM3->CCR1=0;
}
for(f=0; f<200000; f++);
}
}
*****************************************************************************************************************
Application3 :Gnration de deux signaux PWM signal with HSE CLOCK 8MHz and TIMER3 TIM3 : PA6 and PA7
#include <stm32f4xx.h>
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
void Config_PWM(void)
{
TIM3->PSC = 1000;
TIM3->ARR = 200;
TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
119
GPIOA->AFR[0] |= 0x22000000; //set GPIOA to AF2
TIM3->BDTR|=0xc000;
TIM3->CCER|=0x11; //Enable Capture/Compare 1 output && Enable Capture/Compare 1 output
TIM3->EGR|=0x06; // Capture/compare 1 generation && Capture/compare 2 generation
TIM3->CR1 |= 0x1; //enable timer 3
}
int main(void)
{
unsigned int f;
Config_PWM();
clock_config();
while(1)
{
TIM3->CCR1++;
TIM3->CCR2++;
if(TIM3->CCR1==TIM3->ARR && TIM3->CCR2==TIM3->ARR)
{
TIM3->CCR1=0;
TIM3->CCR2=0;
}
for(f=0; f<100000; f++);
}
}
********************************************************************************
Application 4 : Gnration de deux signaux PWM signal with HSI CLOCK 16MHz and TIMER3 TIM3 : PA6 and PA7
#include <stm32f4xx.h>
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
120
}
void Config_PWM(void)
{
int main(void)
{
unsigned int f;
Config_PWM();
//clock_config();
while(1)
{
TIM3->CCR1++;
TIM3->CCR2++;
if(TIM3->CCR1==TIM3->ARR && TIM3->CCR2==TIM3->ARR)
{
TIM3->CCR1=0;
TIM3->CCR2=0;
}
for(f=0; f<100000; f++);
}
}
121
******************************************************************************************
APPLICATION 5: Generation de 4 signaux PWM using HSE clock and TIMER4 TIM4 : PD12 PD13 PD14 PD15
#include "stm32f4xx.h"
void delay(void)
{
volatile uint32_t i;
for (i=1; i <= 0xFFFF; i++);
}
int main()
{
RCC->APB1ENR = 0x00000004; // CLOCK ENABLE FOR TIMER4
RCC->AHB1ENR = 0x00000008; //CLOCK ENABLE FOR GPIOD
TIM4->CCER = 0x1111;
TIM4->CCMR1=0x6060;
TIM4->CCMR2=0x6060;
TIM4->CR1 = 0x0001;
TIM4->PSC = 1000;
TIM4->ARR = 200;
TIM4->CCR1 = 0;
TIM4->CCR2 = 0;
TIM4->CCR3 = 0;
TIM4->CCR4 = 0;
while(1)
{
volatile int i = 0;
122
for(i = 0; i <= 200 ; i++)
{
TIM4->CCR1 = i;
TIM4->CCR2 = i;
TIM4->CCR3 = i;
TIM4->CCR4 = i;
delay();
}
for(i = 200; i >= 0 ; i--)
{
TIM4->CCR1 = i;
TIM4->CCR2 = i;
TIM4->CCR3 = i;
TIM4->CCR4 = i;
delay();
}
**********************************************************************************************************************
APPLICATION 6: Gnration de 4 signaux PWM using HSE clock and TIMER4 TIM4 : PD12 PD13 PD14 PD15
#include "stm32f4xx.h" // Device header
void delay(void)
{
volatile uint32_t i;
for (i=1; i <= 0xFFFF; i++);
}
123
int main()
{
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
TIM4->CCER |= 0x1111;
TIM4->CCMR1|=0x6060;
TIM4->CCMR2|=0x6060;
TIM4->CR1 |= TIM_CR1_CEN;
TIM4->PSC = 1000;
TIM4->ARR = 200;
TIM4->CCR1 = 0;
TIM4->CCR2 = 0;
TIM4->CCR3 = 0;
TIM4->CCR4 = 0;
while(1)
{
volatile int i = 0;
for(i = 0; i <= 200 ; i++)
{
TIM4->CCR1 = i;
TIM4->CCR2 = i;
TIM4->CCR3 = i;
TIM4->CCR4 = i;
delay();
}
for(i = 200; i >= 0 ; i--){
TIM4->CCR1 = i;
TIM4->CCR2 = i;
TIM4->CCR3 = i;
TIM4->CCR4 = i;
124
delay();
}
125
APPLICATION 7 : ROTATION SYNCHRONNE DE 2 SERVO MOTEUR DE -90-> 0 et de 0->90
#include <stm32f4xx.h>
void clock_config() //Si on veut que la source clock soit egale HSE
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
void Config_PWM(void)
{
TIM3->PSC = 1000; //Le compteur est pilot par une horologe egale 16.000.000/1000=16000Hz (16KHz)
TIM3->ARR = 320; //la priode du signal PWM doit etre egale 50Hz T(PWM)=ARR x (Source_clk/PSC)=320x(16000000/1000)=50
TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
GPIOA->AFR[0] |= 0x22000000; //set GPIOA to AF2
TIM3->BDTR|=0xc000;
TIM3->CCER|=0x11; //Enable Capture/Compare 1 output && Enable Capture/Compare 1 output
TIM3->EGR|=0x06; // Capture/compare 1 generation && Capture/compare 2 generation
TIM3->CR1 |= 0x1; //enable timer 3
}
int main(void)
{
unsigned int f;
unsigned int i;
Config_PWM();
//clock_config(); //Clock source HSI 16MHz
while(1)
126
{
TIM3->CCR1=10;
TIM3->CCR2=10;
for(i=6;i<=40;i++) //rotation du servo de -90 jusqu 0
{
TIM3->CCR1=i;
TIM3->CCR2=i;
for(f=0; f<200000; f++);
}
for(i=40;i>=6;i--) //rotation du servo de 0 jusqu 90
{
TIM3->CCR1=i;
TIM3->CCR2=i;
for(f=0; f<200000; f++);
}
}
}
127
APPLICATION 8 : ROTATION ASYNCHRONNE DE 2 SERVO MOTEUR DE -90-> 0 et de 0->90
#include <stm32f4xx.h>
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready
void Config_PWM(void)
{
TIM3->PSC = 1000;
TIM3->ARR = 320; //TO fix the period T=20ms (50Hz)
TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
GPIOA->AFR[0] |= 0x22000000; //set GPIOA to AF2
TIM3->BDTR|=0xc000;
TIM3->CCER|=0x11; //Enable Capture/Compare 1 output && Enable Capture/Compare 1 output
TIM3->EGR|=0x06; // Capture/compare 1 generation && Capture/compare 2 generation
TIM3->CR1 |= 0x1; //enable timer 3
}
int main(void)
{
unsigned int f;
unsigned int i;
Config_PWM();
128
//clock_config();
while(1)
{
TIM3->CCR1=8;
TIM3->CCR2=8;
for(i=8;i<=40;i++)
{
TIM3->CCR1=i;
for(f=0; f<200000; f++);
}
for(i=40;i>=8;i--)
{
TIM3->CCR1=i;
for(f=0; f<200000; f++);
}
for(i=8;i<=40;i++)
{
TIM3->CCR2=i;
for(f=0; f<200000; f++);
}
for(i=40;i>=8;i--)
{
TIM3->CCR2=i;
for(f=0; f<200000; f++);
}
}
}
129
130
131
LCD STM32F4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32_ub_lcd_2x16.h"
132
int main(void)
{
__IO uint16_t ADCBuffer;
unsigned long j;
char text[60];
SystemInit();
// Init LC-Display
UB_LCD_2x16_Init();
for(j=0;j<=40000000;j++);
UB_LCD_2x16_Clear();
while(1)
{
for(ADCBuffer=0;ADCBuffer<4096;ADCBuffer++)
{
sprintf (text,"%d",ADCBuffer);
UB_LCD_2x16_String(0,0,"TIMER:");
UB_LCD_2x16_String(7,0,text);
for(j=0;j<=4000000;j++);
}
UB_LCD_2x16_Clear();
}
}
133
ANALOGUE DIGITAL CONVERTER
Introduction
The STM32F4 has 3 ADCs built in. There are 16 multiplexed channels used to connect the ADCs to the processor. 8 of these are connected to
ADC3, while all 16 of the channels are connected to ADC2 and ADC1. Each ADC can convert with a maximum precision of 12bits, meaning
that the output of the ADC will range from 0 to 212-1 or, 0 to 4095. The rest of the article looks at how you can use 1 of these ADCs to read
analog signals from 2 or more channels
134
Figure: ADC BLOCK DIAGRAM
135
typedef struct
{
__IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */
__IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */
__IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */
__IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */
__IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */
__IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */
__IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */
__IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */
__IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */
__IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */
__IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */
__IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */
__IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */
__IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */
__IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/
__IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */
__IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */
__IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */
__IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */
__IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */
} ADC_TypeDef;
136
REGISTRES:
137
ADC common control register (ADC_CCR)
138
ADC regular sequence register 3 (ADC_SQR3)
139
APPLICATION: Affichage de lADC outpout sur un LCD( 2x16)
Le but principal consiste afficher sur LCD(2x16) les rsultats de conversions de 2 chaines (ADC1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f4xx.h"
#include "stm32_ub_lcd_2x16.h"
140
/* inputs are PA2 & PA3 -> must be enabled for analog, PA must have clock! */
int main ()
{
unsigned int j;
__IO uint16_t ADCBuffer[2];
char text[60];
SystemInit(); // Quarz Einstellungen aktivieren
/*-----------------------------------------------------------------------------*/
/* Software triggered, dual, simultaneous sampling */
/*-----------------------------------------------------------------------------*/
UB_LCD_2x16_String(0,0,"TEST ADC");
for (j = 0; j<10000000; j++);
UB_LCD_2x16_Clear();
while (1)
{
ADC1->CR2 |= ADC_CR2_SWSTART; // simultaneous Start Conversion
ADC2->CR2 |= ADC_CR2_SWSTART; // simultaneous Start Conversion
for (j = 0; j<100; j++){}; // wait for conversion to complete
ADCBuffer[0]=ADC1->DR;
ADCBuffer[1]=ADC2->DR;
sprintf (text,"%d %d",ADCBuffer[0],ADCBuffer[1]);
UB_LCD_2x16_String(0,0,text);
for (j = 0; j<1000000; j++);
UB_LCD_2x16_Clear();
141
};
}
USART
#include <stdio.h>
#include "STM32F4xx.h"
char character[30];
int i;
142
/****************************************TEMPO**********************************/
void Delay_TIME(__IO uint32_t nCount)
{
while(nCount--);
}
}
/******************GPIO configuration : PD12, PD13, PD14, PD15 USED FOR THE COMMAND**************/
void config_GPIO()
{
RCC->AHB1ENR |= 1<<3; //Clocks for GPIOD
GPIOD->MODER |= 0x55<<24; //Bits 12..15 are output
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 configuration :
*********************************************************************************/
void UsartInit()
{
143
RCC->APB1ENR|=0x00040000; // Enable clock for USART3
GPIOB->AFR[1]=0x00007700; // //enable USART3_TX to PB10 and USART3_RX to PB11
GPIOB->MODER|=0x2AA00000; // configuring the USART3 ALTERNATE function to PB10 and PB11
USART3->BRR=0X1112; // 9600 Baud
//UART4->BRR = 0x0890; // 19200 baud
//UART4->BRR = 0x0450; // 38400 baud
//UART4->BRR = 0x02e0; // 57600 baud
//UART4->BRR = 0x016d; // 115200 baud
USART3->CR1|=0x0000202C; // USART3 enable
// NVIC->ISER[1]|=0x80; // NVIC da USART3 interrupta izin verelim
}
/************************************************************************************************
//To send data, we simply assign it to the DR register. Then we wait until the TXE (TX empty) flag
//in the SR register is set to be sure the data is transmitted. In the code it looks like this:
************************************************************************************************/
char receive_data()
{
char RXCH = USART3->DR;
return RXCH;
}
/*********************************************************************************
144
MESSAGE DACCEUIL
*********************************************************************************/
void MESSAGE_WELCOM()
{
SendTxt("TEST UART ");
SendTxt("\n");
SendTxt("WELCOM");
SendTxt("\n");
}
int main()
{
config_GPIO();
SystemInit_1();
UsartInit();
MESSAGE_WELCOM();
while(1)
{
for(i=0;i<20;i++)
{
sprintf (character,"%d",i);
SendTxt(character);
SendTxt("\n");
Delay_TIME(10000000);
// To read in received data, all we have to do is to wait until RXNE (RX not empty) bit is set in the status register SR
//of the USART1. As soon as we realized, this bit is set, we read out the data from the DR (data register) of the USART
if((USART3->SR & 0x0020)!=0) //if((USART3->SR & 0x0020)) FLAG RXNE=1 BUFFER_RX est plein est pret lire
{
char read_character=receive_data(); //lecture du caractere et Le flag RXNE reviend 0
/********************** CMD1***************************************************/
if(read_character=='A')
{
145
SendTxt("CMD1 VALIDE ");
SendTxt("\n");
GPIOD->ODR = 0xF000; //turn LEDs D12 D13 D14 D15 on
Delay_TIME(0xFFFFFF);
GPIOD->ODR = ~0xF000; //turn LEDs D12 D13 D14 D15 off
Delay_TIME(0xFFFFFF);
}
i=0;
}
}
146
__IO uint16_t ADCBuffer[2];
char text[60];
int i;
int j;
int ncount1,ncount2;
/****************************************TEMPO**********************************/
void Delay_TIME(__IO uint32_t nCount)
{
while(nCount--);
}
RCC->PLLCFGR = 0x07402A04; // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim 168 Mhz
RCC->CR |= 0x01000000; // PLL calismaya baslasin (Rehber Sayfa 95)
while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
FLASH->ACR = 0x00000605; // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
RCC->CFGR |= 0x00000002; // Sistem Clk u PLL uzerinden besleyelim
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
/******************GPIO configuration : PD12, PD13, PD14, PD15 USED FOR THE COMMAND**************/
void config_GPIO()
{
RCC->AHB1ENR |= 1<<3; //Clocks for GPIOD
147
GPIOD->MODER |= 0x55<<24; //Bits 12..15 are output
GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz
}
/*********************************************************************************
USART3 configuration :
*********************************************************************************/
void UsartInit()
{
void configuration_ADC()
{
RCC->APB2ENR |= 0x00000100 + 0x00000200; // Enable clock for ADC1 & ADC2
RCC->AHB1ENR |= 0x00000001 + 0x00000002; // Enable clock for GPIOA & GPIOB
ADC->CCR = 0x00000006; // No DMA, Regular simultaneous mode only
ADC1->CR2 = 0x00000001; // Control Register 2: ADC1 ON
ADC1->SQR3 = 0x00000002; // regular SeQuence Register 3
ADC2->CR2 = 0x00000001; // Control Register 2: ADC2 ON
ADC2->SQR3 = 0x00000003; // regular SeQuence Register 3
GPIOA->MODER |= 0x000000f0; // MODE Register -> PA2, PA3 are analog inputs
}
/************************************************************************************************
148
//To send data, we simply assign it to the DR register. Then we wait until the TXE (TX empty) flag
//in the SR register is set to be sure the data is transmitted. In the code it looks like this:
************************************************************************************************/
char receive_data()
{
char RXCH = USART3->DR;
return RXCH;
}
void MESSAGE_WELCOM()
{
int main()
149
{
config_GPIO();
SystemInit_1();
UsartInit();
configuration_ADC();
//MESSAGE_WELCOM();
while(1)
{
ADC1->CR2 |= ADC_CR2_SWSTART; // simultaneous Start Conversion
ADC2->CR2 |= ADC_CR2_SWSTART; // simultaneous Start Conversion
while((ADC1->SR & 0x2)==0); // wait for ADC2 conversion to complete
while((ADC2->SR & 0x2)==0); // wait for ADC2 conversion to complete
ADCBuffer[0]=ADC1->DR;
ADCBuffer[1]=ADC2->DR;
// To read in received data, all we have to do is to wait until RXNE (RX not empty) bit is set in the status register
SR
//of the USART1. As soon as we realized, this bit is set, we read out the data from the DR (data register) of the
USART
if((USART3->SR & 0x0020)!=0) //if((USART3->SR & 0x0020)) FLAG RXNE=1 BUFFER_RX est plein est pret lire
{
char read_character=receive_data(); //lecture du caractere et Le flag RXNE reviend 0
150
/********************** CMD1***************************************************/
if(read_character=='A')
{
ncount2=0;
if(ncount1==1)
{
GPIOD->ODR = 0xF000; //turn LEDs D12 D13 D14 D15 on
Delay_TIME(0xFFFFFF);
GPIOD->ODR = ~0xF000; //turn LEDs D12 D13 D14 D15 off
Delay_TIME(0xFFFFFF);
}
ncount1++;
}
ncount1=0;
if(ncount2==1)
{
GPIOD->ODR = 0x5000; //turn LEDs D12 and D14 on
Delay_TIME(0xFFFFFF);
GPIOD->ODR = ~0x5000; //turn LEDs D13 and D15 on
Delay_TIME(0xFFFFFF);
GPIOD->ODR = 0x0; //LEDs off
}
ncount2++;
}
}
else
{
ncount1=0;
ncount2=0;
151
}
}
}
152
#include <stdio.h>
int N1,N2;
void clock_config()
{
RCC->CFGR = 0x00000001; //select HSE as system clock
RCC->CR |= 1<<16; //HSE on
while (!(RCC->CR & (1<<17))); //wait until HSE ready on attend ce que HSERDY=1
void SystemInit_1()
{
RCC->CFGR |= 0x00009400; // Fixation of the AHB and APB prescaler : HPRE PPRE1 PPRE2
RCC->CR |= 0x00010000; // HSE ON
while (!(RCC->CR & 0x00020000));// wait until will be ready HSERDY=1
RCC->PLLCFGR = 0x07402A04; // PLL coefficients : M = 4, N = 168, P = 2 and Q = 7 ==> SYSCLK= HSE x(N/M*P)=8x
(168/4x2)=168MHz =>CLK_TIM2=SYSCLK/PPRE1=168/4=42MHz
RCC->CR |= 0x01000000; // PLL ON
while(!(RCC->CR & 0x02000000)); // wait until will be PLL ready PLLRDY=1
153
FLASH->ACR = 0x00000605; // Flash ROM is 5 Wait state
RCC->CFGR |= 0x00000002; // System PLL On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
void UsartInit()
{
154
}
/**********************************************************************************
//PA0 and PA1 used for CAPTURE SIGNAL
**********************************************************************************/
void GPIOA_CONGIGURATION()
{
// enable GPIOA clock
RCC->AHB1ENR = 0x00000001;
// Alternate Function
GPIOA->MODER =0x0000000A; // AF, TIM2_CH1 // AF, TIM2_CH2
// Alternate Function pins
GPIOA->AFR[0] =0x00000011;// TIM2_CH1, AF1 // TIM2_CH2, AF1
}
void GPIOD_CONGIGURATION()
{
RCC->AHB1ENR |= 1<<3; //Clocks for GPIOD
GPIOD->MODER |= 0x55500000; //Bits 12..15 are output
}
void TIM2_MODE_INPUT_CAPTURE()
{
// enable TIM2 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; //0x00000001
// configure TIM2_CH1 for input capture //////////////////////////////////
TIM2->CCMR1 = 0x0121;// set TIM2_CH1 for input mode // set the input filter to 4 samples
// select edge of the active transition
//enable input capture
TIM2->CCER = 0x0033;
TIM2->SR=0;
//TIM2->PSC = 2;
155
//enable TIM2
TIM2->CR1 = 0x0001;
void square_signal_1()
{
GPIOD->ODR = 0xF000;
Delay(0x600);
GPIOD->ODR =~0xF000;
Delay(0x600);
}
void square_signal_2()
{
GPIOD->ODR = 0x0F00;
Delay(0x700);
GPIOD->ODR =~0x0F00;
Delay(0x700);
}
void MESSAGE_WELCOM()
{
SendTxt("TEST UART ");
SendTxt("\n");
SendTxt("WELCOM");
SendTxt("\n");
}
int main(void)
{
SystemInit_1();
UsartInit();
GPIOA_CONGIGURATION();
GPIOD_CONGIGURATION();
156
TIM2_MODE_INPUT_CAPTURE();
MESSAGE_WELCOM();
while (1)
{
square_signal_1();
square_signal_2();
if((TIM2->SR&0x0002)) // CC1IF =1 ?
{
N1++;
if(N1==10000)
{
value_CCR1=TIM2->CCR1;
sprintf(text,"%d %d",value_CCR1,value_CCR2);
SendTxt(text);
SendTxt("\n");
N1=0;
}
TIM2->CNT=0;
TIM2->SR &=0; // CC1IF =0 the flag is clear
}
if((TIM2->SR&0x0004)) // CC1IF =1 ?
{
N2++;
if(N2==10000)
{
value_CCR2=TIM2->CCR2;
sprintf(text,"%d %d",value_CCR1,value_CCR2);
SendTxt(text);
SendTxt("\n");
N2=0;
}
TIM2->CNT=0;
TIM2->SR &=0; // CC1IF =0 the flag is clear
157
}
void TIM2_IRQHandler()
{
158
ANNEXE
La rpartition de la RAM
159
GPIO
TIMER
ADC
DAC
CAN
SYSTEM CLOCK
I2S
LES PERIPHERIQUES
160
Chaque interface (priphrique: interface de communication(I2C,SPI,USB), TIMER, PORT(PORTA,PORTB,PORTC.) est dfinie par un
ensemble de registres qui sont regroupes dans une structure(ensemble de registre). La manipulation de ces registres se fait
via un pointeur pointu sur cette structure.
Exemple : #define TIM2 ((TIM_TypeDef *) TIM2_BASE) TIM2 est un pointeur sur la structure TIM_TypeDef
Exemple :
161
La structure TIM_TypeDef contient plusieurs registres permettant de configurer les timers (CR1, RESERVED0,
CR2,RESERVED1,SMCR.etc, RESERVED14)et elle est dfinie comme ceci :
typedef struct
{
__IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
uint16_t RESERVED0; /*!< Reserved, 0x02 */
__IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
uint16_t RESERVED1; /*!< Reserved, 0x06 */
__IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
uint16_t RESERVED2; /*!< Reserved, 0x0A */
__IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
uint16_t RESERVED3; /*!< Reserved, 0x0E */
__IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */
uint16_t RESERVED4; /*!< Reserved, 0x12 */
__IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
uint16_t RESERVED5; /*!< Reserved, 0x16 */
__IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
uint16_t RESERVED6; /*!< Reserved, 0x1A */
__IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
uint16_t RESERVED7; /*!< Reserved, 0x1E */
__IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
uint16_t RESERVED8; /*!< Reserved, 0x22 */
__IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
__IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
uint16_t RESERVED9; /*!< Reserved, 0x2A */
__IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
__IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
uint16_t RESERVED10; /*!< Reserved, 0x32 */
__IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
__IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
__IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
__IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
__IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
uint16_t RESERVED11; /*!< Reserved, 0x46 */
__IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
uint16_t RESERVED12; /*!< Reserved, 0x4A */
__IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
162
uint16_t RESERVED13; /*!< Reserved, 0x4E */
__IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */
uint16_t RESERVED14; /*!< Reserved, 0x52 */
} TIM_TypeDef;
163
#define USART1 ((USART_TypeDef *) USART1_BASE)
#define USART6 ((USART_TypeDef *) USART6_BASE)
#define ADC ((ADC_Common_TypeDef *) ADC_BASE)
#define ADC1 ((ADC_TypeDef *) ADC1_BASE)
#define ADC2 ((ADC_TypeDef *) ADC2_BASE)
#define ADC3 ((ADC_TypeDef *) ADC3_BASE)
#define SDIO ((SDIO_TypeDef *) SDIO_BASE)
#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE)
#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
#define TIM9 ((TIM_TypeDef *) TIM9_BASE)
#define TIM10 ((TIM_TypeDef *) TIM10_BASE)
#define TIM11 ((TIM_TypeDef *) TIM11_BASE)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE)
#define CRC ((CRC_TypeDef *) CRC_BASE)
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
#define DMA1 ((DMA_TypeDef *) DMA1_BASE)
#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE)
#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE)
#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE)
#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE)
#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE)
#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE)
#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE)
#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE)
#define DMA2 ((DMA_TypeDef *) DMA2_BASE)
#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE)
#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE)
#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE)
164
#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE)
#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE)
#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE)
#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE)
#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE)
#define ETH ((ETH_TypeDef *) ETH_BASE)
#define DCMI ((DCMI_TypeDef *) DCMI_BASE)
#define CRYP ((CRYP_TypeDef *) CRYP_BASE)
#define HASH ((HASH_TypeDef *) HASH_BASE)
#define RNG ((RNG_TypeDef *) RNG_BASE)
#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)
#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)
#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)
#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE)
165
166
167
168
FSMC register map
#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address
#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) (0xA0000000+ 0x0000= 0XA0000000)
#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) (0xA0000000+ 0x0104= 0XA0000104)
#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) (0xA0000000+ 0x0060= 0XA0000060)
#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) (0xA0000000+ 0x0080= 0XA0000080)
#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) (0xA0000000+ 0x00A0= 0XA00000A0)
169
170
FMSC REGISTER MAP (SUITE)
171
FMSC REGISTER MAP (SUITE)
172
RNG register map
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) (0x40000000 + 0x00010000 = 0x50000000)
#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) (0x50000000+ 0x60800 =0x50060800)
173
174
HASH REGISTER MAP AND RESET VALUES (SUITE)
175
176
177
DCMI register map
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) (0x40000000 + 0x00010000 = 0x50000000)
#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) (0x50000000+ 0x50000 =0x50050000)
178
179
ETHERNET MAC register map
#define PERIPH_BASE ((uint32_t)0x40000000)
Rq : #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) (0x40000000 + 0x00020000= 0x40020000)
#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) (0x40020000 + 0x8000= 0x40028000)
#define ETH_MAC_BASE (ETH_BASE) 0x40028000
#define ETH_MMC_BASE (ETH_BASE + 0x0100) 0x40028000 + 0x0100 =0x40028100
#define ETH_PTP_BASE (ETH_BASE + 0x0700) 0x40028000 + 0x0700 =0x40028700
#define ETH_DMA_BASE (ETH_BASE + 0x1000) 0x40028000 + 0x1000 =0x40029000
180
181
182
Dfinition des bits attribus quelques registres
/******************************************************************************/
/* */
/* Reset and Clock Control */
/* */
/******************************************************************************/
/******************** Bit definition for RCC_CR register ********************/
#define RCC_CR_HSION ((uint32_t)0x00000001)
#define RCC_CR_HSIRDY ((uint32_t)0x00000002)
183
#define RCC_CR_PLLRDY ((uint32_t)0x02000000)
#define RCC_CR_PLLI2SON ((uint32_t)0x04000000)
#define RCC_CR_PLLI2SRDY ((uint32_t)0x08000000)
184
#define RCC_PLLCFGR_PLLP ((uint32_t)0x00030000)
#define RCC_PLLCFGR_PLLP_0 ((uint32_t)0x00010000)
#define RCC_PLLCFGR_PLLP_1 ((uint32_t)0x00020000)
185
/*!< SWS configuration */
#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */
#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */
#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */
186
/*!< PPRE2 configuration */
#define RCC_CFGR_PPRE2 ((uint32_t)0x0000E000) /*!< PRE2[2:0] bits (APB2 prescaler) */
#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00002000) /*!< Bit 0 */
#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00004000) /*!< Bit 1 */
#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00008000) /*!< Bit 2 */
187
#define RCC_CFGR_MCO2_0 ((uint32_t)0x40000000)
#define RCC_CFGR_MCO2_1 ((uint32_t)0x80000000)
188
Address offset: 0x0C
Reset value: 0x0000 0000
189
Address offset: 0x10
Reset value: 0x0000 0000
190
/******************** Bit definition for RCC_AHB3RSTR register **************/
#define RCC_AHB3RSTR_FSMCRST ((uint32_t)0x00000001)
191
#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000)
#define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000)
192
Address offset: 0x24
Reset value: 0x0000 0000
193
Address offset: 0x30
Reset value: 0x0010 0000
194
/******************** Bit definition for RCC_AHB3ENR register ***************/
#define RCC_AHB3ENR_FSMCEN ((uint32_t)0x00000001)
195
#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000)
#define RCC_APB1ENR_DACEN ((uint32_t)0x20000000)
196
Address offset: 0x44
Reset value: 0x0000 0000
197
Address offset: 0x50
Reset value: 0x7E67 91FF
198
/******************** Bit definition for RCC_AHB3LPENR register *************/
#define RCC_AHB3LPENR_FSMCLPEN ((uint32_t)0x00000001)
199
#define RCC_APB1LPENR_PWRLPEN ((uint32_t)0x10000000)
#define RCC_APB1LPENR_DACLPEN ((uint32_t)0x20000000)
200
Address offset: 0x64
Reset value: 0x0007 5F33
201
/******************** Bit definition for RCC_CSR register *******************/
#define RCC_CSR_LSION ((uint32_t)0x00000001)
#define RCC_CSR_LSIRDY ((uint32_t)0x00000002)
#define RCC_CSR_RMVF ((uint32_t)0x01000000)
#define RCC_CSR_BORRSTF ((uint32_t)0x02000000)
#define RCC_CSR_PADRSTF ((uint32_t)0x04000000)
#define RCC_CSR_PORRSTF ((uint32_t)0x08000000)
#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000)
#define RCC_CSR_WDGRSTF ((uint32_t)0x20000000)
#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000)
#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000)
202
#define RCC_SSCGR_SSCGEN ((uint32_t)0x80000000)
203
/******************************************************************************/
204
205
206
207
208
TIMER_STM32F4
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227