新手入门
- 积分
- 8
- 金钱
- 8
- 注册时间
- 2022-9-6
- 在线时间
- 2 小时
|
7金钱
最近弄个ws2812,而且还是gd32系列的,所以一点整的我一点头痛了都,就是一块灯板上一共有423个灯珠,是用pwm+dma来驱动,但是现在只能控制前面的93个灯珠,却不能控制后面的那些灯珠,只要过了第93个灯珠,后面的灯珠就不受控了,颜色是随机显示的,希望哪位大佬帮我看看问题的所在,,指点指点
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32f307c_eval.h"
#define T1H#define T0H 160 //65
// LED灯珠数量
#define LED_NUM 105 //500个bit的时候,可以亮18颗,每增加100就可以亮多四颗。//11是开始的亮一颗,15就三个灯珠亮,17的话就四个灯珠亮,所以每加亮一颗就需要在11的基础上加2
// TIMER0_CH0, 这个查对照表
#define TIMER3_CH0CV ((uint32_t)0x40000834)
#define TRANSFER_NUM ((24 * LED_NUM)+6000)
uint8_t LEDlen;
uint16_t dma_ws2812_buffer[TRANSFER_NUM];
void gpio_config(void);
void timer_config(void);
void dma_config(void);
void gpio_config(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
/*configure PA8(TIMER0 CH0) as alternate function*/
gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
}
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
void dma_config(void)
{
dma_parameter_struct dma_init_struct;
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA0);
/* initialize DMA channel5 */
dma_deinit(DMA0,DMA_CH0);
/* DMA channel5 initialize */
dma_init_struct.periph_addr = (uint32_t)TIMER3_CH0CV; //外设的基地址
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //不设置递增,每一次传输地址不加一
dma_init_struct.memory_addr = (uint32_t)dma_ws2812_buffer; //内存基地址
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //内存的基地址,每一次传输地址加一
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;//外设的数据宽度为半字(16bit)传输
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; //内存的数据宽度为半字(16bit)传输
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; //传输方向为内存向外设传输数据
dma_init_struct.number = TRANSFER_NUM; //这个为每次传输的数据量大小,比如ws2815为(24*有多少个灯珠+复位时间)
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; //这个是dma被中断后的响应优先级
dma_init(DMA0,DMA_CH0,&dma_init_struct);
dma_circulation_enable(DMA0,DMA_CH0);
dma_memory_width_config(DMA0,DMA_CH0,DMA_MEMORY_WIDTH_8BIT);
dma_memory_to_memory_disable(DMA0,DMA_CH0);
/* enable DMA channel5 */
dma_channel_enable(DMA0,DMA_CH0);
}
void timer_config(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER3);
timer_deinit(TIMER3);
timer_struct_para_init(&timer_initpara);
/* TIMER0 configuration */
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 245;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER3,&timer_initpara);
/* CH0 configuration in PWM1 mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER3,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER3,TIMER_CH_0,0);
timer_channel_output_mode_config(TIMER3,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER3,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
/* TIMER0 primary output enable */
timer_primary_output_config(TIMER3,ENABLE);
/* TIMER0 update DMA request enable */
/* auto-reload preload enable */
timer_dma_transfer_config(TIMER3,TIMER_DMACFG_DMATA_CH0CV,TIMER_DMACFG_DMATC_10TRANSFER);
timer_dma_enable(TIMER3, TIMER_DMA_CH0D);
timer_auto_reload_shadow_enable(TIMER3);
/* TIMER0 counter enable */
timer_enable(TIMER3);
}
AUAR AuarTable;
void WS6812_ledsingle_send2(uint8_t color[][3], uint16_t len)//第一个是定义的数组是确定是哪一个灯的哪一个颜色,第二个是灯珠的数量
{
uint16_t i=0;
uint16_t j=0;
uint16_t memaddr =0;
uint16_t AuarRGBTableBuf[3];
AuarTable.Dimmer=255;
if(memaddr < 300 )//ws2812,开始需要300us的低电平来复位
{
dma_ws2812_buffer[memaddr] = 00;
memaddr++;
}
for(j=0;j<len;j++)
{
AuarRGBTableBuf[0]=color[j][0]*AuarTable.Dimmer/255;
AuarRGBTableBuf[1]=color[j][1]*AuarTable.Dimmer/255;
AuarRGBTableBuf[2]=color[j][2]*AuarTable.Dimmer/255;
for(i=0; i<8; i++) // GREEN data
{
dma_ws2812_buffer[memaddr] = ((AuarRGBTableBuf[1]<<i) & 0x0080) ? T1H:T0H;
memaddr++;
}
for(i=0; i<8; i++) // RED
{
dma_ws2812_buffer[memaddr] = ((AuarRGBTableBuf[0]<<i) & 0x0080) ? T1H:T0H;
memaddr++;
}
for(i=0; i<8; i++) // BLUE
{
dma_ws2812_buffer[memaddr] = ((AuarRGBTableBuf[2]<<i) & 0x0080) ? T1H:T0H;
memaddr++;
}
}
if(memaddr<TRANSFER_NUM)//后面结束时不知道为什么会是高电平,所以加一个低电平
{
dma_ws2812_buffer[memaddr] = 0;
memaddr++;
}
}
void DealAuarDate(AUAR *AUARTa)
{
uint16_t number = 110;
uint16_t i=0,j=0;
for(i=0;i<number;i++)
{
AUARTa->RGBTable[i][0]=250;//255;//AUARTa->Blue;//Effect_Table.HSIRGB[0]; blue 0;//green//
AUARTa->RGBTable[i][1]=0;//255;//AUARTa->RED;//Effect_Table.HSIRGB[1];red255;//red//
AUARTa->RGBTable[i][2]=0;//255;// AUARTa->Green;//Effect_Table.HSIRGB[2]; green0;//blue//
}
WS6812_ledsingle_send2(AUARTa->RGBTable,number);
}
int main(void)
{
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
systick_config();
gpio_config();
dma_config();
timer_config();
while (1)
{
DealAuarDate(&AuarTable);
}
}
|
|