Вт май 16, 2023 11:05:43
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*
*@Note
USART Print debugging routine:
USART1_Tx(PA9).
This example demonstrates using USART1(PA9) as a print debug port output.
*/
#include "debug.h"
#include "ws2812.h"
/* Global typedef */
/* Global define */
/* Global Variable */
//TIM_TypeDef timer_handle;
TIM_TimeBaseInitTypeDef time_base_init = {0};
TIM_OCInitTypeDef timer_output_cfg = {0};
DMA_InitTypeDef dma_leds = {0};
void Timer_PWM_Init();
void DMA_LEDs_Init();
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
printf("This is printf example\r\n");
Timer_PWM_Init();
DMA_LEDs_Init();
// while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
ws2812_init(TIM1);
ws2812_set_pixel(0, 0, 0, 0);
ws2812_show();
int i = 0;
while(1)
{
printf("OK\r\n");
Delay_Ms(1000);
ws2812_set_pixel(0, i++, 0, 0);
ws2812_show();
}
}
// Init Timer for PWM (PA8)
void Timer_PWM_Init() {
GPIO_InitTypeDef GPIO_PWMInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
GPIO_PWMInitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_PWMInitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_PWMInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_PWMInitStructure );
// GPIO_PinRemapConfig(AFIO_PCFR1_PD01_REMAP, DISABLE);
time_base_init.TIM_ClockDivision = TIM_CKD_DIV1;
time_base_init.TIM_Period = 126;
time_base_init.TIM_CounterMode = TIM_CounterMode_Up;
time_base_init.TIM_Prescaler = 0;
time_base_init.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &time_base_init);
timer_output_cfg.TIM_OCMode = TIM_OCMode_PWM1;
timer_output_cfg.TIM_OutputState = TIM_OutputState_Enable;
timer_output_cfg.TIM_OCPolarity = TIM_OCPolarity_High;
// timer_output_cfg.TIM_OCIdleState = 0;
// timer_output_cfg.TIM_OCNIdleState = 0;
timer_output_cfg.TIM_Pulse = 0;
// TIM_DMAConfig(TIM1, TIM_DMABase, TIM_DMABurstLength)
TIM_OC1Init(TIM1, &timer_output_cfg);
TIM_CtrlPWMOutputs(TIM1, ENABLE );
TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
TIM_ARRPreloadConfig( TIM1, ENABLE );
TIM_Cmd( TIM1, ENABLE );
}
void DMA_LEDs_Init() {
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );
NVIC_SetPriority(DMA1_Channel1_IRQn,0xE0);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
dma_leds.DMA_PeripheralBaseAddr = (u32)TIM1->DMAADR;
dma_leds.DMA_MemoryBaseAddr = (u32)get_ws2812b_array_ptr();
dma_leds.DMA_DIR = DMA_DIR_PeripheralDST;
dma_leds.DMA_BufferSize = LED_ARRAY_LEN*2;
dma_leds.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_leds.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_leds.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma_leds.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
dma_leds.DMA_Mode = DMA_Mode_Normal;
dma_leds.DMA_Priority = DMA_Priority_High;
dma_leds.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &dma_leds);
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
DMA_ClearFlag(DMA1_FLAG_TC1);
DMA_Cmd(DMA1_Channel1, ENABLE);
}
/*********************************************************************
* @fn DMA1_Channel1_IRQHandler
*
* @brief This function DMA1 Channel1 exception.
*
* @return none
*/
void DMA1_Channel1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel1_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC1))
{
// TIM_Cmd(TIM1, DISABLE);
// TIM_DMACmd(TIM1, DMA1_Channel1, NewState)
DMA_ClearITPendingBit(DMA1_IT_TC1|DMA1_IT_GL1|DMA1_IT_HT1);
}
}
/*
* ws2812.c
*
* Created on: May 4, 2023
* Author: dmitr
*/
#include "ws2812.h"
uint16_t BUF_DMA[LED_ARRAY_LEN] = {0};
TIM_TypeDef * timer_handle = NULL;
int ws2812_init(TIM_TypeDef * th)
{
if (!th) return -1;
else timer_handle = th;
ws2812_clear_buffer();
return 0;
}
void ws2812_clear_buffer() {
for(int i=0;i<(LED_ARRAY_LEN-DELAY_LEN);i++) BUF_DMA[i] = LOW;
}
uint32_t * get_ws2812b_array_ptr() {
return &BUF_DMA;
}
void byte_to_sequence(uint8_t byte_to_convert, uint16_t * seq) {
for (int i = 7; i <= 0; i--) {
if (((byte_to_convert>>i) & 1) == 0) seq[i] = LOW;
else seq[i] = HIGH;
}
}
void copy_sequence_to_position(uint32_t position, int sp_offset, uint16_t * seq, uint16_t * led_array) {
if (position > LED_COUNT) position = LED_COUNT;
if (sp_offset > 2) sp_offset = 2;
if (sp_offset < 0) sp_offset = 0;
for (int i = 0; i < 8; i++) led_array[position+8*sp_offset+i] = seq[i];
}
void ws2812_set_pixel(uint32_t pixel_num, uint8_t r, uint8_t g, uint8_t b) {
if (pixel_num > LED_COUNT) pixel_num = LED_COUNT;
uint16_t tmp[8];
byte_to_sequence(r, &tmp);
copy_sequence_to_position(pixel_num, 0, &tmp, &BUF_DMA);
byte_to_sequence(g, &tmp);
copy_sequence_to_position(pixel_num, 1, &tmp, &BUF_DMA);
byte_to_sequence(b, &tmp);
copy_sequence_to_position(pixel_num, 2, &tmp, &BUF_DMA);
}
void ws2812_show() {
DMA_Cmd(DMA1_Channel1, ENABLE);
}
/*
* ws2812.h
*
* Created on: May 4, 2023
* Author: dmitr
*/
#ifndef USER_WS2812_H_
#define USER_WS2812_H_
#include "stdio.h"
#include "stdint.h"
#include "ch32v30x.h"
#include "ch32v30x_tim.h"
#include "ch32v30x_dma.h"
//----------
#define DELAY_LEN 48
#define LED_COUNT 8
#define LED_ARRAY_LEN DELAY_LEN + LED_COUNT*24
#define HIGH 0x8A3D // 54%
#define LOW 0x3AE1 // 23%
int ws2812_init(TIM_TypeDef * th);
uint32_t * get_ws2812b_array_ptr();
void ws2812_set_pixel(uint32_t pixel_num, uint8_t r, uint8_t g, uint8_t b);
void ws2812_clear_buffer();
void ws2812_show();
#endif /* USER_WS2812_H_ */
Ср май 17, 2023 08:51:29
Ср май 17, 2023 13:05:45
Ср май 17, 2023 13:07:02
void DMA1_Channel2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel2_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC2) != RESET) {
DMA_ClearITPendingBit(DMA1_IT_TC2);
}
if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) {
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
}
// Вставить настройку таймера для нового запроса
// time_base_init.TIM_Period = 126;
TIM1->CNT = 0;
DMA_Cmd(DMA1_Channel2, DISABLE);
TIM_DMACmd(TIM1, TIM_DMA_CC1, DISABLE);
TIM_Cmd(TIM1, DISABLE);
TIM_ITConfig(TIM1, TIM_IT_CC1, DISABLE);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
x++;
}
void ws2812_show() {
TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_Cmd(TIM1, ENABLE);
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
DMA_Cmd(DMA1_Channel2, ENABLE);
}
Ср май 17, 2023 17:30:47
Ср май 17, 2023 17:42:38
Чт май 18, 2023 11:57:34
Чт май 18, 2023 12:20:56
Сб май 20, 2023 01:10:11
// Init Timer for PWM (PA8)
void Timer_PWM_Init() {
GPIO_InitTypeDef GPIO_PWMInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
GPIO_PWMInitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_PWMInitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_PWMInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_PWMInitStructure );
GPIO_PinRemapConfig(AFIO_PCFR1_TIM1_REMAP_FULLREMAP, ENABLE);
time_base_init.TIM_ClockDivision = TIM_CKD_DIV4;
time_base_init.TIM_Period = 99;
time_base_init.TIM_CounterMode = TIM_CounterMode_Up;
time_base_init.TIM_Prescaler = 0;
time_base_init.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &time_base_init);
timer_output_cfg.TIM_OCMode = TIM_OCMode_PWM1;
timer_output_cfg.TIM_OutputState = TIM_OutputState_Enable;
timer_output_cfg.TIM_OCPolarity = TIM_OCPolarity_Low;
timer_output_cfg.TIM_OCIdleState = 0;
// timer_output_cfg.TIM_OCNIdleState = 0;
timer_output_cfg.TIM_Pulse = 10; // Если выставлять больше, уровень будет резко меняться, в конечном итоге выставится сплошной уровень по выходу ШИМ. HIGH 0x8F5C LOW 0x47AE
// TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_1Transfer);
// TIM_DMACmd(TIM1, TIM_DMA_CC1, DISABLE);
TIM_OC1Init(TIM1, &timer_output_cfg);
TIM_CtrlPWMOutputs(TIM1, ENABLE );
TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
TIM_ARRPreloadConfig( TIM1, ENABLE );
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
NVIC_EnableIRQ(TIM1_CC_IRQn);
TIM_Cmd( TIM1, ENABLE );
}
Сб май 20, 2023 17:54:16
Ср май 31, 2023 20:59:37