PWM驱动电机,电机不转

2019-03-23 16:17发布

使用PWM小风扇驱动电机,电机不转。
代码如下:
#include "stm32f10x.h"
#include <stdio.h>

void GPIO_PWM_Config(void);
void TIM3_Config(void);
void NVIC_TIM3Config(void);
void COM_Config(void);
void delay(uint32_t nCount);
int fputc(int ch, FILE *f);
int fgetc( FILE *f);

const uint16_t Period_Val = 1000;
__IO uint16_t CCR1_Val = 100,CCR2_Val=900;                          

uint16_t PrescalerValue = 0;
uint16_t  Times=0;

int main(void)
{
   GPIO_PWM_Config();
   TIM3_Config();
   NVIC_TIM3Config();
   COM_Config();

   while(1)
   {
            delay(6000000);
         printf(" %d ", Times++);

   }
}

void GPIO_PWM_Config(void)
{
           GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
    GPIO_Init(GPIOD, &GPIO_InitStructure);       


}


void TIM3_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    // System Clocks Configuration  PCLK1 = HCLK/2 = 36MHz
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);                  // TIM3完全重映射,至PC6、7、8、9

    /*计算预分频系数
    PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;        */

    /* 时基设置 */
    TIM_TimeBaseStructure.TIM_Period = Period_Val;
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    /*TIM3为 PWM1模式 , 由Channel1输出 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                 
    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

        /*TIM3为 PWM1模式 , 由Channel2输出 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                 
    TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC2Init(TIM3, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);


    /* TIM IT 使能*/
    TIM_ITConfig(TIM3, TIM_IT_CC1|TIM_IT_CC2 , ENABLE);

    /* TIM3 使能 */
    TIM_Cmd(TIM3, ENABLE);


}

void NVIC_TIM3Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

void COM_Config(void)
{

    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

   //  初始化STM32的USART2的TX管脚,配置为复用功能推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

   //  初始化STM32的USART2的RX管脚,配置为复用功能输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

//         使能STM32的USART2的管脚重映射, TX、RX分别映射至PD5、6
    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

    USART_InitStructure.USART_BaudRate = 115200;              //串口的波特率,
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据字长度(8位或9位)
    USART_InitStructure.USART_StopBits = USART_StopBits_1;      //可配置的停止位-支持1或2个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;         //无奇偶校验  
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //双工模式,使能发送和接收

    USART_Init(USART2, &USART_InitStructure);

        USART_Cmd(USART2, ENABLE);
}

void delay(__IO uint32_t nCount)
{
    for (; nCount != 0; nCount--);
}

#ifndef MicroLIB
//#pragma import(__use_no_semihosting)             //没有实现fgetc时需要声明该参数   
/* 标准库需要的支持函数 使用printf()调试打印不需要实现该函数 */               
struct __FILE
{
        int handle;
    /* Whatever you require here. If the only file you are using is */   
    /* standard output using printf() for debugging, no file handling */   
    /* is required. */
};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
/* 重定义fputc函数 如果使用MicroLIB只需要重定义fputc函数即可 */  
int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */

         /* e.g. write a character to the USART */
    USART_SendData(USART2, (uint8_t) ch);

    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
    {}

    return ch;
}
/*
可以直接使用putchar
不需要再定义 int putchar(int ch),因为stdio.h中有如下定义
#define putchar(c) putc(c, stdout)
*/

int ferror(FILE *f) {  
    /* Your implementation of ferror */  
    return EOF;  
}
#endif

FILE __stdin;

int fgetc(FILE *fp)
{
        int ch = 0;
       
    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
    {
    }

    ch = (int)USART2->DR & 0xFF;
       
    putchar(ch); //回显
       
        return ch;
}


void TIM3_IRQHandler(void)
{
           if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

        GPIO_SetBits(GPIOD,GPIO_Pin_3);

    }

    if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

        GPIO_ResetBits(GPIOD,GPIO_Pin_3);
                                                                          
    }
}


无论是接PD3,还是PC6,电机都不转,同样的程序改变CCR_Val可以改变LED灯的亮度,但电机就是不转。
不知道是哪里出问题了,求大神们指教!
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
maychang
1楼-- · 2019-03-23 19:20
/ “无论是接PD3,还是PC6,电机都不转”
难道STM32单片机的I/O口线输出能力已经足以驱动电动机了?
你不妨试试令某条口线始终为“1”或者为“0”(相当于PWM占空比为1或者为0),看看电动机转还是不转。
strong161
2楼-- · 2019-03-23 22:27
 精彩回答 2  元偷偷看……
shrxh
3楼-- · 2019-03-24 03:54
maychang 发表于 2018-3-24 18:44
“无论是接PD3,还是PC6,电机都不转”
难道STM32单片机的I/O口线输出能力已经足以驱动电动机了?
你不妨 ...

我试了下,使PD3置1,发现,电机两端连PD3和3V3电机转动,连PD3和GND电机不转。我理解的是PD3置1,应该与GND连电机转动才对,是我理解错了吗?
maychang
4楼-- · 2019-03-24 05:00
shrxh 发表于 2018-3-24 20:36
我试了下,使PD3置1,发现,电机两端连PD3和3V3电机转动,连PD3和GND电机不转。我理解的是PD3置1,应该与 ...

“我理解的是PD3置1,应该与GND连电机转动才对,是我理解错了吗?”
我也这么理解。
不知道为什么“电机两端连PD3和3V3电机转动,连PD3和GND电机不转”。
chunyang
5楼-- · 2019-03-24 10:24
 精彩回答 2  元偷偷看……
shrxh
6楼-- · 2019-03-24 16:20
chunyang 发表于 2018-3-24 23:54
楼主应给出相关局部电路才好判断。

IMG_20180325_101735.jpg 我连了两个电机,一个电机连PD3和GND,一个连PC6和GND,两个电机都不转;
如果连PD3和3V3,电机转,并且改变占空比可以调速;
连PC6和3V3,电机也不转。
是不是这个板子3V3和GND搞混了?

一周热门 更多>