打印

GD32F130精准延时SPI_DMA_TX发送数据讨论贴

[复制链接]
8587|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mrhw|  楼主 | 2014-11-25 13:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mrhw 于 2014-12-3 19:46 编辑

产品原来是使用STM32F103C8T6的,为节省成本准备使用GD32F130C8T6, 移植编译成功后测试,果然体现出了GD32 M3内核的运算性能优势(之前我们移植过STM32F051C8T6最后因运算能力不足而放弃),但也带来了新的问题:程序中我们使用了1个EXTI2中断和1个TIM3中断,EXTI2中断抢占优先级为1,TIM3中断抢点优先级为0, 在进入EXTI2中断后开启TIM3并运行计算任务,计算任务尚未完成时,TIM3中断发生打断EXTI2,TIM3中断处理函数中使能DMA_SPI_TX,此时TIM3中断已经处理完成,EXTI2中断继续运行至完成,接下来又来一个EXTI2中断(EXTI2的中断频率为18K/秒)。
程序逻辑编程正确,经测试有一点不能达到要求:每次进入TIM3后使能DMA_SPI_TX,发出的数据并不在同一时间,有时提前<1us,有时延时<1us ,并不能实现时间上的对齐,在STM32F0和F1上没有这种现象,(EXTI2的中断源频率非常稳定,这个我们已经成熟应用于STM32F1),我们尝试提高SPI的速度,速度设置越高,SPI发出数据的时间对齐程序越高,但是超出了接收设备的极限,这里希望能得到一个解决的思路!
沙发
mrhw|  楼主 | 2014-11-26 16:18 | 只看该作者
一天了,没人回答

使用特权

评论回复
板凳
张思| | 2014-11-26 16:40 | 只看该作者

使用特权

评论回复
地板
sunmeat| | 2014-11-26 18:29 | 只看该作者
看不出是什么原因来

使用特权

评论回复
5
yc_xpg| | 2014-11-27 15:51 | 只看该作者
发个实验代码来给分析哈....

使用特权

评论回复
6
mrhw|  楼主 | 2014-11-27 16:37 | 只看该作者
yc_xpg 发表于 2014-11-27 15:51
发个实验代码来给分析哈....

void TIM3_init(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef                 NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        TIM_TimeBaseStructure.TIM_Period = 576;
        TIM_TimeBaseStructure.TIM_Prescaler = 0;
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

       
        NVIC_InitStructure.NVIC_IRQChannel =  TIM3_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  
}


void Exti2_init(void) //这个中断有稳定的18K/秒中断源
{

        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

           GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);

        /* Enable SYSCFG clock */
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
         

        GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
               
           
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,GPIO_PinSource2);

          EXTI_InitStructure.EXTI_Line=EXTI_Line2;           
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
          EXTI_InitStructure.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStructure);                
       
       
       
        NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn ;                       
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;       
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1 ;                                       
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                               
          NVIC_Init(&NVIC_InitStructure);            
  
}



void TIM3_IRQHandler(void)
{

        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
        {
               
                       
                TIM_Cmd(TIM3, DISABLE);
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
                DMA_Cmd(DMA1_Channel3, ENABLE); //使能SPI_DMA发送
       
        }
       
}




void EXTI2_3_IRQHandler(void)
{
       
               
               
        EXTI_ClearITPendingBit(EXTI_Line2);               
       
        TIM_Cmd(TIM3, ENABLE); //开启TIM3,TIM3优级抢占优先级较高,计算任何还没有完成时就会进入TIM3中断,
        DMA_Cmd(DMA1_Channel3, DISABLE);
        SPI_DMA_InitStructure.DMA_BufferSize = 18;
        SPI_DMA_InitStructure.DMA_MemoryBaseAddr = data[0];
        DMA_Init(DMA1_Channel3, &SPI_DMA_InitStructure);

        {
                //计算任务
                //每次的计算任务都会顺利完成
        }                                 
                       
         

}


流程

1.        TIM3_init();
2.        Exti2_init();
3.        EXTI2中断发生,在EXTI2中断内启动TIM3定时器,定时器马上中断,然后抢占执行,在TIM3中断内使能SPI_DMA,接收设备接收到发送的数据。

问题:接收设备收到的第一个字节的时间上有时会早一点,有时会晚一点(小于1US),时间总是不相等,(描述为接收到第1个字节的时间不对齐),这样的执行方式在STM32F0/F1上时间对齐性都很好。

多谢各位朋友的关注!

使用特权

