打印
[技术问答]

申请HC32L系列的SPI+DMA读写flash的代码

[复制链接]
5602|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Sam131208|  楼主 | 2024-3-19 08:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
HC32L系列的DMA例程都是关于ADC、RAM的,没有关于I2S, SPI这些外设使用的例程,建议增加这类常用的外设例程。

使用特权

评论回复
沙发
ysf| | 2024-3-19 09:26 | 只看该作者
072/073  例程中是有SPI的DMA例程,我有参考用来驱动过SPI显示屏

使用特权

评论回复
板凳
Sam131208|  楼主 | 2024-3-19 10:38 | 只看该作者
ysf 发表于 2024-3-19 09:26
072/073  例程中是有SPI的DMA例程,我有参考用来驱动过SPI显示屏

  你好,072/073我都在官网下载了,没有发现你说的SPI+DMA例程,uart+dma例程倒是有。
  方便透露下你在哪里下的DDL以及版本吗? 不胜感激。

使用特权

评论回复
地板
ysf| | 2024-3-19 13:51 | 只看该作者
本帖最后由 ysf 于 2024-3-19 14:23 编辑

就是官网下的1.20驱动,打开后点开发工具就找到了
https://www.xhsc.com.cn/Productlist/info.aspx?itemid=1782
可能是我记错了,应该是根据DMAC里面的例子改的,弄懂里面的几个参数,其实也很简单
void App_DmaCfg(void)
{
    stc_dma_cfg_t stcDmaCfg;

    //打开DMA时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE);

    DDL_ZERO_STRUCT(stcDmaCfg);
    //DDL_ZERO_STRUCT(aDST_Buffer);

    stcDmaCfg.enMode =  DmaMskBlock;                           //选择块传输
    stcDmaCfg.u16BlockSize = 0x01;                             //块传输个数
    stcDmaCfg.u16TransferCnt = BUFFER_SIZE;                    //块传输次数,一次传输数据大小为 块传输个数*BUFFER_SIZE
    stcDmaCfg.enTransferWidth = DmaMsk8Bit;                   //传输数据的宽度,此处选择字8Bit宽度
    stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc;                //源地址自增
          stcDmaCfg.enDstAddrMode = DmaMskDstAddrFix;                //DmaMskDstAddrInc:目的地址自增;DmaMskDstAddrFix:目的地址固定
    stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable;//DmaMskDstAddrReloadDisable:禁止重新加载传输目的地址;DmaMskDstAddrReloadEnable 自动加载
    stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable; //DmaMskSrcAddrReloadDisable:禁止重新加载传输源地址;DmaMskSrcAddrReloadEnable:自动加载
    stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable;    //DmaMskBcTcReloadDisable:禁止重新加载BC/TC值;DmaMskBcTcReloadEnable:自动加载
    stcDmaCfg.u32SrcAddress = (uint32_t)&u8Disp_Buffer[0];     //指定传输源地址 u8Disp_Buffer[0]
    stcDmaCfg.u32DstAddress =(uint32_t) &M0P_SPI1->DATA;         //指定传输目的地址  M0P_SPI1->DATA   aDST_Address
    stcDmaCfg.enRequestNum = DmaSPI1TXTrig;                        //设置为软件触发  DmaSPI1TXTrig   DmaSWTrig
          stcDmaCfg.enTransferMode = DmaMskOneTransfer;             //DmaMskOneTransfer:dma只传输一次,DMAC传输完成时清除CONFA:ENS位  DmaMskContinuousTransfer
    stcDmaCfg.enPriority = DmaMskPriorityFix;                  //各通道固定优先级,CH0优先级 > CH1优先级

    Dma_InitChannel(DmaCh0,&stcDmaCfg);                        //初始化dma通道0
               
        //        Spi_FuncEnable(M0P_SPI1, SpiMskDmaTxEn);                       //SpiMskDmaTxEn         = 0x10u,   ///<DMA硬件访问发送使能
       
       
        // Dma_DisableChannelIrq(DmaCh0);
  // Dma_DisableChannelErrIrq(DmaCh0);

    //使能DMA,使能DMA0,清除DMA0状态
    Dma_Enable();
    //Dma_EnableChannel(DmaCh0);
    //Dma_ClrStat(DmaCh0);   
    // Spi_FuncEnable(M0P_SPI1, SpiMskDmaTxEn);                       //SpiMskDmaTxEn         = 0x10u,   ///<DMA硬件访问发送使能
}



使用特权

评论回复
5
Sam131208|  楼主 | 2024-3-19 17:28 | 只看该作者
本帖最后由 Sam131208 于 2024-3-19 17:32 编辑
ysf 发表于 2024-3-19 13:51
就是官网下的1.20驱动,打开后点开发工具就找到了
https://www.xhsc.com.cn/Productlist/info.aspx?itemid= ...

看起来与我的差不多,我主要用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;
}

使用特权

