這個(gè)數(shù)組口算都超4K,而V003只有2K的RAM
#define PIXEL_NUM? ? ? ?72? ? ? ? ? // LED的數(shù)量
#define NUM? ? ? ? ? ? ?(24*PIXEL_NUM + 100)? //LED顏色數(shù)組
工程包:
看到5*社區(qū)有一個(gè)帖子說可以用DMA雙緩沖進(jìn)行搬運(yùn)RGB顏色數(shù)據(jù),從而降低RAM,
求助CH32如何配置。
配合AI自行摸索(剛學(xué)編程多擔(dān)待):
#include "debug.h"
#define PIXEL_NUM? ? ? ?72? ? ? ? ? // 定義LED的數(shù)量
#define BUFFER_SIZE? ? ?(24 * 2)? ? // 每個(gè)緩沖區(qū)大小為2個(gè)WS2812像素的數(shù)據(jù)大?。?6字節(jié))
#define WS1? ? ? ? ? ? ?43? ? ? ? ? ? // PWM高電平的時(shí)間長(zhǎng)度,對(duì)應(yīng)0.9us
#define WS0? ? ? ? ? ? ?14? ? ? ? ? ? // PWM低電平的時(shí)間長(zhǎng)度,對(duì)應(yīng)0.3us
#define TIM2_CH2CVR_ADDRESS? ? 0x40000038? ? // TIM2_UP是DMA的通道2, 比較/捕獲寄存器
int16_t pixel_buffer1[BUFFER_SIZE];
int16_t pixel_buffer2[BUFFER_SIZE];
volatile int current_buffer = 0;
volatile uint16_t pixel_index = 0;
// 初始化TIM2 PWM輸出
void TIM2_PWMOut_Init(u16 arr, u16 psc, u16 ccp) {
//
}
// 初始化DMA傳輸
void TIM2_DMA_Init(DMA_Channel_TypeDef *DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize) {
? ? DMA_InitTypeDef DMA_InitStructure = {0};
? ? RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
? ? DMA_DeInit(DMA_CHx);
? ? DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr;? ? ?// 外設(shè)地址
? ? DMA_InitStructure.DMA_MemoryBaseAddr = memadr;? ? ? ?// 內(nèi)存地址
? ? DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;? ?// 數(shù)據(jù)傳輸方向:內(nèi)存到外設(shè)
? ? DMA_InitStructure.DMA_BufferSize = bufsize;? ? ? ? ? // 緩沖區(qū)大小
? ? DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;? // 不遞增外設(shè)地址
? ? DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;? ? ? ? ? ?// 遞增內(nèi)存地址
? ? DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 半字?jǐn)?shù)據(jù)大小
? ? DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;? ? ? ? ?// 半字?jǐn)?shù)據(jù)大小
? ? DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;? ? ? ? ? ? ? ? ? ? ? ? ?// 循環(huán)模式
? ? DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;? ? ? ? ? ? ? ? ?// 最高優(yōu)先級(jí)
? ? DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;? ? ? ? ? ? ? ? ? ? ? ? ? ? // 禁止內(nèi)存到內(nèi)存?zhèn)鬏?/p>
? ? DMA_Init(DMA_CHx, &DMA_InitStructure);
? ? DMA_ITConfig(DMA_CHx, DMA_IT_TC | DMA_IT_HT, ENABLE); // 啟用半傳輸和全傳輸中斷
? ? DMA_Cmd(DMA_CHx, ENABLE);? ? // 使能DMA通道
}
// 搬運(yùn)
void DMA1_Channel2_IRQHandler(void) {
? ? if (DMA_GetITStatus(DMA1_IT_HT2)) {? // 半傳輸中斷
? ? ? ? // MCU 準(zhǔn)備好下一組像素的數(shù)據(jù),寫入到未被DMA使用的緩沖區(qū)
? ? ? ? uint32_t color = Wheel(pixel_index++ % 256);
? ? ? ? WS281x_SetPixelColor(current_buffer ? pixel_buffer1 : pixel_buffer2, 0, color);
? ? ? ? color = Wheel(pixel_index++ % 256);
? ? ? ? WS281x_SetPixelColor(current_buffer ? pixel_buffer1 : pixel_buffer2, 1, color);
? ? ? ? DMA_ClearITPendingBit(DMA1_IT_HT2);
? ? }
? ? if (DMA_GetITStatus(DMA1_IT_TC2)) {? // 傳輸完成中斷
? ? ? ? // MCU 準(zhǔn)備好下一組像素的數(shù)據(jù),寫入到未被DMA使用的緩沖區(qū)
? ? ? ? uint32_t color = Wheel(pixel_index++ % 256);
? ? ? ? WS281x_SetPixelColor(current_buffer ? pixel_buffer1 : pixel_buffer2, 0, color);
? ? ? ? color = Wheel(pixel_index++ % 256);
? ? ? ? WS281x_SetPixelColor(current_buffer ? pixel_buffer1 : pixel_buffer2, 1, color);
? ? ? ? DMA_ClearITPendingBit(DMA1_IT_TC2);
? ? }
}
int main(void) {
? ? USART_Printf_Init(115200);
? ? printf("SystemClk:%d\r\n", SystemCoreClock);
? ? Delay_Init();
? ? // 初始化所有像素為關(guān)閉狀態(tài)
? ? WS_Write_RGB_to_Buffer(0x0, 0, 0, pixel_buffer1);
? ? WS_Write_RGB_to_Buffer(0x0, 0, 0, pixel_buffer2);
? ? TIM2_PWMOut_Init(57, 0, 0); // 調(diào)整周期值、高電平、低電平時(shí)間
? ? TIM2_DMA_Init(DMA1_Channel2, (u32)TIM2_CH2CVR_ADDRESS, (u32)pixel_buffer1, BUFFER_SIZE);? ? // 初始化DMA傳輸
? ? NVIC_InitTypeDef NVIC_InitStructure;
? ? NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
? ? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
? ? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
? ? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
? ? NVIC_Init(&NVIC_InitStructure);
? ? TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);? ? // 使能TIM2的DMA更新功能
? ? TIM_Cmd(TIM2, ENABLE);? ? // 使能TIM2
? ? TIM_CtrlPWMOutputs(TIM2, ENABLE);? ? // 使能TIM2的PWM輸出
? ? while (1) {
? ? }
}