urada 发表于 2025-1-25 23:04:24

开启DMA希望SPI自动接收数据但是CLK没有输出

最近一段时间刚开始接触单片机领域 想用spi+dma来批量接收麦克风的pdm数据, 基本就是给麦克风一个信号 麦克风返回一个数字的采样信号. 文档里的信息不多 但是按我理解这样设置后spi应该会自动开始发送clk信号并等待来自miso的输入. 但是烧录之后clk一直维持低电平没有输出时钟.
已经排除电气连接的问题, 并用不带dma的spi功能进行了发送测试. 顺便我不太明白在不带dma的情况下要怎么直接一直输出clk, spi似乎只有在缓冲区里有数据时才发送clk同时从mosi输出
#include <stdio.h>
#include <stc8h.h>
#include <intrins.h>

#define ADDH(x)(((unsigned char *)&x))
#define ADDL(x)(((unsigned char *)&x))

char xdata dma_buf;

void main()
{       
        // 允许写入特殊功能寄存器
        // 即高128位xfr寄存器
        P_SW2 |= 0x80;
       
        // 设置gpio输出模式
        P3M0 = 0;
        P3M1 = 0;
        P5M0 = 0;
        P5M1 = 0;
        P2M0 = 0;
        P2M1 = 0;
        P1M0 = 0;
        P1M1 = 0;
       
        // 设置hric-mclk频率为27mhz
        // 设置分频系数为3, sysclk=27/3=9mhz
        CLKDIV = 3;

        // 初始化spi
       
        // 设置spi功能脚
        // cs        P35
        // mosi        P34
        // miso        P33
        // clk        P32
        P_SW1 |= 12;
       
        // 配置spi
        SPCTL = 0;
        SPCTL |= 1 << 7; // 忽略cs脚
        SPCTL |= 1 << 6; // spi使能
        // 控制发送/接收大小端
        SPCTL |= 1 << 4; // 主机模式
       
        // 清除spi状态
        SPSTAT = 0xc0;
       
        // DMA初始化
        // 禁止中断
        // 仅启用rx
        // 00100000
        DMA_SPI_CFG = 0x20;
       
        // 启用spi dma
        // 主机模式
        // 复位FIFO
        DMA_SPI_CR = 0xC1;
        DMA_SPI_STA = 1;
        DMA_SPI_AMT = 100;
       
        // 设置接收缓冲区地址
        DMA_SPI_RXAH = ADDH(dma_buf);
        DMA_SPI_RXAL = ADDL(dma_buf);
       
        // 主循环
        while(1)
        {
                // 只是测试一下有无时钟信号, 故总是丢弃所有接收到的数据
                DMA_SPI_STA = 0;
                _nop_();
        }
}



不太清楚是不是该发这个板块今天刚注册

urada 发表于 2025-1-25 23:07:37

硬件是stc8H8K64U 启用usb仿真 逻辑分析仪在spi发送测试时能正常检测到mosi和clk输出

王昱顺 发表于 2025-1-25 23:56:33

urada 发表于 2025-1-25 23:07
硬件是stc8H8K64U 启用usb仿真 逻辑分析仪在spi发送测试时能正常检测到mosi和clk输出 ...
spi是全双工,一直发 FFH 就可以拿到接受数据了

urada 发表于 2025-1-26 09:44:01

王昱顺 发表于 2025-1-25 23:56
spi是全双工,一直发00就可以拿到接受数据了

谢谢 我禁用了dma尝试手动发0试了一下
        SPSTAT |= 0xC0;
       
        // DMA初始化
        // 10100101
        // DMA_SPI_CFG = 0x20;
       
        // DMA_SPI_CR = 0xC1;
        // DMA_SPI_STA = 1;
        // DMA_SPI_AMT = 100;
       
        // 设置缓冲区地址
        // DMA_SPI_RXAH = ADDH(dma_buf);
        // DMA_SPI_RXAL = ADDL(dma_buf);
       
        // 主循环
        while(1)
        {
                SPSTAT |= 0xC0;
                SPDAT = 0;
               
                while (SPSTAT != 0x80)
                        _nop_();
               
                // DMA_SPI_STA = 0;
        }

但是用逻辑分析仪看了一下 发送完一个字节后clk变为低电平, miso被重新拉高, 2us后才会继续发送下一个字节 spi时钟为2Mhz clk能连续发送吗? 还是这就是spi的特性?

王昱顺 发表于 2025-1-26 11:07:25

urada 发表于 2025-1-26 09:44
谢谢 我禁用了dma尝试手动发0试了一下




spi需要装载数据,clk就是会中断的,并不是完全的连续

urada 发表于 2025-1-27 21:28:17

王昱顺 发表于 2025-1-26 11:07
spi需要装载数据,clk就是会中断的,并不是完全的连续

好的 谢谢. 我又研究了一下手册, 其实简单的计数器好像就能满足我的需求 对pdm脉冲信号进行计数 固定频率取一次再重置计数器 最后大概就能转为pcm信号. 这两天试一下
页: [1]
查看完整版本: 开启DMA希望SPI自动接收数据但是CLK没有输出