diff --git a/Horloge.c b/Horloge.c new file mode 100644 index 0000000..180b8a2 --- /dev/null +++ b/Horloge.c @@ -0,0 +1,137 @@ +#include +#include +#include + + +//Il faut trouver le signal +//On est à Timer 2 + +static void (*TIM2_Appel)(void) = 0; + +void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Prescaler){ + if (Timer == TIM1) { + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; //L'horloge est enabléd + } else if (Timer == TIM2) { + TIM2->CR1 |= TIM_CR1_CEN; //On enable l'horloge interne + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + } else if (Timer == TIM3) { + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + } else if (Timer == TIM4) { + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; + } + Timer->ARR |= Autoreload; + Timer->PSC |= Prescaler; +} + +//La fonction TIM2_IRQHandler s'utilise dans le processeur, on l'a juste redifint, tel qu'à chaque overflow on met un bit 1 dans GPIOA_ODR +void TIM2_IRQHandler(void) { //On redefinit le IRQHandler qui est déjà ecrit dans le code source + if (TIM2->SR & TIM_SR_UIF) { //On met le bit de overflow à un dès qu'on a overflow + TIM2->SR &= ~TIM_SR_UIF; //Remise à zero + + if (TIM2_Appel){TIM2_Appel();} + } +} + + +void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void)){ //On veut créer une fonction qui envoie un signal au cas où il y a debordement, avec une prioritaire, 0 plus importante 15 moins importante + if (Timer == TIM2){ + + TIM2_Appel = Interrupt_fonc; + + NVIC_EnableIRQ(TIM2_IRQn); + NVIC_SetPriority(TIM2_IRQn, Prio); + TIM2->DIER |= TIM_DIER_UIE; //Le registre DIER(Interrupt Enable Register) est mis au bit Update Interrupt, qui se commute lors d'un overflow + TIM2->CR1 |= TIM_CR1_CEN; //Clock Enable + } +} + + +//Fonction qui permet de clignoter le DEL à un pulse volue (Sinusoïdale) +//Si le sinus est haut(haute tension) le Duty Cicle est proche de 100%, +//si le sinus est bas (vers la tension la plus basse) le Duty Cycle est vers 0% +//On s'applique sur un plage de [0V; 3.3V] + + +void MyTimer_PWM(TIM_TypeDef * Timer , int Channel){ + int pwrmd; + int CCR_VAL = (ARR_VAL + 1) * DUTYC / 100.0f; + #if POWERMODE //Powermode 1 + pwrmd = 0b110; + #else + pwrmd = 0b111; //Powermode 2 + #endif + if (Channel == 1){ + Timer->CCR1 = CCR_VAL; //Faut avoir le bon valeur + Timer->CCMR1 &= ~(0b111<<4); //On clear les trois bits qui sont de pwm + Timer->CCMR1 |= (pwrmd<<4); //On affecte le powermode au bits de lecture pour le µ-controlleur + Timer->CCMR1 |= TIM_CCMR1_OC1PE; //Update preload, il n'affecte pas le valeur avant que la prochaine cycle + Timer->CCER = TIM_CCER_CC1E; //Enable le pin voulu basculer + } + else if (Channel == 2){ + Timer->CCR2 = CCR_VAL; + Timer->CCMR1 &= ~(0b111<<12); //Le TIMx_CCMR1 configure deux channels, de bit [6:4] CH1, [14:12] CH2 (OC2M = Output Channel 2 ) + Timer->CCMR1 |= (pwrmd<<12); + Timer->CCMR1 |= TIM_CCMR1_OC2PE; + Timer->CCER |= TIM_CCER_CC2E; + } + else if (Channel == 3){ + Timer->CCR3 = CCR_VAL; + Timer->CCMR1 &= ~(0b111<<4); + Timer->CCMR2 |= (pwrmd<<4); + Timer->CCMR2 |= TIM_CCMR2_OC3PE; + Timer->CCER |= TIM_CCER_CC3E; + } + else if (Channel == 4){ + Timer->CCR4 = CCR_VAL; + Timer->CCMR1 &= ~(0b111<<12); + Timer->CCMR2 |= (pwrmd<<12); + Timer->CCMR2 |= TIM_CCMR2_OC4PE; + Timer->CCER |= TIM_CCER_CC4E; + } + + //En dessous d'ici, on a l'aide du plus gentil chat que je connais + // Enable auto-reload preload -- //Ensures that your initial configuration — PWM mode, duty cycle, period — actually takes effect before the timer starts counting. + Timer->CR1 |= TIM_CR1_ARPE; + // Force update event to load ARR and CCR values immediately + Timer->EGR |= TIM_EGR_UG; + // Start the timer + Timer->CR1 |= TIM_CR1_CEN; + +} + +//Une fonction qui met le bon PWM volue +int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, float DutyC){ + int CCR_VAL = (ARR_VAL + 1) * DutyC / 100.0f; //ARR_VAL déjà definie + switch (Channel){ + case 1: Timer->CCR1 = CCR_VAL; + case 2: Timer->CCR2 = CCR_VAL; + case 3: Timer->CCR3 = CCR_VAL; + case 4: Timer->CCR4 = CCR_VAL; + default: break; +} +return 0; +Timer->EGR |= TIM_EGR_UG; +} +//Putaing con, ça marche pas + + + /* + Pulse width modulation mode allows you to generate a signal with a frequency determined + by the value of the TIMx_ARR register and a duty cycle determined by the value of the + TIMx_CCRx register. + + The PWM mode can be selected independently on each channel (one PWM per OCx + output) by writing 110 (PWM mode 1) or ‘111 (PWM mode 2) in the OCxM bits in the + TIMx_CCMRx register. You must enable the corresponding preload register by setting the + OCxPE bit in the TIMx_CCMRx register, and eventually the auto-reload preload register by + setting the ARPE bit in the TIMx_CR1 register. + */ +//Il faut créer une autre fonction qui lui met le bon duty cycle +//Timer->CCR1 = Duty_cycle*0.01*3.3; // On divise par cent et multiplue par 3.3V, plage de ADC + +//Pareil pour la frequence, faut une fonction externe qui lui fait ça + + + //Pendant les vacances terminer l'ADC et l'USART (Activités sur Moodle) +//Hell naw, that did not happen cuh + diff --git a/Horloge.h b/Horloge.h new file mode 100644 index 0000000..dc53fb3 --- /dev/null +++ b/Horloge.h @@ -0,0 +1,16 @@ +#include +#define PSC_VAL 624 +#define ARR_VAL 0xE0FF + +//DUTY CYCLE +#define DUTYC 70 //Chiffre entre 0 et 100, où 100 est 100% duty cycle +#define POWERMODE 1 // 1 vaut powermode 1, 0 vaut powermode 2 (Powermode pour le config de dutycycle) +//Powermode 1 reste sur la bonne polarité: cad. si DUTY_CYCLE vaut 60 alors le signal reste HIGH pour 60% du periode, inverse pour pwmd2 +//Timer +void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Prescaler); +void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void)); +void TIM2_IRQHandler(void); + +//PWM +void MyTimer_PWM(TIM_TypeDef * Timer , int Channel); +int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, float DutyC); \ No newline at end of file diff --git a/MYGPIO.c b/MYGPIO.c new file mode 100644 index 0000000..764e301 --- /dev/null +++ b/MYGPIO.c @@ -0,0 +1,97 @@ +#include +#include +#include + + +//FONCTIONS POUR LE DEL INTERNE + +void initGPIO_Interne(void){ + RCC->APB2ENR |= (0x01 << 2) | (0x01 << 3) | (0x01 << 4) ; + + //Start + //CRL pour les 8 premiers portes, CRH pour les 8 dernières portes + if (LED_PIN_INTERNE < 8){ + LED_GPIO_INTERNE->CRL &= ~(0xF << (LED_PIN_INTERNE*4)); + LED_GPIO_INTERNE->CRL |= GPIO_OUTPUT_PPULL_MODE<<(LED_PIN_INTERNE*4) ; // On met tous les Pins de broche A à ANalog Input sauf broche PA.5 qui correspond au LED GREEN: Output 2MHz et GP output push-pull + } + else{ + LED_GPIO_INTERNE->CRH &= ~(0xF <<((LED_PIN_INTERNE-8)*4)); + LED_GPIO_INTERNE->CRH |= GPIO_OUTPUT_PPULL_MODE<<((LED_PIN_INTERNE-8)*4); + } + + if (BUTTON_PIN_INTERNE < 8){ + BUTTON_GPIO_INTERNE->CRL &= ~(0xF << (BUTTON_PIN_INTERNE*4)); + BUTTON_GPIO_INTERNE->CRL |= GPIO_INPUT_FLOATING_MODE<<(BUTTON_PIN_INTERNE*4) ; // On met tous les Pins de broche A à ANalog Input sauf broche PA.5 qui correspond au LED GREEN: Output 2MHz et GP output push-pull + } + else{ + BUTTON_GPIO_INTERNE->CRH &= ~(0xF <<((BUTTON_PIN_INTERNE-8)*4)); + BUTTON_GPIO_INTERNE->CRH |= GPIO_INPUT_FLOATING_MODE<<((BUTTON_PIN_INTERNE-8)*4); + } +} + +int boutonAppuye_Interne(void){ + return BUTTON_GPIO_INTERNE->IDR &(1<ODR |= (0x01 << LED_PIN_INTERNE) ; //On essaie de mettre en position PA5 de GPIOC_ODR un 1 comme ca allume le LED GREEN + } + + void eteindreDEL_Interne(void){ + LED_GPIO_INTERNE->ODR &= ~(0x01 << LED_PIN_EXTERNE) ; //On essaie de mettre en position PA5 de GPIOC_ODR un 0 comme ca eteint le LED GREEN + //ALlumer un LED externe, PB8/D15 OUTPUT, Bouton Poussoir PB9/D14 +} + +void commuterDEL_Interne(void){ + LED_GPIO_INTERNE->ODR ^= (0x01 << LED_PIN_INTERNE); +} + + + +//FONCTIONS POUR LE DEL EXTERNE + +void initGPIO_Externe(void){ + RCC->APB2ENR |= (0x01 << 2) | (0x01 << 3) | (0x01 << 4) ; + + //Start + //CRL pour les 8 premiers portes, CRH pour les 8 dernières portes + if (LED_PIN_EXTERNE < 8){ + LED_GPIO_EXTERNE->CRL &= ~(0xF << (LED_PIN_EXTERNE*4)); + LED_GPIO_EXTERNE->CRL |= GPIO_OUTPUT_PPULL_MODE<<(LED_PIN_EXTERNE*4) ; // On met tous les Pins de broche A à ANalog Input sauf broche PA.5 qui correspond au LED GREEN: Output 2MHz et GP output push-pull + } + else{ + LED_GPIO_EXTERNE->CRH &= ~(0xF <<((LED_PIN_EXTERNE-8)*4)); + LED_GPIO_EXTERNE->CRH |= GPIO_OUTPUT_PPULL_MODE<<((LED_PIN_EXTERNE-8)*4); + } + + if (BUTTON_PIN_EXTERNE < 8){ + BUTTON_GPIO_EXTERNE->CRL &= ~(0xF << (BUTTON_PIN_EXTERNE*4)); + BUTTON_GPIO_EXTERNE->CRL |= GPIO_INPUT_FLOATING_MODE<<(BUTTON_PIN_EXTERNE*4) ; // On met tous les Pins de broche A à ANalog Input sauf broche PA.5 qui correspond au LED GREEN: Output 2MHz et GP output push-pull + } + else{ + BUTTON_GPIO_EXTERNE->CRH &= ~(0xF <<((BUTTON_PIN_EXTERNE-8)*4)); + BUTTON_GPIO_EXTERNE->CRH |= GPIO_INPUT_FLOATING_MODE<<((BUTTON_PIN_EXTERNE-8)*4); + } +} + +int boutonAppuye_Externe(void){ + return BUTTON_GPIO_EXTERNE->IDR &(1<ODR |= (0x01 << LED_PIN_EXTERNE) ; +} //On essaie de mettre en position PA5 de GPIOC_ODR un 1 comme ca allume le LED GREEN + + +void eteindreDEL_Externe(void){ + LED_GPIO_EXTERNE->ODR &= ~(0x01 << LED_PIN_EXTERNE) ; //On essaie de mettre en position PA5 de GPIOC_ODR un 0 comme ca eteint le LED GREEN + //ALlumer un LED externe, PB8/D15 OUTPUT, Bouton Poussoir PB9/D14 +} + +void commuterDEL_Externe(void){ + LED_GPIO_EXTERNE->ODR ^= (0x01 << LED_PIN_EXTERNE); +} + + + + diff --git a/MYGPIO.h b/MYGPIO.h new file mode 100644 index 0000000..2a7ef22 --- /dev/null +++ b/MYGPIO.h @@ -0,0 +1,38 @@ +//Definitions + +//INTERNE +#define LED_PIN_INTERNE (5) // 5 pour le LED de Arduino +#define BUTTON_GPIO_INTERNE (GPIOA) //GPIOA pour l'Arduion +#define LED_GPIO_INTERNE (GPIOA) //GPIOA pour Arduino +#define BUTTON_PIN_INTERNE (13) //13 pour Arduino + +//EXTERNE +#define LED_PIN_EXTERNE (8) // 8 pour la porte PB8 +#define BUTTON_GPIO_EXTERNE (GPIOB) //GPIOB pour externe +#define LED_GPIO_EXTERNE (GPIOB) //GPIOB pour Externe +#define BUTTON_PIN_EXTERNE (9) //9 pour bouton poussoir + +//STATIQUES +#define GPIO_OUTPUT_PPULL_MODE (2) //Mis en GP output 2MHz en mode PP +#define GPIO_INPUT_PUPD_MODE (8) //Pour mettre à Pull up/down +#define GPIO_INPUT_FLOATING_MODE (4) + +//Pour y entrer dans le: si on est sur l'arduino ou sur le led externe +#define INTERNE 1 // 1 c'est vrai, 0 faux + +//FONCTIONS +void initGPIO_Interne(void); +int boutonAppuye_Interne(void); +void allumerDEL_Interne(void); +void eteindreDEL_Interne(void); +void commuterDEL_Interne(void); +void allume_bit_Interne(void); + +void initGPIO_Externe(void); +int boutonAppuye_Externe(void); +void allumerDEL_Externe(void); +void eteindreDEL_Externe(void); +void commuterDEL_Externe(void); +void allume_bit_Externe(void); + +