Untitled
unknown
c_cpp
a year ago
5.3 kB
30
Indexable
Never
#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 ); }