CH32V307 LVGL SPI DMA無法進入DMA中斷

void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)

{

? ? NVIC_InitTypeDef? NVIC_InitStructure;

? ? RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);? //使能DMA傳輸


? DMA_DeInit(DMA_CHx);? ?//將DMA的通道1寄存器重設(shè)為缺省值

? ? DMA1_MEM_LEN=cndtr;

? ? DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;? //DMA外設(shè)ADC基地址

? ? DMA_InitStructure.DMA_MemoryBaseAddr = cmar;? //DMA內(nèi)存基地址

? ? DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;? //數(shù)據(jù)傳輸方向,從內(nèi)存讀取發(fā)送到外設(shè)

? ? DMA_InitStructure.DMA_BufferSize = cndtr;? //DMA通道的DMA緩存的大小

? ? DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;? //外設(shè)地址寄存器不變

? ? DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;? //內(nèi)存地址寄存器遞增

? ? DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte? ;? //數(shù)據(jù)寬度為8位

? ? DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte? ?; //數(shù)據(jù)寬度為8位

? ? DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;? //工作在正常緩存模式

? ? DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x擁有中優(yōu)先級

? ? DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;? //DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?/span>

? ? DMA_Init(DMA_CHx, &DMA_InitStructure);? //根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道USART1_Tx_DMA_Channel所標(biāo)識的寄存器



? ? NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;

? ? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

? ? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

? ? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

? ? NVIC_Init(&NVIC_InitStructure);

? ? DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);? //使能DMA傳輸完成中斷


}?



/*************************************************************************************************************/


//? ? int32_t x;

//? ? int32_t y;

//? ? for(y = area->y1; y <= area->y2; y++) {

//? ? ? ? for(x = area->x1; x <= area->x2; x++) {

//? ? ? ? ? ? /*Put a pixel to the display. For example:*/

//? ? ? ? ? ? /*put_px(x, y, *color_p)*/

//? ? ? ? ? ? LCD_DrawPoint(x, y, color_p->full);

//? ? ? ? ? ? color_p++;

//? ? ? ? }

//? ? }


//? ? u16 height, width;

//? ? uint32_t y=0;

//? ? ? ? width = area->x2 -area->x1 + 1;

//? ? ? ? height = area->y2 -area->y1 + 1;

//? ? ? ? LCD_Address_Set(area->x1,area->y1,area->x2,area->y2);

//? ? ? ? for(y = 0; y

//? ? ? ? ? ? ? ? {

//? ? ? ? ? ? LCD_WR_DATA(color_p->full);

//? ? ? ? ? ? ? ? ? ? color_p++;

//? ? ? ? ? ? ? ? }

? ? void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

? ? void DMA1_Channel3_IRQHandler(void);

? ? ? {

? ? ? ? ? if(DMA_GetITStatus(DMA1_IT_TC3))

? ? ? ? ? {

? ? ? ? ? ? ? printf("進入DMA中斷\r\n");? ? ? ? ? ? ? ? ? ? ?//無法打印

? ? ? ? ? ? ? lv_disp_flush_ready(disp_drv);

? ? ? ? ? ? ? DMA_ClearITPendingBit(DMA1_IT_TC3); //清除全部中斷標(biāo)志

? ? ? ? ? }

? ? ? }

? ? LCD_Fill(area->x1,area->y1,area->x2,area->y2,color_p->full);



/*************************************************************************************************************/


void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)? ? ? ? ? ? ? ? ?//LCD打印函數(shù)

{? ? ? ? ??

? ? u16 color1[1];

? ? u16 num;

? ? color1[0]=color;

? ? num=(xend-xsta+1)*(yend-ysta+1)*2;

? ? LCD_Address_Set(xsta,ysta,xend,yend);//設(shè)置顯示范圍

? ? LCD_CS_Clr();

? ? MYDMA_Config(DMA1_Channel3,(u32)&SPI1->DATAR,(u32)color1,num);

? ? SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);

? ? MYDMA_Enable(DMA1_Channel3);

? ? LCD_CS_Set();


}



/*************************************************************************************************************/

如果不用DMA,使用以下函數(shù)之一是可以打印的

//? ? int32_t x;

//? ? int32_t y;

//? ? for(y = area->y1; y <= area->y2; y++) {

//? ? ? ? for(x = area->x1; x <= area->x2; x++) {

//? ? ? ? ? ? /*Put a pixel to the display. For example:*/

//? ? ? ? ? ? /*put_px(x, y, *color_p)*/

//? ? ? ? ? ? LCD_DrawPoint(x, y, color_p->full);

//? ? ? ? ? ? color_p++;

//? ? ? ? }

//? ? }


//? ? u16 height, width;

//? ? uint32_t y=0;

//? ? ? ? width = area->x2 -area->x1 + 1;

//? ? ? ? height = area->y2 -area->y1 + 1;

//? ? ? ? LCD_Address_Set(area->x1,area->y1,area->x2,area->y2);

//? ? ? ? for(y = 0; y

//? ? ? ? ? ? ? ? {

//? ? ? ? ? ? LCD_WR_DATA(color_p->full);

//? ? ? ? ? ? ? ? ? ? color_p++;

