使用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灯的亮度,但电机就是不转。
不知道是哪里出问题了,求大神们指教!
此帖出自
小平头技术问答
一周热门 更多>