1. ;
void RCC_Init(void) {
RCC->CFGR |= RCC_CFGR_PLLXTPRE;
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY)) {
};
RCC->CFGR |= (RCC_CFGR_PLLMULL6);
RCC->CFGR |= RCC_CFGR_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY)) {
};
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_1;
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
}
2. , , , Push Pull;
void GPIO_Init(void) {
RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN);
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
GPIOB->CRL &= ~(GPIO_CRL_CNF3 | GPIO_CRL_MODE3);
GPIOB->CRL |= GPIO_CRL_MODE3_0;
GPIOB->CRL &= ~(GPIO_CRL_CNF4 | GPIO_CRL_MODE4);
GPIOB->CRL |= GPIO_CRL_MODE4_0;
GPIOB->CRL &= ~(GPIO_CRL_CNF5 | GPIO_CRL_MODE5);
GPIOB->CRL |= GPIO_CRL_MODE5_0;
GPIOB->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_MODE6);
GPIOB->CRL |= GPIO_CRL_MODE6_0;
GPIOB->CRL &= ~(GPIO_CRL_CNF7 | GPIO_CRL_MODE7);
GPIOB->CRL |= GPIO_CRL_MODE7_0;
GPIOB->CRH &= ~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8);
GPIOB->CRH |= GPIO_CRH_MODE8_0;
GPIOB->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9);
GPIOB->CRH |= GPIO_CRH_MODE9_0;
GPIOA->CRH &= ~(GPIO_CRH_CNF11 | GPIO_CRH_MODE11);
GPIOA->CRH |= GPIO_CRH_MODE11_0;
GPIOA->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_MODE12);
GPIOA->CRH |= GPIO_CRH_MODE12_0;
GPIOA->CRH &= ~(GPIO_CRH_CNF15 | GPIO_CRH_MODE15);
GPIOA->CRH |= GPIO_CRH_MODE15_0;
GPIOB->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_MODE12);
GPIOB->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);
GPIOB->CRH &= ~(GPIO_CRH_CNF14 | GPIO_CRH_MODE14);
GPIOB->CRH |= GPIO_CRH_MODE14_0;
GPIOB->CRH &= ~(GPIO_CRH_CNF15 | GPIO_CRH_MODE15);
GPIOB->CRH |= (GPIO_CRH_CNF15_1 | GPIO_CRH_MODE15_0);
GPIOA->CRH &= ~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8);
GPIOA->CRH |= GPIO_CRH_MODE8_0;
GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9);
GPIOA->CRH |= (GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0);
GPIOA->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
GPIOA->CRH |= GPIO_CRH_MODE10_0;
GPIOB->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
GPIOB->CRH |= (GPIO_CRH_CNF10_1 | GPIO_CRH_MODE10_0);
GPIOB->CRH &= ~(GPIO_CRH_CNF11 | GPIO_CRH_MODE11);
GPIOB->CRH |= (GPIO_CRH_CNF11_1 | GPIO_CRH_MODE11_0);
GPIOB->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_MODE0);
GPIOB->CRL &= ~(GPIO_CRL_CNF1 | GPIO_CRL_MODE1);
GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_MODE0);
GPIOA->CRL &= ~(GPIO_CRL_CNF1 | GPIO_CRL_MODE1);
GPIOA->CRL &= ~(GPIO_CRL_CNF2 | GPIO_CRL_MODE2);
GPIOA->CRL &= ~(GPIO_CRL_CNF3 | GPIO_CRL_MODE3);
GPIOA->CRL &= ~(GPIO_CRL_CNF4 | GPIO_CRL_MODE4);
GPIOA->CRL &= ~(GPIO_CRL_CNF5 | GPIO_CRL_MODE5);
GPIOA->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_MODE6);
GPIOA->CRL &= ~(GPIO_CRL_CNF7 | GPIO_CRL_MODE7);
}
3. DMA,
;
extern uint16_t adc_buf[10];
void ADC_Init(void) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel1->CPAR = (uint32_t) &ADC1->DR;
DMA1_Channel1->CMAR = (unsigned int) adc_buf;
DMA1_Channel1->CNDTR = 10;
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
DMA1_Channel1->CCR |= DMA_CCR_MSIZE_0;
DMA1_Channel1->CCR |= DMA_CCR_PSIZE_0;
DMA1_Channel1->CCR |= DMA_CCR_MINC;
DMA1_Channel1->CCR |= DMA_CCR_CIRC;
DMA1_Channel1->CCR |= DMA_CCR_TCIE;
DMA1_Channel1->CCR |= DMA_CCR_EN;
NVIC_SetPriority(DMA1_Channel1_IRQn, 10);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
RCC->CFGR &= ~RCC_CFGR_ADCPRE;
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
ADC1->SQR3 = 0;
ADC1->SQR3 |= 1 << 5;
ADC1->SQR3 |= 2 << 10;
ADC1->SQR3 |= 3 << 15;
ADC1->SQR3 |= 4 << 20;
ADC1->SQR3 |= 5 << 25;
ADC1->SQR2 = 6;
ADC1->SQR2 |= 7 << 5;
ADC1->SQR2 |= 8 << 10;
ADC1->SQR2 |= 9 << 15;
ADC1->CR2 = ADC_CR2_EXTSEL_0 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_2
| ADC_CR2_EXTTRIG;
ADC1->SMPR1 = 0;
ADC1->SMPR2 = 0;
ADC1->SMPR2 |= (uint32_t) (6 << (0 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (1 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (2 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (3 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (4 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (5 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (6 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (7 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (8 * 3));
ADC1->SMPR2 |= (uint32_t) (6 << (9 * 3));
ADC1->SMPR1 |= (uint32_t) (6 << (0 * 3));
ADC1->CR2 |= ADC_CR2_ADON;
ADC1->CR2 |= ADC_CR2_RSTCAL;
while ((ADC1->CR2 & ADC_CR2_RSTCAL) == ADC_CR2_RSTCAL) {
}
ADC1->CR2 |= ADC_CR2_CAL;
while ((ADC1->CR2 & ADC_CR2_RSTCAL) == ADC_CR2_CAL) {
}
ADC1->SQR1 |= 9 << 20;
ADC1->CR1 |= ADC_CR1_SCAN;
ADC1->CR2 |= ADC_CR2_DMA;
ADC1->CR2 |= ADC_CR2_ADON;
}
4. ,
;
void TIM1_Init(void) {
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
TIM1->CCER = 0;
TIM1->ARR = 1000;
TIM1->PSC = 48 - 1;
TIM1->BDTR |= TIM_BDTR_MOE;
TIM1->CCR2 = 0;
TIM1->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
TIM1->CCER |= (TIM_CCER_CC2P |TIM_CCER_CC2E);
TIM1->CCR3 = 0;
TIM1->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
TIM1->CCER |= TIM_CCER_CC3NE;
TIM1->CCER &= ~TIM_CCER_CC3NP;
TIM1->CR1 |= TIM_CR1_CEN;
}
5. UART ,
;
void UART3_Init(void) {
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
USART3->BRR = 0xD0;
USART3->CR1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}
void UART3_Send(char chr) {
while (!(USART3->SR & USART_SR_TC))
;
USART3->DR = chr;
}
void UART3_Send_String(char* str) {
uint8_t i = 0;
while (str[i])
UART3_Send(str[i++]);
}
void UART3_Send_Number_Float(float data){
char str[100];
char *tmpSign = (data < 0) ? "-" : "";
float tmpVal = (data < 0) ? -data : data;
int tmpInt1 = tmpVal;
float tmpFrac = tmpVal - tmpInt1;
int tmpInt2 = trunc(tmpFrac * 10);
sprintf (str, "%s%d.%01d", tmpSign, tmpInt1, tmpInt2);
UART3_Send_String(str);
}
6. FreeRtos config
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( ( unsigned long ) 48000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 32 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define configKERNEL_INTERRUPT_PRIORITY 255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
#endif
7. main;
#include "main.h"
void vTaskUART2(void *argument);
void vTaskConvADC(void *argument);
uint32_t Motor(int32_t which, int32_t speed, int32_t turn);
void IndicatorLED(uint32_t number, uint32_t status);
#define MotorLeft 1
#define MotorRight 0
#define MoveBack 0
#define MoveForward 1
#define MaxSpeedMotor 1000
uint16_t adc_buf[10];
uint16_t SensWhiteOrBlack[10];
int main(void) {
RCC_Init();
GPIO_Init();
TIM1_Init();
UART3_Init();
ADC_Init();
xTaskCreate(vTaskUART2, "UART", 512, NULL, 1, NULL);
xTaskCreate(vTaskConvADC, "ADC", 128, NULL, 1, NULL);
UART3_Send_String("Start program\r\n");
GPIOA->BSRR |= GPIO_BSRR_BS10;
vTaskStartScheduler();
while (1) {
}
}
void vTaskUART2(void *argument) {
while (1) {
for (uint32_t i = 0; i <= 9; i++)
{
if (adc_buf[i] <= 300)
{
IndicatorLED(i, 0);
SensWhiteOrBlack[i] = 0;
} else
{
IndicatorLED(i, 1);
SensWhiteOrBlack[i] = 1;
}
}
float devMotorLeft = 1;
float devMotorRight = 1;
uint32_t flagSizeBuf = 0;
for (int32_t i = 6; i <= 9; i++)
{
if (SensWhiteOrBlack[i])
{
flagSizeBuf = 1;
if(i == 6 && SensWhiteOrBlack[i] == 1)
{
devMotorRight = 0.75;
}
else if(i == 7 && SensWhiteOrBlack[i] == 1)
{
devMotorRight = 0.5;
}
else if(i == 8 && SensWhiteOrBlack[i] == 1)
{
devMotorRight = 0.25;
}
else if(i == 9 && SensWhiteOrBlack[i] == 1)
{
devMotorRight = 0.0;
}
}
}
for(int32_t i = 5; i >= 0; i--)
{
if(SensWhiteOrBlack[i])
{
flagSizeBuf = 1;
if(i == 3 && SensWhiteOrBlack[i] == 1)
{
devMotorLeft = 0.75;
}
else if(i == 2 && SensWhiteOrBlack[i] == 1)
{
devMotorLeft = 0.5;
}
else if(i == 1 && SensWhiteOrBlack[i] == 1)
{
devMotorLeft = 0.25;
}
else if(i == 0 && SensWhiteOrBlack[i] == 1)
{
devMotorLeft = 0.0;
}
}
}
if(!flagSizeBuf)
{
devMotorLeft = 0;
devMotorRight = 0;
}
Motor(MotorRight, (int32_t)(MaxSpeedMotor * (float)devMotorRight), MoveForward);
Motor(MotorLeft, (int32_t)(MaxSpeedMotor * (float)devMotorLeft), MoveForward);
vTaskDelay(50);
}
}
void vTaskConvADC(void *argument) {
while (1) {
vTaskDelay(5000);
}
}
void IndicatorLED(uint32_t number, uint32_t status) {
if (number == 0 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS9;
}
else if (number == 0 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR9;
}
if (number == 1 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS8;
}
else if (number == 1 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR8;
}
if (number == 2 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS7;
}
else if (number == 2 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR7;
}
if (number == 3 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS6;
}
else if (number == 3 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR6;
}
if (number == 4 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS5;
}
else if (number == 4 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR5;
}
if (number == 5 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS4;
}
else if (number == 5 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR4;
}
if (number == 6 && status == 0) {
GPIOB->BSRR |= GPIO_BSRR_BS3;
}
else if (number == 6 && status == 1) {
GPIOB->BSRR |= GPIO_BSRR_BR3;
}
if (number == 7 && status == 0) {
GPIOA->BSRR |= GPIO_BSRR_BS15;
}
else if (number == 7 && status == 1) {
GPIOA->BSRR |= GPIO_BSRR_BR15;
}
if (number == 8 && status == 0) {
GPIOA->BSRR |= GPIO_BSRR_BS12;
}
else if (number == 8 && status == 1) {
GPIOA->BSRR |= GPIO_BSRR_BR12;
}
if (number == 9 && status == 0) {
GPIOA->BSRR |= GPIO_BSRR_BS11;
}
else if (number == 9 && status == 1) {
GPIOA->BSRR |= GPIO_BSRR_BR11;
}
}
uint32_t Motor(int32_t which, int32_t speed, int32_t turn) {
if (which == 0)
{
UART3_Send_Number_Float(speed);
UART3_Send_String("\t");
if (speed > 0 && speed <= 1000)
{
TIM1->CCR3 = speed;
if (turn == 0)
{
GPIOB->BSRR |= GPIO_BSRR_BS14;
}
else
{
GPIOB->BSRR |= GPIO_BSRR_BR14;
}
}
else
{
TIM1->CCR3 = 0;
GPIOB->BSRR |= GPIO_BSRR_BR14;
}
}
else if (which == 1)
{
UART3_Send_Number_Float(speed);
UART3_Send_String("\r\n");
if (speed > 0 && speed <= 1000)
{
TIM1->CCR2 = speed;
if (turn == 1)
{
GPIOA->BSRR |= GPIO_BSRR_BS8;
}
else
{
GPIOA->BSRR |= GPIO_BSRR_BR8;
}
}
else
{
TIM1->CCR2 = 0;
GPIOA->BSRR |= GPIO_BSRR_BS8;
}
}
return 0;
}
void DMA1_Channel1_IRQHandler(void) {
DMA1->IFCR = DMA_IFCR_CGIF1 | DMA_IFCR_CTCIF1;
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
DMA1_Channel1->CCR |= DMA_CCR_EN;
ADC1->CR2 |= ADC_CR2_ADON;
}