0% found this document useful (0 votes)
17 views7 pages

Code Finale

The document is a C program for configuring and using various peripherals on an STM32F4 microcontroller, including timers, ADC, I2C, and USART. It implements functionalities such as temperature reading from a DS1621 sensor, PWM control, and interrupt handling for external events. The main function initializes the peripherals and enters an infinite loop, while the interrupt handlers manage data acquisition and communication tasks.

Uploaded by

saidazmitri123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views7 pages

Code Finale

The document is a C program for configuring and using various peripherals on an STM32F4 microcontroller, including timers, ADC, I2C, and USART. It implements functionalities such as temperature reading from a DS1621 sensor, PWM control, and interrupt handling for external events. The main function initializes the peripherals and enters an infinite loop, while the interrupt handlers manage data acquisition and communication tasks.

Uploaded by

saidazmitri123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

#include "stm32f4xx.

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

RCC->AHB1ENR |= 1 << 0; // Enable clock for GPIOA


GPIOA->MODER |= (3 << 2) | (3 << 4) | (3 << 6); // PA1, PA2, PA3 as analog
RCC->APB2ENR |= 1 << 8; // Enable ADC1 clock
ADC1->CR2 |= (1 << 0); // Turn on ADC (bit 0)
ADC1->CR1 |= (1 << 11); // Enable discontinuous mode
ADC1->CR1 |= (1 << 5); // Enable EOC (End of Conversion) interrupts
(bit 5)
ADC1->SQR1 = 0; // Single conversion in the sequence (L[3:0] =
0000)
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt in NVIC
}
void config_I2C(void) {
// Enable GPIOB and I2C1 clocks
RCC->AHB1ENR |= (1 << 1); // GPIOB clock
RCC->APB1ENR |= (1 << 21); // I2C1 clock

// Configure PB6 (SCL) and PB7 (SDA) as Alternate Function Open-Drain


GPIOB->MODER &= ~((3 << (12)) | (3 << (14))); // Clear mode
GPIOB->MODER |= (2 << (12)) | (2 << (14)); // Set to Alternate Function
GPIOB->OTYPER |= (1 << 6) | (1 << 7); // Open-drain
GPIOB->AFR[0] |= (4 << (24)) | (4 << (28)); // AF4 for I2C1

// 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);

TIM3->PSC = 15; // Prescaler for 1 MHz frequency (16MHz/(15+1))


TIM3->ARR = 999; // Period for 1 kHz (ARR+1)

// Configure duty cycles (Alpha = 1 + CCRx)


TIM3->CCR1 = 0;
TIM3->CCR2 = 0;
TIM3->CCR3 = 0;
TIM3->CCR4 = 0;
// Configure CCMR1 (CH1 and CH2) in PWM1
TIM3->CCMR1 |= (6 << 4) | (6 << 12);;
// Configure CCMR2 (CH3 and CH4) in PWM1
TIM3->CCMR2 |= (6 << 4) | (6 << 12);

// 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);

// Send DS1621 address with write bit


while (!(I2C1->SR1 & (1 << 0))); // Wait for START condition
I2C1->DR = DS1621_ADDR;

while (!(I2C1->SR1 & (1 << 1))); // Wait for address acknowledgment


I2C1->SR2; // Clear address flag

while (!(I2C1->SR1 & (1 << 7))); //test FLAG TXE


// Send START_CONVERT command
I2C1->DR = START_CONVERT;

// Send STOP condition


I2C1->CR1 |= (1 << 9);
}
// Function to Read Temperature from DS1621
float ReadTemperature(void) {

// Send START condition


I2C1->CR1 |= (1 << 8);

// Send DS1621 address with write bit


while (!(I2C1->SR1 & (1 << 0))); // Wait for START condition
I2C1->DR = DS1621_ADDR;

while (!(I2C1->SR1 & (1 << 1))); // Wait for address acknowledgment


I2C1->SR2; // Clear address flag

// Send READ_TEMP command


I2C1->DR = READ_TEMP;
while (!(I2C1->SR1 & (1 << 7))); // Wait for data register empty
// Send RESTART condition
I2C1->CR1 |= (1 << 8);
// Send DS1621 address with read bit
while (!(I2C1->SR1 & (1 << 0))); // Wait for START condition

I2C1->DR = DS1621_ADDR | 0x01;


while (!(I2C1->SR1 & (1 << 1))); // Wait for address acknowledgment
I2C1->SR2;
// Clear address flag

// Send ACK and STOP condition


I2C1->CR1|=(1 << 10);
// Read temperature
while (!(I2C1->SR1 & (1 << 6))); //TEST FLAG RXNE
DATA_HIGH = I2C1->DR;

// Send NACK and STOP condition


I2C1->CR1 &= ~(1 << 10); // Clear NACK bit
while (!(I2C1->SR1 & (1 << 6))); //TEST FLAG RXNE
DATA_LOW = I2C1->DR;

if(DATA_LOW!=0)
{
temperature=DATA_HIGH+0.5;
}
else
{
temperature=DATA_HIGH;
}

I2C1->CR1 |= (1 << 9); // STOP condition

return temperature; // Return integer temperature


}

void SendChar_USART3(char c)
{
while (!(USART3->SR & (1 << 7)))
;
USART3->DR = c;
}

void SendString_USART3(char *pt)


{
while (*pt)
{
SendChar_USART3(*pt);
pt++;
}
}

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;

chain_number = 0; // Reset counter

sprintf(message, "ADC1: %d, ADC2: %d, ADC3: %d,


Temperature: %.2f\r\n", ADC_VALUE[0], ADC_VALUE[1], ADC_VALUE[2],temperature);
SendString_USART3(message);
}
}
}

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);

for (j = 0; j < N; j++)


{
Buffer_RX[j] = 0;
}
}
}

You might also like