Code Finale
Code Finale
h"
#include <stdio.h>
#include <string.h>
void config_TIMER6(void);
void config_EXTI(void);
void config_ADC(void);
void config_I2C(void);
void config_USART3(void);
int k = 0;
int chain_number = 0;
int ADC_VALUE[3];
char message[50];
char Buffer_RX[50];
int i = 0;
int j = 0;
int N = 0;
int DATA_HIGH;
int DATA_LOW;
#define DS1621_ADDR 0x90
// DS1621 Command Codes
#define START_CONVERT 0xEE
#define READ_TEMP 0xAA
float temperature;
void config_TIMER6(void)
{
RCC->APB1ENR |= (1 << 4); // Enable clock for TIM6
TIM6->PSC = 15999; // Configure prescaler to divide the frequency
TIM6->ARR = 1999; // Configure auto-reload for adjusting the
period
TIM6->DIER |= (1 << 0); // Enable TIM6 interrupts
NVIC_EnableIRQ(TIM6_DAC_IRQn); // Enable TIM6 interrupt in NVIC
}
void config_EXTI(void)
{
RCC->AHB1ENR |= 1 << 0; // Enable clock for GPIOA
RCC->APB2ENR |= 1 << 14; // Enable clock for SYSCFG
SYSCFG->EXTICR[0] = 0; // Map PA0 to EXTI0
EXTI->IMR |= 1; // Enable EXTI0 line
EXTI->FTSR |= 1; // Configure trigger on falling edge
NVIC_EnableIRQ(EXTI0_IRQn); // Enable EXTI0 interrupt in NVIC
}
void config_ADC(void)
{
RCC->AHB1ENR |= (1 << 3); // Enable clocks for GPIOD
GPIOD->MODER |= (1 << 24) | (1 << 26) |(1 << 28) | (1 << 30); // PD12 PD13
PD14 PD15 as output
// Configure I2C1
I2C1->CR2 = 16; // APB1 clock frequency = 16 MHz
I2C1->CCR = 80; // 100 kHz I2C speed
I2C1->TRISE = 17; // Maximum rise time
I2C1->CR1 |= (1 << 0); // Enable I2C1
}
void config_USART3(void)
{
// Enable clock for GPIOB
RCC->AHB1ENR |= (1 << 1);
// Configure PB10 (TX) and PB11 (RX) in Alternate Function
GPIOB->MODER |= (2 << 20); // PB10
GPIOB->MODER |= (2 << 22); // PB11
// Configure AF7 (USART3) for PB10 and PB11
GPIOB->AFR[1] |= (7 << 8); // PB10 -> AF7 (USART3_TX)
GPIOB->AFR[1] |= (7 << 12); // PB11 -> AF7 (USART3_RX)
RCC->APB1ENR |= (1 << 18); // Enable clock for USART3 (bit 18)
USART3->BRR = 1667; // Baud rate 9600
USART3->CR1 |= (1 << 2); // Enable RE (bit 2)
USART3->CR1 |= (1 << 3); // Enable TE (bit 3)
USART3->CR1 |= (1 << 4); // Enable IDLE interrupt (bit 4)
USART3->CR1 |= (1 << 5); // Enable RXNE interrupt (bit 5)
USART3->CR1 |= (1 << 13); // Enable USART (bit 13)
NVIC_EnableIRQ(USART3_IRQn); // Enable USART3 interrupt in NVIC
}
void config_TIM3_PWM(void)
{
// Enable clock for TIM3
RCC->APB1ENR |= (1 << 1);
// Enable clock for GPIOB
RCC->AHB1ENR |= (1 << 1);
// Configure PB0, PB1, PB4, and PB5 in AF
GPIOB->MODER |= (2 << 0) | (2 << 2) | (2 << 8) | (2 << 10);
// Configure AF2 (TIM3)
GPIOB->AFR[0] |= (2 << 0) | (2 << 4) | (2 << 16) | (2 << 20);
// Enable Channels
TIM3->CCER |= (1 << 0) | (1 << 4) | (1 << 8) | (1 << 12);
// Start TIMER
TIM3->CR1 |= (1 << 0);
}
void config_NVIC_Priorities(void)
{
NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(2, 0, 0));
NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(2, 1, 0));
NVIC_SetPriority(TIM6_DAC_IRQn, NVIC_EncodePriority(2, 2, 0));
NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(2, 3, 0));
}
// Function to Start DS1621 Temperature Conversion
void StartConversion(void) {
// Send START condition
I2C1->CR1 |= (1 << 8);
if(DATA_LOW!=0)
{
temperature=DATA_HIGH+0.5;
}
else
{
temperature=DATA_HIGH;
}
void SendChar_USART3(char c)
{
while (!(USART3->SR & (1 << 7)))
;
USART3->DR = c;
}
int main(void)
{
config_EXTI();
config_TIMER6();
config_ADC();
config_I2C();
config_USART3();
config_TIM3_PWM();
config_NVIC_Priorities();
while (1);
}
void EXTI0_IRQHandler(void)
{
if ((EXTI->PR & 0x1) != 0) // Check if EXTI0 triggered the interrupt
{
TIM6->CR1 |= 0x0001; // Start TIMER6
EXTI->PR = 0x1; // Clear the interrupt flag by writing 1
}
}
void TIM6_DAC_IRQHandler(void)
{
if ((TIM6->SR & 0x0001) != 0) // If update flag is set (UIF=1)
{
k++;
if (k == 1)
{
GPIOD->ODR = (1 << 15); // Set D15 high
ADC1->SQR3 = 1;
ADC1->CR2 |= 1 << 30;
}
if (k == 2)
{
GPIOD->ODR = (1 << 14); // Set D14 high
ADC1->SQR3 = 2;
ADC1->CR2 |= 1 << 30;
}
if (k == 3)
{
GPIOD->ODR = (1 << 13); ; // Set D13 high
StartConversion();
temperature = ReadTemperature();
ADC1->SQR3 = 3;
ADC1->CR2 |= 1 << 30;
k = 0;
}
TIM6->SR &= 0; // Interrupt has been handled (UIF=0)
}
}
void ADC_IRQHandler(void)
{
if (ADC1->SR & (1 << 1)) // Check EOC flag
{
chain_number++;
if (chain_number == 1)
{
ADC_VALUE[0] = ADC1->DR; // Read data register
}
if (chain_number == 2)
{
ADC_VALUE[1] = ADC1->DR;
}
if (chain_number == 3)
{
ADC_VALUE[2] = ADC1->DR;
void USART3_IRQHandler(void)
{
if (USART3->SR & (1 << 5))
{
i++;
Buffer_RX[i - 1] = USART3->DR;
}
if (USART3->SR & (1 << 4))
{
USART3->DR;
if (strstr(Buffer_RX, "FW+"))
{
if ((TIM3->CCR1 < 1000) && (TIM3->CCR3 < 1000))
{
TIM3->CCR1 += 125;
TIM3->CCR2 = 0;
TIM3->CCR3 += 125;
TIM3->CCR4 = 0;
}
}
else if (strstr(Buffer_RX, "FW-"))
{
if ((TIM3->CCR1 > 125) && (TIM3->CCR3 > 125))
{
TIM3->CCR1 -= 125;
TIM3->CCR2 = 0;
TIM3->CCR3 -= 125;
TIM3->CCR4 = 0;
}
}
else if (strstr(Buffer_RX, "STOP"))
{
// Stop motors (set duty cycles to 0)
TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
TIM3->CCR3 = 0;
TIM3->CCR4 = 0;
}
else if (strstr(Buffer_RX, "BW+"))
{
if ((TIM3->CCR2 < 1000) && (TIM3->CCR4 < 1000))
{
TIM3->CCR1 = 0;
TIM3->CCR2 += 125;
TIM3->CCR3 = 0;
TIM3->CCR4 += 125;
}
}
else if (strstr(Buffer_RX, "BW-"))
{
if ((TIM3->CCR2 > 125) && (TIM3->CCR4 > 125))
{
TIM3->CCR1 = 0;
TIM3->CCR2 -= 125;
TIM3->CCR3 = 0;
TIM3->CCR4 -= 125;
}
}
else if (strstr(Buffer_RX, "LT"))
{
TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
TIM3->CCR3 = 1000;
TIM3->CCR4 = 0;
}
else if (strstr(Buffer_RX, "RT"))
{
TIM3->CCR1 = 1000;
TIM3->CCR2 = 0;
TIM3->CCR3 = 0;
TIM3->CCR4 = 0;
}
N = i;
i = 0;
SendString_USART3(Buffer_RX);