本帖最后由 Sam131208 于 2024-3-19 17:32 编辑
看起来与我的差不多,我主要用DMA来读取数据,节省电流。不过测试一直不正常。
static int spi_transceive(void* dev, uint8_t *tx, int16_t tx_len, uint8_t *rx, int16_t rx_len){
Spi_SetCS(dev, FALSE);
do{
while(Spi_GetStatus(dev, SpiTxe) == FALSE);
Spi_SendData(dev, *tx ++);
}while(--tx_len > 0);
while(Spi_GetStatus(dev, SpiTxe) == FALSE);
if(rx_len < 32){
while(rx_len -- > 0){
Spi_SendData(dev, 0x5a);
while(Spi_GetStatus(dev, SpiTxe) == FALSE);
*rx ++ = Spi_ReceiveData(dev);
}
}else{
stc_dma_cfg_t stcDmaCfg;
DDL_ZERO_STRUCT(stcDmaCfg); //结构体变量值清零
stcDmaCfg.enMode = DmaMskBlock; //选择块传输
stcDmaCfg.u16BlockSize = 0x01; //块传输个数
stcDmaCfg.u16TransferCnt = rx_len; //块传输次数,一次传输数据大小为 块传输个数*BUFFER_SIZE
stcDmaCfg.enTransferWidth = DmaMsk8Bit; //传输数据的宽度,此处选择字(8Bit)宽度
stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix; //源地址固定
stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc; //目的地址自增
stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //禁止重新加载传输目的地址
stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable; //禁止重新加载传输源地址
stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable; //禁止重新加载BC/TC值
stcDmaCfg.u32SrcAddress = (uint32_t)&((M0P_SPI_TypeDef*)dev)->DATA; //指定传输源地址
stcDmaCfg.u32DstAddress = (uint32_t)rx; //指定传输目的地址
stcDmaCfg.enRequestNum = (M0P_SPI0 == dev)?DmaSPI0RXTrig:DmaSPI1RXTrig; //设置为软件触发
stcDmaCfg.enTransferMode = DmaMskOneTransfer; //dma传输一次,DMAC传输完成时清除CONFA:ENS位
stcDmaCfg.enPriority = DmaMskPriorityFix; //各通道固定优先级,CH0优先级 > CH1优先级
Dma_InitChannel(DmaCh1,&stcDmaCfg);
Dma_Enable(); //使能DMA
Dma_ClrStat(DmaCh1);
Dma_EnableChannel(DmaCh1); //使能DmaCh1
}
Spi_SetCS(dev, TRUE);
return 0;
}
|