评论回复
7
sunmeat| | 2014-11-28 08:10 | 只看该作者
mrhw 发表于 2014-11-27 16:37
void TIM3_init(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

会不会是因为主频率的问题引起的呢,1us已经很小了,试试用120M的主频率,会不会时间更精确点

使用特权

评论回复
8
mrhw|  楼主 | 2014-11-28 10:44 | 只看该作者
sunmeat 发表于 2014-11-28 08:10
会不会是因为主频率的问题引起的呢,1us已经很小了,试试用120M的主频率,会不会时间更精确点 ...

GD32F130C8T6 标准频率 48M, stm32f051C8T6也是48M, Stm32不会存在这种时间上的不对齐

将GD32F130超频到72M 有细微的好转,但还是不能够时间对齐,反而提高SPI的发送速度,时间对齐要好一些,但还是不能向STM32那样时间高度对齐(STM32各种SPI速度下时间对齐性都非常好)。

难不成GD32F130底层代码有问题?

使用特权

评论回复
9
mrhw|  楼主 | 2014-11-28 10:51 | 只看该作者
sunmeat 发表于 2014-11-28 08:10
会不会是因为主频率的问题引起的呢,1us已经很小了,试试用120M的主频率,会不会时间更精确点 ...

GD32F130 标准主频48M,STM32F051标准主频也是48M,STM32F0可以实现这种时间上的高度对齐。

将GD32F130超频到72M,时间上的对齐性有稍微转好,但不如提高SPI的发送速度来的明显,即使提高了SPI的发送速度,也是不能实现时间上的高度对齐的(STM32F051在各种SPI发送速度下,都可以实现时间高度对齐)。

难道GD32F130的移植库底层代码有问题?

使用特权

评论回复
10
sunmeat| | 2014-11-28 11:06 | 只看该作者
mrhw 发表于 2014-11-28 10:44
GD32F130C8T6 标准频率 48M, stm32f051C8T6也是48M, Stm32不会存在这种时间上的不对齐

将GD32F130超频 ...

仔细看两者区别的说明文档,看看你用到的外设,找出区别

使用特权

评论回复
11
mrhw|  楼主 | 2014-11-28 11:33 | 只看该作者
sunmeat 发表于 2014-11-28 11:06
仔细看两者区别的说明文档,看看你用到的外设,找出区别

区别:

中断差异化

1.STM32F0 M0内核没有使用中断优先级分组 测试OK

2.STM32F1 M3内核使用了中断优先级分组   测试OK

3.GD32F130 M3内核使用了中断优先级分组  出现时间对齐性较差问题


中断初始化函数我已经贴出来了,该代码对中断的初始化也正确,但是就时间对齐性较差,使用GD提供的库,没有做出任何修改。

使用特权

评论回复
12
itachier| | 2014-11-28 13:24 | 只看该作者
ST32挺好的啊,你这边可以联系我,我有方法解决。QQ:2355925820

使用特权

评论回复
13
mrhw|  楼主 | 2014-11-28 21:37 | 只看该作者
itachier 发表于 2014-11-28 13:24
ST32挺好的啊,你这边可以联系我,我有方法解决。QQ:2355925820

你贴子都没有看仔细!

你应回复:

GD32挺好的啊,你这边可以联系我,我有方法解决。QQ:2355925820


哈哈!!!

使用特权

评论回复
14
myxiaonia| | 2014-11-29 12:12 | 只看该作者
实际上也不一定是中断的问题,有可能你设置dma发送后,这个也有可能发生延迟
我的看法,后一个问题的可能性更大,中断那是m3核心的问题,估计当目前为止没有一个产品是自定义的m3核

使用特权

评论回复
15
mrhw|  楼主 | 2014-11-29 16:49 | 只看该作者
myxiaonia 发表于 2014-11-29 12:12
实际上也不一定是中断的问题,有可能你设置dma发送后,这个也有可能发生延迟
我的看法,后一个问题的可能性 ...

ARM核心肯定是没有问题的,关键可能在于GD32的流水线处理机制上吧?

我就是使能了SPI_DMA发送,它非要以不确定的时间段后发送出去,一个普通用户有什么办法呢!

问题比较啰嗦,标题的描述也欠恰当!

使用特权

评论回复
16
mrhw|  楼主 | 2014-11-29 16:54 | 只看该作者
myxiaonia 发表于 2014-11-29 12:12
实际上也不一定是中断的问题,有可能你设置dma发送后,这个也有可能发生延迟
我的看法,后一个问题的可能性 ...

我还想过是不是进入中断后TIM使能的时间不确定,或SPI_DMA使能的时间不确定, 就将TIM使能放到EXTI中断的第一句,SPI_DMA使能放到TIM中断的第一句,试运行没有任何效果。

使用特权

评论回复
17
pmp| | 2014-11-30 00:13 | 只看该作者
楼主解决了吗

使用特权

评论回复
18
mrhw|  楼主 | 2014-11-30 08:09 | 只看该作者
pmp 发表于 2014-11-30 00:13
楼主解决了吗

没有!

我能想到的手段都试了,比如调整SPM_DMA优先级,或是将其它不相关代码全部删除,只运行这2部分相关的最小代码都不行。

以每天到这个GD32官方论坛来查看6次的频率来等待答案!


使用特权

评论回复
19
sunmeat| | 2014-11-30 09:05 | 只看该作者
mrhw 发表于 2014-11-30 08:09
没有!

我能想到的手段都试了,比如调整SPM_DMA优先级,或是将其它不相关代码全部删除,只运行这2部分相 ...


楼主加这个群,各种资深代理都在这里,GD32的代理支持做的不错

使用特权

评论回复
20
mrhw|  楼主 | 2014-11-30 19:38 | 只看该作者
最新测试情况:

我用GD32F150C8T6替换GD32F130C8T6,将时钟初始化为72M,情况依然!

即然经济型的搞不定,那我就用GD32F103C8T6,这回和STM32F103C8T6差距做到了最小,测试结果:

1.初始化为72M时钟,情况依然!
2.初始化为108时钟,情况依然!
3.直接将STM32F103C8T6的HEX写入GD32F103C8T6,情况依然!

GD32的设计者们,你们真的应该关注一下本贴了!!!

使用特权

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

本版积分规则

9

主题

41

帖子

0

粉丝