这里的主要实验是motor电机实验
motor中用到的pwm引脚是pb8,时钟是TIM10的通道1,这些基于
F:\BaiduNetdiskDownload\探索者F4资料盘(A盘)《STM32F4xx中文参考手册》
F:\BaiduNetdiskDownload\探索者F4资料盘(A盘)《【英文】STM32F207数据手册(Rev9)》
1. led.h
#include"stm32f2xx.h"
#ifndef __LED_H
#define __LED_H
void LED_Init(void);
//void Delay(vu32 nCount);
void CTL_LED(u8 LED_NUM, u8 OFF_ON);
#endif
led.c
#include"led.h"
#include"stm32f2xx.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD, GPIO_Pin_11|GPIO_Pin_12);
}
/*
void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}
*/
#if 1
void CTL_LED(u8 LED_NUM, u8 OFF_ON)
{
switch(LED_NUM)
{
case 0:
if(OFF_ON == 1)
{
GPIO_ResetBits(GPIOD, GPIO_Pin_11);
}
else
{
GPIO_SetBits(GPIOD, GPIO_Pin_11);
}
break;
case 1:
if(OFF_ON == 1)
{
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}
else
{
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
break;
default:
//GPIO_ResetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
GPIO_ResetBits(GPIOD,GPIO_Pin_11|GPIO_Pin_12);
break;
}
}
#endif
usart.h
#include"stm32f2xx.h"
#include "stm32f2xx_conf.h"
#ifndef __USART_H
#define __USART_H
void uart_init(u32 bound);
void USART_Configuration(void);
void USART_NVIC_Config(void);
#endif
usart.c
#include"stm32f2xx.h"
#include"usart.h"
void USART_Configuration(void) //串口配置
{
GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体
USART_InitTypeDef USART_InitStructure; //声明一个串口类型的结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //时钟使能配置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口使能配置
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //将PB10和PB11复用为串口3的输入输出
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //端口配置,取决于我们用哪个IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //表明IO口的功能是什么
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure); //组,组下面具体的
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200; //串口的一些相关配置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
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(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //串口中断使能
USART_Cmd(USART3, ENABLE); //串口使能
}
void USART_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
pwm.h
#include"stm32f2xx.h"
#ifndef __PWM_H_
#define __PWM_H_
void TIM10_PWM_Init(u32 arr);
#endif
pwm.c
#include"stm32f2xx.h"
#include"pwm.h"
void TIM10_PWM_Init(u32 arr)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE); //使能定时器10时钟,这里采用定时器10,且定时器10挂载在APB2上?
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能gpio时钟
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM10); //将GPIOB8复用为TIM10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化TIM4 输出通道 初始化输出比较参数
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //模式1决定,当cnt
gpio.h
#include"stm32f2xx.h"
#ifndef __GPIO_H
#define __GPIO_H
void GPIO9_Set_Init(void);
void GPIO12_Set_Init(void);
#endif
gpio.c
#include"gpio.h"
#include"stm32f2xx.h"
void GPIO9_Set_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //这里要选择为输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//GPIO_SetBits(GPIOB, GPIO_Pin_9); //PB9控制电机转动方向
}
void GPIO12_Set_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_OType_PP表示推挽方式输出,GPIO_OType_OD表示开漏
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//GPIO_SetBits(GPIOB, GPIO_Pin_12); //PB12使能开关
}
motor.h
#include"stm32f2xx.h"
#include "stm32f2xx_conf.h"
#ifndef __MOTOR_H_
#define __MOTOR_H_
void Start_Pwm(void);
void Pause_Pwm(void);
void USART3_IRQHandler(void);
void CTL_DIR(u8 DIR);
#endif
motor.c
#include"stm32f2xx.h"
#include"usart.h"
#include"gpio.h"
#include"pwm.h"
#include"motor.h"
#include"led.h"
#define MOTOR_START 0x01
#define MOTOR_PAUSE 02
#define MOTOR_FORWARD 03
#define MOTOR_INVERT 04
//中断服务函数,在启动文件startup_stm32。。。无返回值,无参数
void USART3_IRQHandler(void) //串口3中断服务
{
u16 Res = 0;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断
{
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
Res = USART_ReceiveData(USART3);//读取接收到的数
if(Res == MOTOR_START)
{
Start_Pwm();
}
else if(Res == MOTOR_PAUSE)
{
Pause_Pwm();
}
else if(Res == MOTOR_FORWARD)
{
CTL_DIR(0);
}
else if(Res == MOTOR_INVERT)
{
CTL_DIR(1);
}
else
{
CTL_LED(0, 1); //右边的灯
}
}
else
{
CTL_LED(1, 1); //左边的灯
}
}
void CTL_DIR(u8 DIR)
{
switch(DIR)
{
case 0: //0时设置为正向
GPIO_ResetBits(GPIOB, GPIO_Pin_9); //置低
TIM10_PWM_Init(500);
break;
case 1: //1时设置为反向
GPIO_SetBits(GPIOB, GPIO_Pin_9); //置高
TIM10_PWM_Init(500);
break;
default:
break;
}
}
//电机开始转动函数
void Start_Pwm(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_9);
TIM10_PWM_Init(500);
}
//电机停止转动函数
void Pause_Pwm(void)
{
TIM_Cmd(TIM10, DISABLE);
}
main.c
#include"stm32f2xx.h"
#include"gpio.h"
#include"usart.h"
#include"pwm.h"
#include"motor.h"
#include"led.h"
void Delay(__IO uint32_t nCount); //延时函数
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组
USART_Configuration();
USART_NVIC_Config();
LED_Init();
//TIM10_PWM_Init(500); //29是预分频系数,则定时器计数频率是30/29+1=1um,周期由arr决定,重转载值是500,则由1和500,可知整个周期是500
GPIO9_Set_Init();
GPIO12_Set_Init();
//GPIO_SetBits(GPIOB, GPIO_Pin_9); //PB9控制电机转动方向,高电平下pb9与pb12使能
GPIO_SetBits(GPIOB, GPIO_Pin_12); //PB12使能开关
//Start_Pwm(); //往外转
//CTL_DIR(0); //朝里转
//CTL_DIR(1); //往外转
while(1)
{
}
//return 0;
}
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif