打印
[STM32F1]

一个DMA1 发送 SIP1 的问题

[复制链接]
1223|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huwr|  楼主 | 2021-10-10 10:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DMA, SIP, pi, spi, ni, ST
第一次用STM32  实在不太熟悉。

void SPI1_GIIO_Init(void)
{
                 GPIO_InitTypeDef GPIO_InitStructure;
                RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOA, ENABLE );//PORTA时钟使能
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5 ;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                  //PB7/5复用推挽输出
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_Init(GPIOA, &GPIO_InitStructure);                                                        //初始化GPIOA
}

void SPI1_ConfigInit(void)
{
                SPI_InitTypeDef  SPI_InitStructure;
                RCC_APB2PeriphClockCmd(        RCC_APB2Periph_SPI1,  ENABLE );//SPI1时钟使能
                SPI_I2S_DeInit(SPI1);
        
                SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;  //设置SPI单向或者双向的数据模式:
                SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
                SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
                SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                //串行同步时钟的空闲状态为low电平
                SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        //串行同步时钟的第1个跳变沿(上升或下降)数据被采样
                SPI_InitStructure.SPI_NSS = SPI_NSS_Soft ;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
                SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8 ;                //定义波特率预分频的值:波特率预分频值为256
                SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
                SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
                SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

                SPI_Cmd(SPI1, ENABLE); //使能SPI外设
                SPI1_ReadWriteByte(0xff);
}
//DMA 数据大挪移
extern        unsigned char         Ws2811DisBuf[LedCount*24];
void DMA1_3_SIP1_Init(void)
{

        DMA_InitTypeDef                DMA_InitStructure;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);                        //打开DMA1的时钟

        DMA_DeInit(DMA1_Channel3);                                //clear channel3;
        
        
         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &SPI1->DR; /*!< Specifies the peripheral base address for DMAy Channelx. */

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Ws2811DisBuf;     /*!< Specifies the memory base address for DMAy Channelx. */

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;           //外设地址是目的地。  

  DMA_InitStructure.DMA_BufferSize = LedCount;                               //传输的长度

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;     //外设地址指针不加1

  DMA_InitStructure.DMA_MemoryInc = DMA_PeripheralInc_Enable ;         
                                      

  DMA_InitStructure.DMA_PeripheralDataSize=  DMA_PeripheralDataSize_Byte; //以字节为单位搬运

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;   
        
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;      //        DMA模式是一次性的, 不是循环      

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;          //优先级是高
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable ;               //是内存和外设之间传输数据。
        
        DMA_Init(DMA1_Channel3, &DMA_InitStructure);


         DMA_Cmd(DMA1_Channel3, ENABLE);  //使能DMA通道
        
}


void SPI1_Init(void)
{
        SPI1_GIIO_Init();                //打开SPI1 GOIO        的IO时钟 和初始化
        SPI1_ConfigInit();        
        DMA1_3_SIP1_Init();        
}

int main(void)
{        
        SPI1_Init();                         //DAM--SPI1
         
        while(1)
        {
                                    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
//                                while(DMA_GetFlagStatus(DMA1_FLAG_TC3)!=RESET)                                //等待通道3传输完成
        }                        
}


请问是哪里发生了低级错误,造成 不能输出 SPI1 .  谢谢。 2天了,实在没有办法才上网求助。

使用特权

评论回复
沙发
supernan| | 2021-10-10 10:22 | 只看该作者
一步步来,先让SPI跑起来。

去官网下载个固件包,里面有例程参考。STSW-STM32054
SPI跑起来后再把DMA功能加进去。

注意时钟都开启了,如果有管脚REMAP,记得开启AFIO时钟。

使用特权

评论回复
板凳
huwr|  楼主 | 2021-10-10 10:24 | 只看该作者
DMA_ClearFlag (DMA1_FLAG_TC3);
                 DMA_SetCurrDataCounter(DMA1_Channel1, LedCount*24);    //传输数量设置
                 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);   
                 DMA_Cmd(DMA1_Channel3, ENABLE);  //使能DMA通道
               ??????????????????????


不用DMA 能跑起来。  奇怪就是用DMA1 的通道3   启动不了 SPI1 .              我用的是STM32F103C8  .   求指教。
                        while(Idex < LedCount*24)                        //  大约5MS  OK
                        {
                                SPI1_ReadWriteByte(Ws2811DisBuf[Idex++]);

使用特权

评论回复
地板
huwr|  楼主 | 2021-10-10 10:27 | 只看该作者
希望大神有谁做过,给个例子。 谢谢。

使用特权

评论回复
5
llljh| | 2021-10-10 10:29 | 只看该作者

这种问题最好拆开,你先看看spi收到数据没,就是spi的数据寄存器会变
然后再看看dma的cnt寄存器有变化没
把问题范围缩小再推断再验证

使用特权

评论回复
6
jlyuan| | 2021-10-10 10:31 | 只看该作者
题目好像写错了

使用特权

评论回复
7
dingy| | 2021-10-10 10:33 | 只看该作者
用普通模式发送一下试试

使用特权

评论回复
8
dengdc| | 2021-10-10 10:35 | 只看该作者
我没用过dma模式的啊

使用特权

评论回复
9
zhenykun| | 2021-10-10 10:37 | 只看该作者
一部分一部分的分析

使用特权

评论回复
10
xxrs| | 2021-10-10 10:39 | 只看该作者
先用普通模式 看看你的spi有没有问题

使用特权

评论回复
11
huwr|  楼主 | 2021-10-10 10:41 | 只看该作者

嗯,那我按大家的说法挨个排查一下,谢谢哈

使用特权

评论回复
12
guanjiaer| | 2021-11-2 15:50 | 只看该作者
我只会用普通模式

使用特权

评论回复
13
木木guainv| | 2021-11-2 15:52 | 只看该作者
我对dma的这个也不太熟悉

使用特权

评论回复
14
八层楼| | 2021-11-2 15:53 | 只看该作者
spi能正常运行吗

使用特权

评论回复
15
观海| | 2021-11-2 15:56 | 只看该作者
这个是几线制的通讯方式啊

使用特权

评论回复
16
tpgf| | 2021-11-2 16:07 | 只看该作者
分成不同的部分进行分析

使用特权

评论回复
17
heimaojingzhang| | 2021-11-2 16:10 | 只看该作者
先让SPI跑起来

使用特权

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

本版积分规则

780

主题

8627

帖子

5

粉丝