Untitled
unknown
c_cpp
3 years ago
5.3 kB
76
Indexable
#include "stm32f030x6.h"
#define t1 100
#define t2 200
#define t3 300
#define T0H 0xC0
#define T1H 0xFC
#define NUMBER_OF_LEDS 1
#define NUMBER_OF_BYTES (NUMBER_OF_LEDS * 24) + 64
uint8_t data_LED[NUMBER_OF_BYTES];
uint32_t time = 0;
void system_Clock_Init(void);
void GPIO_Init(void);
void Systick_Init(void);
void DMA_Init(void);
void SPI1_Init(void);
void WS2812_Send(void);
void clear_LEDS(void);
int main(void)
{
__disable_irq();
system_Clock_Init();
GPIO_Init();
Systick_Init();
DMA_Init();
SPI1_Init();
__enable_irq();
clear_LEDS();
WS2812_Send();
while(1)
{
//WS2812_Send();
if (time >= t1)
{
GPIOA->ODR ^= GPIO_ODR_0;
time = 0;
}
}
}
void SysTick_Handler(void)
{
time++;
}
void SPI1_IRQHandler(void)
{
DMA1_Channel3->CCR &= ~( DMA_CCR_EN );
}
void system_Clock_Init(void)
{
// Reset the Flash 'Access Control Register', and
// then set 1 wait-state and enable the prefetch buffer.
// (The device header files only show 1 bit for the F0
// line, but the reference manual shows 3...)
// 48MHz clock HSE
FLASH->ACR &= ~(0x00000017U);
FLASH->ACR |= (FLASH_ACR_LATENCY | FLASH_ACR_PRFTBE);
// ENABLE HSE and wait for the HSE to become Ready
RCC->CR |= RCC_CFGR_PLLSRC_HSE_PREDIV;
while (!(RCC->CR & (1<<17)));
// Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
RCC->APB1ENR |= 1<<28;
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PPRE_DIV1 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PLLMUL6;
RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV1;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while (!(RCC->CFGR & RCC_CFGR_SWS_PLL));
}
void GPIO_Init()
{
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //Enable GPIOA clock
GPIOA->AFR[0] &= ~(0xF0F00000); //Set PA6 pin to a alternate function mode
GPIOA->MODER |= GPIO_MODER_MODER0_0 | GPIO_MODER_MODER7_1 | GPIO_MODER_MODER5_1; //Set PA0 pin to output mode and PA6 to atlrnate mode
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_0);
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR5;
GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0);
}
void Systick_Init()
{
/* Configure SysTick */
SysTick->LOAD = 48000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 7;
NVIC_EnableIRQ(SysTick_IRQn);
NVIC_SetPriority(SysTick_IRQn, 1);
}
void DMA_Init()
{
// DMA configuration (channel 1).
// CCR register:
// - Memory-to-peripheral
// - Circular mode enabled.
// - Increment memory ptr, don't increment periph ptr.
// - -bit data size for both source and destination.
// - High priority.
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel3->CCR &= ~( DMA_CCR_MEM2MEM |
DMA_CCR_PL |
DMA_CCR_MSIZE |
DMA_CCR_PSIZE |
DMA_CCR_PINC |
DMA_CCR_EN );
DMA1_Channel3->CCR |= ( DMA_CCR_PL_1 |
DMA_CCR_MINC |
DMA_CCR_CIRC |
DMA_CCR_DIR );
// Set DMA source and destination addresses.
// Source: Address of the framebuffer.
DMA1_Channel3->CMAR = ( uint32_t )&data_LED;
// Destination: SPI1 data register.
DMA1_Channel3->CPAR = ( uint32_t )&( SPI1->DR );
// Set DMA data transfer length (framebuffer length).
DMA1_Channel3->CNDTR = ( uint16_t )NUMBER_OF_BYTES;
}
void SPI1_Init()
{
// SPI1 configuration:
// - Clock phase/polarity: 1/1
// - Assert internal CS signal (software CS pin control)
// - MSB-first
// - 8-bit frames
// - Baud rate prescaler of 8 (for a 6MHz bit-clock)
// - TX DMA requests enabled.
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
SPI1->CR1 &= ~( SPI_CR1_LSBFIRST |
SPI_CR1_BR );
SPI1->CR1 |= ( SPI_CR1_SSM |
SPI_CR1_SSI |
0x2 << SPI_CR1_BR_Pos |
SPI_CR1_MSTR |
SPI_CR1_CPOL |
SPI_CR1_CPHA );
SPI1->CR2 &= ~( SPI_CR2_DS );
SPI1->CR2 |= ( 0x7 << SPI_CR2_DS_Pos |
SPI_CR2_TXDMAEN | SPI_CR2_TXEIE);
// Enable the SPI peripheral.
SPI1->CR1 |= ( SPI_CR1_SPE );
//NVIC->ISER[0] |= (1u << 25);
NVIC_EnableIRQ(SPI1_IRQn);
NVIC_SetPriority(SPI1_IRQn, 2);
}
void WS2812_Send()
{
uint32_t index = 0;
for(int i = 0; i < NUMBER_OF_LEDS; i++)
{
for(int j = 0; j < 24; j++)
{
if(j == 8)
{
data_LED[index] = T1H;
index++;
}
else
{
data_LED[index] = T0H;
index++;
}
}
}
for(int i = 0; i < 64; i++)
{
data_LED[index] = 0x00;
index++;
}
// Enable DMA1 Channel 1 to start sending colors.
DMA1_Channel3->CCR |= ( DMA_CCR_EN );
}
void clear_LEDS()
{
uint32_t index = 0;
for(int i = 0; i < NUMBER_OF_LEDS; i++)
{
for(int j = 0; j < 24; j++)
{
data_LED[index] = T0H;
index++;
}
}
for(int i = 0; i < 64; i++)
{
data_LED[index] = 0x00;
index++;
}
// Enable DMA1 Channel 1 to start sending colors.
DMA1_Channel3->CCR |= ( DMA_CCR_EN );
}
Editor is loading...