- 最近需要用华大的hc32l136的硬件SPI+DMA传输,瞎写很久没调好,看参考手册,瞎碰一天搞通了。。。 
- 先说下我之前犯的错误,也是最宝贵的经验,供参考 
- 没多看参考手册直接写(即使有点烂仍然提供了最高的参考价值。。。),重点看
SPI和DMAC章节 - 错误使用了
软件触发传输,测到的现象是前两个字节可以正确发送,后面的无论是发送数量和数据都对不上了,误以为软件触发可用,自己的配置有问题,实际测试软件触发和规格书讲的一样,是不可用的或者说是不可靠的 
  - 再说下正确的使用方式,文末会粘上测试代码 
- 关键点就一个,触发方式
不要选DmaSWTrig软件触发(至于最后实例能用的这个,从软件的角度看还是软件触发,但官方的角度似乎不认为这是软件触发,或许是软件触发SPI硬件再触发DMA所以叫硬件触发?不管也罢,,,) 
  
  - 语文课兴许没及格,下面是参考手册的一些相关描述,没看明白:
 
 
 - 先讲SPI支持软硬件访问
 
 2.再讲只支持硬件块传输模式,且SPI和系统时钟不同频时不支持硬件触发(官方对软件/硬件触发的解释不是很到位,至少和我理解的不太一样)
 
 - 但是spi时钟和系统时钟必然是不同频的,那硬件触发到底能不能用呢?
 
 - 再看,所谓的软件/硬件DMA传输模式就是软件/硬件请求方式不同,似乎哪个也不支持了。。。软硬件触发和软硬件传输似乎没有关系?
 
 
 
 
- 最后,还是实践出真知。。。
 - 测试程序参考,每200ms用SPI+DMA发送24个字节:
 
 
#define SPI_HANDLE M0P_SPI1
#define DMA_HANDLE DmaCh1uint8_t data_tx_test[24] =
{0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,
};
static void App_GpioInit(void)		
{stc_gpio_cfg_t           stcPortCfg;DDL_ZERO_STRUCT(stcPortCfg);							Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); stcPortCfg.enDrv = GpioDrvH;stcPortCfg.enDir  = GpioDirOut;Gpio_Init(LCD_BK_PORT, LCD_BK_PIN, &stcPortCfg);  Gpio_Init(LCD_CS_PORT, LCD_CS_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_CS_PORT, LCD_CS_PIN,GpioAf1); 				Gpio_Init(LCD_RESET_PORT, LCD_RESET_PIN, &stcPortCfg);  Gpio_Init(LCD_WR_PORT, LCD_WR_PIN, &stcPortCfg);  Gpio_Init(LCD_SCK_PORT, LCD_SCK_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_SCK_PORT, LCD_SCK_PIN,GpioAf1);  			Gpio_Init(LCD_SDA_PORT, LCD_SDA_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_SDA_PORT, LCD_SDA_PIN,GpioAf1);  			
}static void App_SPIInit(void)
{stc_spi_cfg_t  SpiInitStruct;Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi1,TRUE);SpiInitStruct.enSpiMode = SpiMskMaster;   		SpiInitStruct.enPclkDiv = SpiClkMskDiv2;  		SpiInitStruct.enCPOL    = SpiMskcpolhigh;  		SpiInitStruct.enCPHA 	= SpiMskCphasecond; 	Spi_Init(SPI_HANDLE, &SpiInitStruct);Spi_FuncEnable(SPI_HANDLE,SpiMskDmaTxEn);		
}static void App_DmaCfg(void)
{ stc_dma_cfg_t stcDmaCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE); 			DDL_ZERO_STRUCT(stcDmaCfg);stcDmaCfg.enMode =  DmaMskBlock;                           		stcDmaCfg.u16BlockSize = 1;                             		stcDmaCfg.u16TransferCnt = 24;                    				stcDmaCfg.enTransferWidth = DmaMsk8Bit;                   		stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc;                		stcDmaCfg.enDstAddrMode = DmaMskDstAddrFix;                		stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable;		stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable;		stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable;			stcDmaCfg.u32SrcAddress = (uint32_t)&data_tx_test[0]; 			stcDmaCfg.u32DstAddress = (uint32_t)&(M0P_SPI1->DATA);    		stcDmaCfg.enRequestNum = DmaSPI1TXTrig;                        	stcDmaCfg.enTransferMode = DmaMskOneTransfer;              		stcDmaCfg.enPriority = DmaMskPriorityFix;                  		Dma_InitChannel(DMA_HANDLE,&stcDmaCfg);                        	Dma_Enable();
}void dma_test(void)
{en_dma_stat_t ste;while(1){ delay1ms(200);M0P_SPI1->SSN = FALSE;Dma_EnableChannel(DMA_HANDLE);								ste = Dma_GetStat(DMA_HANDLE);while(ste != DmaTransferComplete){ste = Dma_GetStat(DMA_HANDLE);}M0P_SPI1->SSN = TRUE;}
}void demo(void)
{App_GpioInit();App_DmaCfg();App_SPIInit();dma_test();
}
 
- 实测SPI主机发送ok:
 