本帖最后由 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;
- }
|