Compare commits

..

No commits in common. "a2d245df7e5bf78604d1652622664fb37c4eb4cd" and "a606e6331b79ead8f848c8027506dd917611f541" have entirely different histories.

5 changed files with 182 additions and 22 deletions

8
include/Timer.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef TIMER_H_
#define TIMER_H_
#include <stm32f10x.h>
// Config de timer
extern void MyTimer_Base_Init(TIM_TypeDef *Timer , unsigned short ValARR , unsigned short ValPSC );
// Enable timers
void EnableTimer(TIM_TypeDef *Timer);
#endif

View file

@ -1,9 +1,12 @@
#include <stm32f10x.h>
#include <Horloge.h>
#include <MYGPIO.h>
#include <stdlib.h>
#include <MySPI.h>
#include <stdint.h>
#include <Accelerometre.h>
#include <stdio.h>
#include <Timer.h>
#include <Servo.h>
void initAccelo(void)
@ -25,26 +28,27 @@ void initAccelo(void)
}
uint16_t * RecupAccelo(void) { // Recuperation des donnees de l'accelerometre
static uint16_t Messie[3];
uint8_t buf[6];
MySPI_Clear_NSS();
// Lecture multi-octet à partir de 0x32 (X0, X1, Y0, Y1, Z0 et Z1)
MySPI_Send(0x80 | 0x40 | 0x32); // On envoie RW MB A5 ... A0 pour recuperer les données
for (int i = 0; i < 6; i++) {buf[i] = (uint8_t)MySPI_Read();} // Lecture des 6 registres en séquenciel
MySPI_Set_NSS();
static uint16_t Messie[3];
uint8_t buf[6];
MySPI_Clear_NSS();
// Lecture multi-octet à partir de 0x32 (X0, X1, Y0, Y1, Z0 et Z1)
MySPI_Send(0x80 | 0x40 | 0x32); // On envoie RW MB A5 ... A0 pour recuperer les données
for (int i = 0; i < 6; i++) {buf[i] = (uint8_t)MySPI_Read();} // Lecture des 6 registres en séquenciel
MySPI_Set_NSS();
// Conversion des données récupérés en uint16_t
Messie[0] = (uint16_t)(buf[1] << 8 | buf[0]); // X
Messie[1] = (uint16_t)(buf[3] << 8 | buf[2]); // Y
Messie[2] = (uint16_t)(buf[5] << 8 | buf[4]); // Z
return Messie;
// Conversion des données récupérés en uint16_t
Messie[0] = (uint16_t)(buf[1] << 8 | buf[0]); // X
Messie[1] = (uint16_t)(buf[3] << 8 | buf[2]); // Y
Messie[2] = (uint16_t)(buf[5] << 8 | buf[4]); // Z
return Messie;
}
void initLacheur(void){
GPIOB->CRH &= ~(0xF << (0 * 4));
GPIOB->CRH |= (0xA << (0 * 4)); //On met GPIOB.8 en mode output 2Mhz, alternate pp
GPIOB->CRH &= ~(0xF << (0 * 4));
GPIOB->CRH |= (0xA << (0 * 4)); //On met GPIOB.8 en mode output 2Mhz, alternate pp
Timer_Init(TIM4, 0xFFFF, 22);
EnableTimer(TIM4);
MyTimer_Base_Init(TIM4, 0xFFFF, 22);
}
void LacheVoile(int AngelLim, uint16_t moyennen){

View file

@ -1,13 +1,18 @@
#include <stm32f10x.h>
#include <stdio.h>
#include <Horloge.h>
//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;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; //L'horloge est enabléd
} else if (Timer == TIM2) {
TIM2->CR1 |= TIM_CR1_CEN;
TIM2->CR1 |= TIM_CR1_CEN; //On enable l'horloge interne
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
} else if (Timer == TIM3) {
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
@ -16,10 +21,9 @@ void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Pr
}
Timer->ARR |= Autoreload;
Timer->PSC |= Prescaler;
Timer->EGR |= TIM_EGR_UG;
}
//La fonction TIM2_IRQHandler existe déjà dans le processeur, on l'a juste redifint, tel qu'à chaque overflow on met un bit 1 dans GPIOA_ODR
//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
@ -42,3 +46,118 @@ void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void
}
//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;
#if POWERMODE //Powermode 1
pwrmd = 0b110;
#else
pwrmd = 0b111; //Powermode 2
#endif
if (Channel == 1){
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->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->CCMR1 &= ~(0b111<<4);
Timer->CCMR2 |= (pwrmd<<4);
Timer->CCMR2 |= TIM_CCMR2_OC3PE;
Timer->CCER |= TIM_CCER_CC3E;
}
else if (Channel == 4){
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;
switch (Channel) {
case 1:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<0*4); GPIOA->CRH |= (0xA<<0*4); TIM1->BDTR |= 1<<15; }
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<0*4); GPIOA->CRL |= (0xA<<0*4);}
if (Timer == TIM3){GPIOA->CRL &= ~(0xF<<6*4); GPIOA->CRL |= (0xA<<6*4);}
if (Timer == TIM4){GPIOB->CRL &= ~(0xF<<5*4); GPIOB->CRL |= (0xA<<5*4);}
break;
case 2:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<1*4); GPIOA->CRL |= (0xA<<1*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<1*4); GPIOA->CRL |= (0xA<<1*4);}
if (Timer == TIM3){GPIOA->CRL &= ~(0xF<<7*4); GPIOA->CRL |= (0xA<<7*4);}
if (Timer == TIM4){GPIOB->CRL &= ~(0xF<<7*4); GPIOB->CRL |= (0xA<<7*4);}
break;
case 3:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<2*4); GPIOA->CRH |= (0xA<<2*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<2*4); GPIOA->CRL |= (0xA<<2*4);}
if (Timer == TIM3){GPIOB->CRL &= ~(0xF<<0*4); GPIOB->CRL |= (0xA<<0*4);}
if (Timer == TIM4){GPIOB->CRH &= ~(0xF<<0*4); GPIOB->CRH |= (0xA<<0*4);}
break;
case 4:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<3*4); GPIOA->CRH |= (0xA<<3*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<3*4); GPIOA->CRL |= (0xA<<3*4);}
if (Timer == TIM3){GPIOB->CRL &= ~(0xF<<1*4); GPIOB->CRL |= (0xA<<1*4);}
if (Timer == TIM4){GPIOB->CRH &= ~(0xF<<1*4); GPIOB->CRH |= (0xA<<1*4);}
}
}
//Une fonction qui met le bon PWM volue
int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, int DutyC){
int CCR_VAL = (ARR_VAL + 1) * DutyC / 100; //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

View file

@ -1,7 +1,7 @@
#include <Servo.h>
#include <DriverGPIO.h>
#include <PWM.h>
#include <Horloge.h>
#include <Timer.h>
void Servo_Moteur(int angle, TIM_TypeDef * Timer, int Channel){ // Controle du moteur
int dutyCycle = (5* angle + 5*90)/90; // 5-10 % Duty Cycle
@ -10,7 +10,9 @@ void Servo_Moteur(int angle, TIM_TypeDef * Timer, int Channel){ // Controle du m
void initServo(TIM_TypeDef * Timer, int Channel){ // Config du moteur servo
if (Timer == TIM4) {
Timer_Init(TIM4, 0xFFFF, 22); // Pour obtenir un période de 20 ms
EnableTimer(TIM4);
//MyTimer_Base_Init(TIM4, 20000 - 1, 71);
MyTimer_Base_Init(TIM4, 0xFFFF, 22); // Pour obtenir un période de 20 ms
if (Channel == 3){
MyGPIO_Init(GPIOB, 8, AltOut_Ppull); // Outut push pull alternate

27
src/Timer.c Normal file
View file

@ -0,0 +1,27 @@
#include <stm32f10x.h>
#include <Timer.h>
void MyTimer_Base_Init( TIM_TypeDef * Timer , unsigned short ValARR , unsigned short ValPSC ) { // Configuration du timer
Timer -> PSC=(ValPSC);
Timer-> ARR = (ValARR);
Timer->EGR |= TIM_EGR_UG;
};
void EnableTimer(TIM_TypeDef *Timer){
if(Timer == TIM2){
RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;
}
else if(Timer == TIM3){
RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;
}
else if(Timer == TIM4){
RCC -> APB1ENR |= RCC_APB1ENR_TIM4EN;
}
else if(Timer == TIM1){
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
}
else{
}
}