diff --git a/Drivers/Driver_GPIO.c b/Drivers/Driver_GPIO.c new file mode 100644 index 0000000..96d4d27 --- /dev/null +++ b/Drivers/Driver_GPIO.c @@ -0,0 +1,52 @@ +#include "Driver_GPIO.h" + +void MyGPIO_Init(MyGPIO_Struct_TypeDef * Data){ + char finalConf = Data->GPIO_Conf; + GPIO_TypeDef * GPIO; + GPIO = Data->GPIO; + + // Mise en place de la clock + if (GPIO==GPIOA){ + RCC->APB2ENR |= (0x01 << 2) ; + } else if (GPIO==GPIOB){ + RCC->APB2ENR |= (0x01 << 3) ; + } else { + RCC->APB2ENR |= (0x01 << 4) ; + } + + // On regarde si on est en pull_up + if (finalConf == 0x18){ + Data->GPIO->ODR |= 0x01 << Data->GPIO_Pin; + finalConf = 0x08; + } + + // Initialisation de la bonne pin + if (Data->GPIO_Pin < 8){ + Data->GPIO->CRL &= ~(0xF << 4*Data->GPIO_Pin); // shifté de 4*numPin + Data->GPIO->CRL |= (Data->GPIO_Conf << 4*Data->GPIO_Pin); + } + else { + Data->GPIO->CRH &= ~(0xF << 4*(Data->GPIO_Pin -8)); // shifté de 4*numPin + Data->GPIO->CRH |= (Data->GPIO_Conf << 4*(Data->GPIO_Pin -8)); + } +} + + +int MyGPIO_Read(GPIO_TypeDef* GPIO, int GPIO_Pin) {// renvoie 0 ou autre chose different de 0 + return ((GPIO->IDR >> GPIO_Pin) & 1); +} + +void MyGPIO_Set(GPIO_TypeDef* GPIO, int GPIO_Pin){ // Bit 0 à 15 de BSRR c'est le set + GPIO->BSRR |= 0x01 << GPIO_Pin; +} + +void MyGPIO_Reset(GPIO_TypeDef* GPIO, int GPIO_Pin){ // Bit 16 à 31 de BSRR c'est le reset + GPIO->BSRR |= ((0x01 << GPIO_Pin) << 0x10); +} + + +void MyGPIO_Toggle(GPIO_TypeDef* GPIO, int GPIO_Pin){ // Toggle : changer la valeur du ODR + GPIO->ODR ^= 0x01 << GPIO_Pin; +} + + diff --git a/Drivers/Driver_GPIO.h b/Drivers/Driver_GPIO.h new file mode 100644 index 0000000..a04763e --- /dev/null +++ b/Drivers/Driver_GPIO.h @@ -0,0 +1,29 @@ +#ifndef MYGPIO_H +#define MYGPIO_H +#include "stm32f10x.h" + +typedef struct +{ + GPIO_TypeDef* GPIO; + int GPIO_Pin; //numero de 0 a 15 + int GPIO_Conf; //voir ci dessous +} MyGPIO_Struct_TypeDef; + + +#define In_Floating 0x04 +#define In_PullDown 0x08 +#define In_PullUp 0x18 // le 1 représente le fait qu'on est en pull up +#define In_Analog 0x00 +#define Out_Ppull 0x02 +#define Out_OD 0x05 +#define AltOut_Ppull 0x0A +#define AltOut_OD 0x0D + +void MyGPIO_Init(MyGPIO_Struct_TypeDef * Data); +int MyGPIO_Read(GPIO_TypeDef* GPIO, int GPIO_Pin);// renvoie 0 ou autre chose different de 0 +void MyGPIO_Set(GPIO_TypeDef* GPIO, int GPIO_Pin); +void MyGPIO_Reset(GPIO_TypeDef* GPIO, int GPIO_Pin); +void MyGPIO_Toggle(GPIO_TypeDef* GPIO, int GPIO_Pin); + +#endif + diff --git a/Drivers/MyADC.c b/Drivers/MyADC.c new file mode 100644 index 0000000..8a772f8 --- /dev/null +++ b/Drivers/MyADC.c @@ -0,0 +1,36 @@ +#include "MyADC.h" +#include "MyTimer.h" +#include "Driver_GPIO.h" +#define NULL 0 +//#define nombreChannel 1 + +void initADC(int channel){ + + // activer la clock de l'ADC 1 + RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; + RCC->CFGR |= 0x8000; + ADC1->CR2 |= ADC_CR2_ADON; + + // Choix du channel + ADC1->SQR3 |= channel << 0;// on est sur le premier car on a qu'un seul channel +} + +void startADC(void) { + ADC1->CR2 |= ADC_CR2_ADON; +} + +int read(void) { + int value ; + // Recuperer le bit de End of conversion + while (!(ADC1->SR & (0x01 << 1))); + //on veut masquer les 12 bits les plus bas donc on prend le not de 0x0f >> 12 (111000000000) + value = ADC1->DR & (~(0x0f << 12)); + return value; +} + + + + + + + diff --git a/Drivers/MyADC.h b/Drivers/MyADC.h new file mode 100644 index 0000000..c3202fd --- /dev/null +++ b/Drivers/MyADC.h @@ -0,0 +1,12 @@ +#ifndef __MYADC_H +#define __MYADC_H +#include "stm32f10x.h" + +// initialise tout ce au'il y a a faire pour l'ADC: +void initADC(int channel); + +void startADC(void); + +int read(void); + +#endif diff --git a/Drivers/MyTimer.c b/Drivers/MyTimer.c new file mode 100644 index 0000000..d907060 --- /dev/null +++ b/Drivers/MyTimer.c @@ -0,0 +1,286 @@ +#include "MyTimer.h" +#include "stm32f10x.h" +#include "Driver_GPIO.h" +#define NULL 0 + +// Déclaration des fonctions utilisées lors de handlers +void (* ptr1) (void) = NULL; +void (* ptr2) (void) = NULL; +void (* ptr3) (void) = NULL; +void (* ptr4) (void) = NULL; + +void MyTimer_Base_Init (MyTimer_Struct_TypeDef* Data){ + TIM_TypeDef * numTimer ; + numTimer = Data->Timer ; + switch ((int)numTimer) { // on cast le pointeur vers le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // masque pour activer le timer (0xOB, pin 11) + break ; + + case (int)TIM2: + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN ; // masque pour activer le timer2 (0x01) + break ; + + case (int)TIM3: + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ; // masque pour activer le timer2 (0x02) + break ; + + case (int)TIM4: + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN ; // masque pour activer le timer2 (0x03) + break ; + } + // on parametre ARR et PSC sur le timer + Data->Timer->ARR = Data->ARR ; + Data->Timer->PSC = Data->PSC ; +} + +void MyTimer_Base_Start(TIM_TypeDef * Timer ) { + Timer -> CR1 |= TIM_CR1_CEN ; // on active la clock du timer +} + +void MyTimer_Base_Stop(TIM_TypeDef * Timer ) { + Timer -> CR1 &= ~TIM_CR1_CEN ; // on désactive la clock du timer +} + + +void MyTimer_ActiveIT ( TIM_TypeDef * Timer , char Prio, void (* IT_function) (void)){ + Timer->DIER |= 0x01; // on autorise l'interuption au niveau du timer + + switch ((int)Timer) { // on cast le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + NVIC->ISER[0] |= NVIC_ISER_SETENA_25; // on autorise l'interuption au niveau du coeur par le timer 1 + NVIC->IP[25] = Prio; // on parametre la prio du timer + ptr1 = IT_function; //fonction à appeler par le handler + break ; + + case (int)TIM2: + NVIC->ISER[0] |= NVIC_ISER_SETENA_28; // on autorise l'interuption au niveau du coeur par le timer 2 + NVIC->IP[28] = Prio; // on parametre la prio du timer + ptr2 = IT_function; //fonction à appeler par le handler + break ; + + case (int)TIM3: + NVIC->ISER[0] |= NVIC_ISER_SETENA_29; // on autorise l'interuption au niveau du coeur par le timer 3 + NVIC->IP[29] = Prio; // on parametre la prio du timer + ptr3 = IT_function; //fonction à appeler par le handler + break ; + + case (int)TIM4: + NVIC->ISER[0] |= NVIC_ISER_SETENA_30; // on autorise l'interuption au niveau du coeur par le timer 4 + NVIC->IP[30] = Prio; // on parametre la prio du timer + ptr4 = IT_function; //fonction à appeler par le handler + break ; + } +} + + + +void TIM1_UP_IRQHandler(void){ + if (ptr1 != NULL){ // si la fonction a bien été initialisée + (*ptr1)(); // on appelle la fonction en cas de handler1 + } + TIM1->SR &= ~(1<<0); // on baisse le flag d'activation +} + +void TIM2_IRQHandler(void){ + if (ptr2 != NULL){ // si la fonction a bien été initialisée + (*ptr2)(); // on appelle la fonction en cas de handler2 + } + TIM2->SR &= ~(1<<0); // on baisse le flag d'activation +} + +void TIM3_IRQHandler(void){ + if (ptr3 != NULL){ // si la fonction a bien été initialisée + (*ptr3)(); // on appelle la fonction en cas de handler3 + } + TIM3->SR &= ~(1<<0); // on baisse le flag d'activation +} + +void TIM4_IRQHandler(void){ + if (ptr4 != NULL){ // si la fonction a bien été initialisée + (*ptr4)(); // on appelle la fonction en cas de handler4 + } + TIM4->SR &= ~(1<<0); // on baisse le flag d'activation +} + +void MyTimer_PWM(TIM_TypeDef * Timer, char Channel){ + MyGPIO_Struct_TypeDef gpio; + gpio.GPIO_Conf = AltOut_Ppull; + + // Activation la capture du compteur (CNT) dans le registre capture register + Timer->CCER |= TIM_CCER_CC1E; + + + + switch ((int)Channel) { // on cast le timer pour le comparer au pointeur des timers existants + /* ============== + === Channel 1 === + ============== */ + + case 1 : + // On veut mettre les bits 4 à 6 de OC1M à 110 (PWM mode 1 p 349) + Timer->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; + Timer->CCMR1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC1S); // mettre 00 + Timer->CCR1 = 0; + + switch ((int)Timer) { // on cast le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 8; + TIM1->BDTR |= TIM_BDTR_MOE ; // bit MOE pour activer le timer généralement (main output enable) + break ; + + case (int)TIM2: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 0; + break ; + + case (int)TIM3: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 6; + break ; + + case (int)TIM4: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 6; + break ; + } + break ; + + + /* ============== + === Channel 2 === + ============== */ + + case 2 : + + // On veut mettre les bits 12 à 14 de OC1M à 110 (PWM mode 1 p 349) + Timer->CCMR1 |= TIM_CCMR1_OC2M_1| TIM_CCMR1_OC2M_2; + Timer->CCMR1 &= ~(TIM_CCMR1_CC2S | TIM_CCMR1_CC2S); // mettre 00 + Timer->CCR2 = 0; + + switch ((int)Timer) { // on cast le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 9; + TIM1->BDTR |= TIM_BDTR_MOE ; // bit MOE pour activer le timer généralement (main output enable) + break ; + + case (int)TIM2: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 1; + break ; + + case (int)TIM3: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 7; + break ; + + case (int)TIM4: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 7; + break ; + } + break ; + + + /* ============== + === Channel 3 === + ============== */ + case 3 : + + // On veut mettre les bits 4 à 6 de OC2M à 110 (PWM mode 1 p 349) + Timer->CCMR2 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; + Timer->CCMR2 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC1S); // mettre 00 + Timer->CCR3 = 0; + + switch ((int)Timer) { // on cast le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 10; + TIM1->BDTR |= TIM_BDTR_MOE ; // bit MOE pour activer le timer généralement (main output enable) + break ; + + case (int)TIM2: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 2; + break ; + + case (int)TIM3: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 0; + break ; + + case (int)TIM4: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 8; + break ; + } + break ; + + /* ============== + === Channel 4 === + ============== */ + case 4 : + + // On veut mettre les bits 12 à 14 de OC2M à 110 (PWM mode 1 p 349) + Timer->CCMR2 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2; + Timer->CCMR2 &= ~(TIM_CCMR1_CC2S | TIM_CCMR1_CC2S); // mettre 00 + Timer->CCR4 = 0; + + switch ((int)Timer) { // on cast le timer pour le comparer au pointeur des timers existants + case (int)TIM1 : + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 11; + TIM1->BDTR |= TIM_BDTR_MOE ; // bit MOE pour activer le timer généralement (main output enable) + break ; + + case (int)TIM2: + gpio.GPIO = GPIOA; + gpio.GPIO_Pin = 3; + break ; + + case (int)TIM3: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 1; + break ; + + case (int)TIM4: + gpio.GPIO = GPIOB; + gpio.GPIO_Pin = 9; + break ; + } + break ; + } + MyGPIO_Init(&gpio); +} + +// calculer et definir les valeurs de CRR +void Set_PWM_PRCT(TIM_TypeDef * Timer, char Channel, int percent){ + short value = Timer->ARR*percent/100; + + switch (Channel){ + case 1: + Timer->CCR1 = value; + break; + case 2: + Timer->CCR2 = value; + break; + case 3: + Timer->CCR3 = value; + break; + case 4: + Timer->CCR4 = value; + break; + } + + + + +} + + + + + + diff --git a/Drivers/MyTimer.h b/Drivers/MyTimer.h new file mode 100644 index 0000000..184d3e8 --- /dev/null +++ b/Drivers/MyTimer.h @@ -0,0 +1,34 @@ +#ifndef __MYTIMER_H +#define __MYTIMER_H +#include "stm32f10x.h" + +typedef struct +{ + TIM_TypeDef * Timer ; // TIM1 à TIM4 + unsigned short ARR ; + unsigned short PSC ; +} MyTimer_Struct_TypeDef ; + +/* +***************************************************************************************** +* @brief +* @param -> Paramètre sous forme d’une structure (son adresse) contenant les +informations de base +* @Note -> Fonction à lancer systématiquement avant d’aller plus en détail dans les +conf plus fines (PWM, codeur inc ...) +************************************************************************************************* +*/ + + +void MyTimer_Base_Init (MyTimer_Struct_TypeDef* Data) ; + +void MyTimer_Base_Start(TIM_TypeDef * Timer ); +void MyTimer_Base_Stop(TIM_TypeDef * Timer ); + +void MyTimer_ActiveIT (TIM_TypeDef * Timer, char Prio, void (* IT_function) (void)); + +void MyTimer_PWM(TIM_TypeDef * Timer, char Channel); + +void Set_PWM_PRCT(TIM_TypeDef * Timer, char Channel, int percent); + +#endif