STM32
直播中

张玉兰

8年用户 1449经验值
私信 关注
[问答]

STM32F103ZET6将SPI+W25QXX的程序移植后,步进电机均转速转慢的原因?

本人学机械出身,现遇一问题,打不到突破办法,还请各位大虾相助。
CPU:
STM32F103ZET6
功能:多个步进电机控制,数据读写,串口收发等
原程序:采取内部FLASH,
现程序:增加SPI2+W25Q16
多个步进电机脉冲均由多个不同定时器PWM(tiM1TIM2TIM4TIM8)或定时器中断(TIM1)生成;
现象:
1、原程序运行正常,步进电机均正常,通过示波器测量,步进脉冲信号正常。
2、现程序W25Q16读写也正常;步进电机均变慢,通过示波器测量,脉冲信号变慢很多倍,串口也通讯正常。
3、只单独作  W25QXX_Init();的声明,后面的读写都删除掉现象同样;
4、将 W25QXX_Init();函数内逐段注释后编绎,步进电机变慢速度不一样;
分析:
1、怀疑是SPI2干扰了中断,但串口工作正常,为什么不影响串口中断;不知道该如何处理;

2、怀疑是SPI2影响了时钟;不知道该如何处理;

程序通过预编绎选择来做不同程序的对比:
部分代码如下:
将W25Q不声明即为原程序;

#define W25Q

#ifdef W25Q               
          W25QXX_Init();                        
         #endif


#ifdef W25Q               
                                        W25QXX_Read(caiping_record_datatemp,10000+caiming*400,200);                                       
        #else
                                  STMFLASH_Read(FLASH_SAVE_ADDR+10000+caiming*400,(u16*)caiping_record_datatemp,200);               
         #endif

#ifdef W25Q               
                                                        W25QXX_Write(fg_all_record_data,1000+fg_all_record_name*200+record_fg_all_i*20,10);                        
        #else                        
                                                  STMFLASH_Write(FLASH_SAVE_ADDR+100000+fg_all_record_name*200+record_fg_all_i*20,(u16*)fg_all_record_data,10);        
         #endif

void W25QXX_Init(void)
{        
  GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  // PB12 推挽
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(GPIOB,  GPIO_InitStructure);
         GPIO_SetBits(GPIOB,GPIO_Pin_12);

        W25QXX_CS=1;                                //SPI FLASH不选中
        SPI2_Init();                           //初始化SPI
        SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
        W25QXX_TYPE=W25QXX_ReadID();//读取FLASH ID.  

}  

void SPI2_Init(void)
{
         GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
        RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能         

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/15复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,  GPIO_InitStructure);//初始化GPIOB
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //PB14浮空输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,  GPIO_InitStructure);//初始化GPIOB

         GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_15);  //PB13/15上拉

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式: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_High;                //串行同步时钟的空闲状态为高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI2,  SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI2, ENABLE); //使能SPI外设
        
        SPI2_ReadWriteByte(0xff);//启动传输                 


}   

回帖(2)

段朝思

2024-4-2 14:56:35
建议电机不要采用定时器方式形成脉冲,太费机时,最好采用中断方式的PWM。
另外SPI读写就是费时间,可以在主程序执行。
举报

李鸿洋

2024-4-2 17:05:26
有一些可能的原因导致步进电机的转速变慢:

1. 程序中引入了SPI通信,可能会对处理器的运行速度产生影响。检查是否在每次SPI通信之前都进行了适当的延时或等待。

2. 可能存在中断冲突。在程序中,步进电机使用了多个定时器和串口,这些都可能会引发中断。检查是否有多个中断同时发生,并确保将优先级较高的中断处理完毕后再处理其他中断。

3. 片上Flash和外部Flash使用了相同的时钟源,可能会造成时钟分频影响。检查时钟源的分频设置和配置是否正确。

4. 程序中引入了新的代码,可能导致运行速度变慢。检查是否有其他新的代码或处理时间较长的操作。

5. SPI通信速度设置过低。检查SPI通信的配置寄存器,确保通信速度设置合适。

6. 需要检查时序是否正确。SPI通信有特定的时序要求,确保时序配置正确。

最好的解决方法是通过调试程序,逐步排查可能的原因,通过检查程序的不同部分,找到具体导致步进电机转速变慢的原因。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分