评论回复
6
ysf| | 2024-3-19 17:56 | 只看该作者
Sam131208 发表于 2024-3-19 17:28
看起来与我的差不多,我主要用DMA来读取数据,节省电流。不过测试一直不正常。
...

配置在初始化上配置好就成,使用时启动就成,不要每次都要配置,另外在配置前面的外设时钟要先使能:
//打开DMA时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE);      /必须要有这行

使用特权

评论回复
7
ysf| | 2024-3-19 18:00 | 只看该作者
貌似这行不对,这里应该是地址
stcDmaCfg.u32DstAddress = (uint32_t)rx;

改成stcDmaCfg.u32DstAddress = (uint32_t)&rx;  试试

使用特权

评论回复
8
储小勇_526| | 2024-3-20 08:34 | 只看该作者
这些个国产单片机写例程的都是菜鸡,写的乱七八糟的,让初学者摸不着头脑,一点也不规范,能好起来才怪。也不知道测不测试就敢放在官网让别人下载,要做就做精品。

使用特权

评论回复
9
wubangmi| | 2024-3-20 08:50 | 只看该作者
储小勇_526 发表于 2024-3-20 08:34
这些个国产单片机写例程的都是菜鸡,写的乱七八糟的,让初学者摸不着头脑,一点也不规范,能好起来才怪。也 ...

我觉得小华的例程写的挺好的,大概率是我水平低,写的东西我都能看懂。

使用特权

评论回复
10
Sam131208|  楼主 | 2024-3-20 08:55 | 只看该作者
ysf 发表于 2024-3-19 18:00
貌似这行不对,这里应该是地址
stcDmaCfg.u32DstAddress = (uint32_t)rx;

   rx本身是指针变量的了。再来个&rx,就成了指向指针,会崩溃的。

使用特权

评论回复
11
Sam131208|  楼主 | 2024-3-20 09:11 | 只看该作者
储小勇_526 发表于 2024-3-20 08:34
这些个国产单片机写例程的都是菜鸡,写的乱七八糟的,让初学者摸不着头脑,一点也不规范,能好起来才怪。也 ...

  也不能这么说,小华在国内也可以说是傲视群雄了,能排前几名的,可以说是半导体新贵,不容易了。最大的缺点就是例程不完善,驱动有待加强,芯片本身很好的。你的抱怨是没有用过其它更烂的芯片,算是幸福的吐槽了。

使用特权

评论回复
12
储小勇_526| | 2024-3-20 10:25 | 只看该作者
Sam131208 发表于 2024-3-20 09:11
也不能这么说,小华在国内也可以说是傲视群雄了,能排前几名的,可以说是半导体新贵,不容易 ...

我也是刚开始接触国产的,之前一直是瑞萨和STM32,而且我没从头开始写过代码,一直写应用层。现在接触的是复旦微的,代码不敢恭维,反正离标准十万八千里,随便去github下载个代码都比他写的标准。根本就不用心,不知道凭什么从这么多单片机中脱颖而出。

使用特权

评论回复
13
Sam131208|  楼主 | 2024-3-20 17:35 | 只看该作者
储小勇_526 发表于 2024-3-20 10:25
我也是刚开始接触国产的,之前一直是瑞萨和STM32,而且我没从头开始写过代码,一直写应用层。现在接触的 ...

  以STM32来比对的话,从硬件来说,就是个半残;从软件来说,就是个渣渣。从价格来说,STM32也是渣渣,果断无视它了。当然,国产的也有好的,比如GigaDevice, 不过价格就。。。那还不如选STM32.
  综合来说,小华就显得很香了,一些缺点也可以忍受
  

使用特权

评论回复
14
daichaodai| | 2024-3-22 08:31 | 只看该作者
常用外设配置相对简单

使用特权

评论回复
15
小夏天的大西瓜| | 2024-3-26 17:39 | 只看该作者
小华MCU的芯片很不错,就是内部库的驱动需要不断完善

使用特权

评论回复
16
LOVEEVER| | 2024-3-27 13:13 | 只看该作者
实际DMA使用一般情况下按照样例程序进行设计就可以

使用特权

评论回复
17
Sam131208|  楼主 | 2024-3-29 14:45 | 只看该作者
LOVEEVER 发表于 2024-3-27 13:13
实际DMA使用一般情况下按照样例程序进行设计就可以

    可以共享下你的驱动代码? spi flash的完整读写驱动。

使用特权

评论回复
18
xdvca| | 2024-7-31 22:35 | 只看该作者
要全面掌握这些外设的 DMA 使用,我们可以创建相应的示例代码和配置指南。

使用特权

评论回复
19
helloheoo| | 2024-8-21 16:52 | 只看该作者
xdvca 发表于 2024-7-31 22:35
要全面掌握这些外设的 DMA 使用,我们可以创建相应的示例代码和配置指南。 ...

哪里有spi+dma的示例代码

使用特权

评论回复
20
键盘手没手| | 2024-10-2 22:02 | 只看该作者
HC32L系列的DMA例程都是关于ADC、RAM的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

96

帖子

0

粉丝