//? ? ? ? ? ? ? ? }


我在DMA中斷初始化中加入了,

NVIC_EnableIRQ(DMA1_Channel3_IRQn);

但是還是沒有觸發(fā)中斷打印。


程序里定時器中斷是可以正常打印的。但是打印一段后停住了,應(yīng)該是dma這個過程中有什么問題。我無法解決,已經(jīng)困擾相當(dāng)一段時間了。


我選擇用其它的刷新函數(shù)了,雖然速度會慢。


您好,目前從你貼的代碼暫時沒看出什么問題,有幾個點你可以注意一下:

1、檢查一下工程文件的配置是否正確,如啟動文件、ch32v30x.h文件中相關(guān)宏定義以及l(fā)d文件中FLASH、RAM大小的配置

2、程序中在初始化的時候建議將相關(guān)結(jié)構(gòu)體清零,具體可參考附件例程;

3、程序中若使用到中斷,建議初始化時將相關(guān)的中斷標(biāo)志位清零;

4、若無法打印,檢查一下是不是因為沒有調(diào)用相關(guān)頭文件;

5、程序中若要修改DMA傳輸?shù)臄?shù)據(jù)長度,建議可參考一下附件例程的操作方式;

附件為一個SPI使用DMA驅(qū)屏的例程,你可以參考一下。若方便,可以把你的工程文件發(fā)到我的郵箱(lzs@wch.cn)這邊具體看一下,后續(xù)問題的溝通也可以通過郵箱和我溝通。

icon_rar.gifCH32V307 硬件SPI_DMA LCD.zip



沁恒給的DMA中斷仍舊是8位雙發(fā)2次湊成16位數(shù)據(jù)

u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)

{

#if USE_DMA==1

? ? TxData[0] = Byte;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//往緩沖區(qū)中寫入數(shù)據(jù)

? ? DMA1_Channel5->CNTR = 1;? ? ? ? ? ? ? ? ? ? ? ? ? //填寫要傳輸?shù)臄?shù)據(jù)長度

? ? DMA_Cmd(DMA1_Channel5,ENABLE);? ? ? ? ? ? ? ? ? ? //開啟DMA傳輸

? ? while( DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET);//等待傳輸完成

? ? DMA_Cmd(DMA1_Channel5,DISABLE);? ? ? ? ? ? ? ? ? ?//關(guān)閉DMA

? ? DMA_ClearFlag(DMA1_FLAG_TC5);? ? ? ? ? ? ? ? ? ? ?//清除標(biāo)志

#else

? ? while((SPIx->STATR&SPI_I2S_FLAG_TXE)==RESET);? ? //等待發(fā)送區(qū)空

? ? SPIx->DATAR=Byte;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送一個byte

? ? while((SPIx->STATR&SPI_I2S_FLAG_RXNE)==RESET);? ?//等待接收完一個byte

? ? return SPIx->DATAR;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //返回收到的數(shù)據(jù)

#endif


#if USE_DMA==1

? ? return 0;

#endif

}


void Lcd_WriteData_16Bit(u16 Data)

{

? ? Lcd_WriteData(Data>>8);? ? ? ? ? ?//16位數(shù)據(jù)高8位先行

? ? Lcd_WriteData(Data);????????????????? ?//16位數(shù)據(jù)低8位,color_p->full為16位

}



這其實并沒有給優(yōu)化速度提高多少,以下是我的刷新函數(shù)

? ? u16 height, width;

? ? ? ? uint32_t y=0;

? ? ? ? ? ? width = area->x2-area->x1+1 ;

? ? ? ? ? ? height = area->y2-area->y1+1;

? ? ? ? ? ?Lcd_SetRegion(area->x1,area->y1,area->x2,area->y2);

? ? ? ? ? ? for(y = 0; y

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? Lcd_WriteData_16Bit(color_p->full);

? ? ? ? ? ? ? ? ? ? ? ? color_p++;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? lv_disp_flush_ready(disp_drv);

進入刷新函數(shù)里每次cpu都要執(zhí)行y++,這和DMA初衷不符,當(dāng)然也拖慢了運行速度。DMA的使用應(yīng)該建造一個大數(shù)組,將存儲地址賦給這個數(shù)組起始地址,然后執(zhí)行數(shù)據(jù)傳輸,釋放CPU。這種方法適合畫大圖,而不是單單打點。

當(dāng)驅(qū)動240*320畫面時,DMA的U16的數(shù)據(jù)的大小并不夠。傳遞字節(jié)數(shù)應(yīng)該是320*240*2,我想嘗試分4次進行DMA傳輸,但失敗了。我不知道是什么原因,難道也要進行數(shù)據(jù)移位嗎?



另外還有一個有意思的是,我的系統(tǒng)時鐘是144Mhz,我給SPI進行的2分頻,那它的速度應(yīng)該是72Mhz,而我看數(shù)據(jù)手冊SPI時鐘最高36Mhz。然而當(dāng)我進行4分頻的時候,也就是36Mhz,屏幕變成一片白,而72Mhz卻沒有問題。

1699466832185911.png

1699466832177428.png

1699466843195678.jpg


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频