精华内容
下载资源
问答
  • 2019-07-22 21:35:20

    2019年7月22日
    今天是做小车过程中的第二天,今天写一下单纯的实现电机的正反转。(但是还是不会实现PWM调速)代码如下:
    /***********************************************/
    .H 代码
    #ifndef __MOTOR1_H
    #define __MOTOR1_H
    #include “stm32f10x.h”
    //#include “stm32f10x_gpio.h”
    #define High 1 //宏定义 高为1
    #define Low 0 //宏定义 低为0
    #define IN1(a) if (a)
    GPIO_SetBits(GPIOA,GPIO_Pin_4);\ //如果真 IN1 为高电平(PA4)
    else \
    GPIO_ResetBits(GPIOA,GPIO_Pin_4) // 否则为低电平 (PA4)
    #define IN2(a) if (a)
    GPIO_SetBits(GPIOA,GPIO_Pin_5);
    else
    GPIO_ResetBits(GPIOA,GPIO_Pin_5)
    otor_1_Config(void);
    void Motor_1_STOP(void); //停止
    void Motor_1_PRun(void); //正转
    void Motor_1_NRun(void); //反转
    #endif
    下面是.c代码
    #include “motor.h”
    #include “stm32f10x.h”
    #include “delay.h”
    void Motor_1_Config(void)
    {
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//用GPIOA时钟
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
    }
    void Motor_1_STOP(void)
    {
    IN1(High);
    IN2(High);
    }
    void Motor_1_PRun(void)
    {
    IN1(Low);
    IN2(High);
    }
    void Motor_1_NRun(void)
    {
    IN1(High);
    IN2(Low);
    }
    下面是主函数
    int main(void)
    {
    Motor_1_Config();
    delay_init();
    while(1)
    {
    Motor_1_PRun(); //正转
    delay_ms(2000); //延迟2秒
    Motor_1_NRun(); //反转
    delay_ms(2000); //延迟2秒
    Motor_1_STOP(); //停止
    delay_ms(2000);
    }
    }

    更多相关内容
  • 基于STM32的PWM调速,有四个电机 两个电机可以正反转,两个电机调速,内附程序与protues仿真
  • 本设计基于STM32控制直流电机加减速正反转设计(程序+仿真+论文) 仿真:proteus8.9 程序编译器:keil 5 编程语言:C语言 编号C0011 资料下载链接更多设计功能说明: 本设计由STM32F103、L298N电机驱动电路、按键...

    本设计基于STM32控制直流电机加减速正反转设计(程序+仿真+论文)
    仿真:proteus8.9
    程序编译器:keil 5
    编程语言:C语言
    编号C0011
    资料下载链接

    功能说明:
    本设计由STM32F103、L298N电机驱动电路、按键电路组成。
    1.通过按键可以控制电机,正转、反转、加速、减速、停止。
    2.档位分4档,并且可以通过按键顺序正转、反转、加速、减速、停止。
    3.档位可以自定义。
    附赠相关论文,根据实物写的,与仿真功能基本一致。

    仿真图(提供源文件):

    在这里插入图片描述
    在这里插入图片描述

    源程序(提供源文件):

    char dis0[6] = "Dir:+";   //暂存
    char dis1[6] = "Dir:-";   //暂存
    char dis2[16] = "";   //暂?
    char dis3[] = "RUN ";   //暂存?
    char dis4[] = "STOP";   //暂存
    unsigned  char rekey = 0; //按键防止抖动
    unsigned char contNum = 0; //循环计数
    int main(void)
    {
      
        delay_init();            //延时函数初始化
      
    //    uart_init(9600);        //串口初始化为115200
        //  uart2_init(9600)    ;
        TIM3_Int_Init(10, 7199); //定时器
        LED_Init();             //初始化与LED连接的硬件接口
        KEY_Init();
        Lcd_GPIO_init();
        Lcd_Init();
        IN1 = 1;        //方向控制
        IN2 = 0;
        pwmRigh = 0;    //pwm调整,电机转速调整
    
        Lcd_Puts(0, 0, (unsigned char *)dis0);
        sprintf(dis2,"SPEED:%d",pwmRigh);
        Lcd_Puts(0, 1, (unsigned char *)dis2);
         Lcd_Puts(8, 0, (unsigned char *)dis3);
    
        while(1)
        {
            if((key1 == 0) || (key2 == 0) || (key3 == 0) || (key4 == 0) || (key5 == 0))      //检测到按键按下
            {
    //            delay_ms(1);   //小抖动仿真不需要加
                if(rekey == 0)
                {
                    if(key1 == 0)  //检测是否按下
                    {
    
                        rekey = 1;
                        IN1 = 1;        //方向控制
                        IN2 = 0;                   
                        Lcd_Puts(0, 0, (unsigned char *)dis0);
                         Lcd_Puts(8, 0, (unsigned char *)dis3);
                    }
                    else if(key2 == 0) //设置值键
                    {
                        rekey = 1;
                        IN1 = 0;        //方向控制
                        IN2 = 1;
                        Lcd_Puts(0, 0, (unsigned char *)dis1);
                         Lcd_Puts(8, 0, (unsigned char *)dis3);
                    }
                    else if(key3 == 0) //设置值键
                    {
                        rekey = 1;
                        if(pwmRigh < 8)pwmRigh = pwmRigh + 2; //pwm 调速
                        sprintf(dis2,"SPEED:%d",pwmRigh/2);
                        Lcd_Puts(0, 1, (unsigned char *)dis2);
                    }
                    else if(key4 == 0) //设置值键
                    {
                        rekey = 1;
                        if(pwmRigh >= 2)pwmRigh = pwmRigh - 1; //pwm 调速
                        sprintf(dis2,"SPEED:%d",pwmRigh/2);
                        Lcd_Puts(0, 1, (unsigned char *)dis2);
                    }
                    else if(key5 == 0) //设置值键
                    {
                        rekey = 1;
                        IN1 = 0;        //方向控制
                        IN2 = 0;
                        Lcd_Puts(8, 0, (unsigned char *)dis4);
                    }
                }
            }
            else
            {
                rekey = 0;  //防止重复检测到按键
            }
            delay_ms(10);
        }
    }
    
    

    在这里插入图片描述

    以下为部分程序,完整程序可在下载链接获取:

    论文报告:
    在这里插入图片描述

    展开全文
  • 单片机,嵌入式,电路
  • 基于STM32f103ZET6单片机按键控制电机正反转(带PWM调速) 学了快半个月的STM32,收获颇多,很明显的感觉是32位的单片机要比8位单片机(51单片机)强的太多了,不管是性能还是功耗上和51是没法比的,而且还有许多的...

    基于STM32f103ZET6单片机按键控制电机正反转(带PWM调速)

    学了快半个月的STM32,收获颇多,很明显的感觉是32位的单片机要比8位单片机(51单片机)强的太多了,不管是性能还是功耗上和51是没法比的,而且还有许多的外设模块。stm32是ARM Cortex-M3内核的单片机,由于介绍STM32不是重点,这里我就不再赘述。
    用的是板子是f103ZET6的最小系统板,用的库是32的库函数(正点原子)。
    初期我主要学习了GPIO的配置、位操作、LED灯、蜂鸣器、外部中断、串口中断、定时器中断、定时器产生PWM。我准备将学习的内容结合起来做一个项目,也是对学习的总结(由于是在假期写的,没法去调试检验,语法是没有错误和警告的,如果有错误欢迎指正!)。

    简述

    1、通过四个按键控制两个电机的正反转,按键采用连续按有效,并且用定时器写了PWM用于降低电机转动的速度;
    2、在初始化中写了LED闪烁程序和蜂鸣器滴滴响的程序,在本程序中主要用于开机初始化,如果有其他用处可以修改参数调用即可;
    3、由于发现每次使用IO口、使用串口、使用定时器中断、定时器产生PWM都需要配置,所以我在其他文件夹中将j将其进行了配置,如果需要使用只需要调用函数和修改参数即可;
    4、我将所有自己写的.h文件放在了HEAD.h中,所有自己写的.c文件中的函数初始化都放在HEAD.c中的HEAD_Init()函数中(除了在main.c文件中的函数),使用时在main.c文件中调用HEAD.H和HEAD_Init()进行函数初始化。这样做的目的在于将代码规范、整洁化。

    IO口和模块的使用

    该程序中初始化了GPIOA、B、C、D、E、F这几个模式,共用了13个io口,
    其中GPIOA_6和GPIOA_7 用于TIM3 通道1和通道2输出pwm;
    GPIOD_6用于蜂鸣器;
    GPIOB_5 用于LED0;
    GPIOE_5 用于LED1;
    GPIOC_0、GPIOC_1、GPIOC_2、GPIOC_3用于电机A和B各自信号口;
    GPIOF_8、GPIOF_9、GPIOF_10、GPIOF_11用于四个独立按键连接引脚口;
    只初始化配置,没有使用GPIO_G、串口、定时器中断。

    配置文件介绍

    这是stm32f103库函数版标准工程模板的配置文件
    在这里插入图片描述
    下面这个是包含了我自己建立的文件工程
    在这里插入图片描述
    主要有GPIO_INIT、Myself_HELD、TIMER、USART还包括HARDWEAR中的关于LED和蜂鸣器的.c和.h文件,以及三个.txt文档,MSP.IO.txt罗列了最小系统板IO口的使用,READ_GPIO.txt主要写了关于GPIO配置所用到的一些接口参数,README.txt写了我配置文件的日期以及相关的注意事项。这里的三个.txt文件都是自己写的,主要是一些注意事项。
    下面我将我写的一些配置文件做一个简单的介绍

    1、Myself_HEAD

    这个文件夹中主要包括了head.h和head.c文件
    在这里插入图片描述

    head.h

    #ifndef __HEAD_H
    #define __HEAD_H
    
    #include "stm32f10x.h"			//stm官方库
    #include "stm32f10x_usart.h"	//stm官方串口库
    #include "stm32f10x_rcc.h"		//stm官方时钟库
    #include "stm32f10x_tim.h"		//stm官方定时器库
    #include "sys.h" 				//位操作头文件
    #include "delay.h"				//延时头文件
    #include <led.h>				//开机LED闪烁初始化头文件
    #include <GPIO.h>				//所有GPIO初始化配置头文件  GPIO   ABCDEFG
    #include <BEEP.h>				//开机蜂鸣器滴滴初始化头文件
    #include <USART.h>				//串口初始化以及串口中断服务函数头文件   只有配置了串口1、串口2、串口3,没有配置串口4和串口5
    #include <U_Timer.h>			//定时器中断初始化以及定时器中断服务函数(只写了四个通用定时器的)还包括定时器3的四路通道产生PWM初始化
    
    void HEAD_Init(void);			//头文件初始化声明
    
    
    #endif
    

    head.c

    #include <head.h>
    
    void HEAD_Init(void)			//初始化各个头文件的函数,直接在main.c文件中调用HEAD_Init()
    {
    	//GPIO_Init_x();			//修改x选择GPIO模式  共ABCDEFG七种  在GPIO.c文件里配置 
    	//在哪个函数里使用GPIO就在哪个函数里调用各个模块的初始化
    	//注意引脚不能重复
    	GPIO_Init_A();			//GPIO_A初始化      A_6   A_7    TIM3 通道1和通道2输出pwm
    	GPIO_Init_D();		    //GPIO_D初始化      D_6   蜂鸣器
    	GPIO_Init_B();			//gpio_B初始化      B_5   LED0
    	GPIO_Init_E();			//gpio_E初始化      E_5   LED1
    	GPIO_Init_C();		    //GPIO_C初始化		C_0   C_1   C_2   C_3	电机A和B各自IN口
    	GPIO_Init_F();			//GPIO_F初始化		F_8   F_9   F_10  F_11  四个独立按键连接引脚口	
    	
    	TIM3_PWM_Init(99,719);		//通用定时器3    在这里用于产生PWM  初始化四个通道  TIM_SetCompare2(TIM3,x);	通道2用于输出占空比最大100  产生频率1Khz
    	
    	USART_Init_1(115200);		//串口1初始化声明			32 bound_1   波特率
    	delay_init();				//延时初始化
    	
    	LED_Init();					//LED初始化
    	BEEP_Init();				//蜂鸣器初始化
    }
    

    GPIO_INIT

    这个文件夹中包括GPIO.h和GPIO.c文件
    在这里插入图片描述

    GPIO.h

    #ifndef __GPIO_H
    #define __GPIO_H
    
    #include "stm32f10x.h"
    #include "stm32f10x_rcc.h"				//stm官方时钟库
    #include "sys.h" 
    //需要修改gpio配置参数直接修改GPIO.C文件中的参数
    void GPIO_Init_A(void);				//GPIO_A   初始化函数声明
    void GPIO_Init_B(void);				//GPIO_B   初始化函数声明
    void GPIO_Init_C(void);				//GPIO_C   初始化函数声明
    void GPIO_Init_D(void);				//GPIO_D   初始化函数声明
    void GPIO_Init_E(void);				//GPIO_E   初始化函数声明
    void GPIO_Init_F(void);				//GPIO_F   初始化函数声明
    void GPIO_Init_G(void);				//GPIO_G   初始化函数声明
    
    
    #endif
    
    /*3种最大翻转速度:
           -2MHZ
           -10MHz
           -50MHz*/
    /*(1)GPIO_Mode_AIN 模拟输入
    (2)GPIO_Mode_IN_FLOATING 浮空输入
    (3)GPIO_Mode_IPD 下拉输入
    (4)GPIO_Mode_IPU 上拉输入
    (5)GPIO_Mode_Out_OD 开漏输出
    (6)GPIO_Mode_Out_PP 推挽输出
    (7)GPIO_Mode_AF_OD 复用开漏输出
    (8)GPIO_Mode_AF_PP 复用推挽输出
    */			 
    

    GPIO.c

    这里我将GPIO的七个模式都进行了初始化,如果有需要只需要修改相关的接口参数,然后进行函数调用就可以了。

    #include <GPIO.h>
    
    void GPIO_Init_A(void)						//GPIO_A
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_A;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能GPIO_A端口
    	
    	GPIO_InitStructurc_A.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_A配置			推挽输出
    	GPIO_InitStructurc_A.GPIO_Pin=GPIO_Pin_6;					//设置对应引脚			输出pwm		TIM3通道1
    	GPIO_InitStructurc_A.GPIO_Pin=GPIO_Pin_7;					//设置对应引脚			输出pwm		TIM3通道2
    	GPIO_InitStructurc_A.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOA,&GPIO_InitStructurc_A);					//GPIOA初始化
    	
    }
    
    
    void GPIO_Init_B(void)						//GPIO_B
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_B;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	//使能GPIO_B端口
    	
    	GPIO_InitStructurc_B.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_B配置				推挽输出
    	GPIO_InitStructurc_B.GPIO_Pin=GPIO_Pin_5;					//设置对应引脚		LED_B_5 
    	
    	GPIO_InitStructurc_B.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOB,&GPIO_InitStructurc_B);					//GPIO_B初始化
    	GPIO_SetBits(GPIOB,GPIO_Pin_5);							//GPIO_B   引脚pin_5输出高电平   LED_B_5  引脚状态初始化LED灭
    	
    }
    
    void GPIO_Init_C(void)						//GPIO_C
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_C;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//使能GPIO_C端口
    	
    	GPIO_InitStructurc_C.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_C配置				推挽输出
    	GPIO_InitStructurc_C.GPIO_Pin=GPIO_Pin_0;			    	//设置对应引脚				电机A  IN1
    	GPIO_InitStructurc_C.GPIO_Pin=GPIO_Pin_1;			    	//设置对应引脚				电机A  IN2
    	GPIO_InitStructurc_C.GPIO_Pin=GPIO_Pin_2;			    	//设置对应引脚				电机B  IN1
    	GPIO_InitStructurc_C.GPIO_Pin=GPIO_Pin_3;			    	//设置对应引脚				电机B  IN2
    	GPIO_InitStructurc_C.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOC,&GPIO_InitStructurc_C);					//GPIO_C初始化
    	
    	GPIO_ResetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);	//GPIO_C   引脚pin_0输出低电平   引脚状态初始化		电机引脚初始化低电平
    	
    	
    }
    
    void GPIO_Init_D(void)						//GPIO_D
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_D;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);	//使能GPIO_D端口
    	
    	GPIO_InitStructurc_D.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_D配置				推挽输出
    	GPIO_InitStructurc_D.GPIO_Pin=GPIO_Pin_6;					//设置对应引脚		BEEP_F
    	GPIO_InitStructurc_D.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOD,&GPIO_InitStructurc_D);					//GPIO_D初始化
    	GPIO_ResetBits(GPIOD,GPIO_Pin_6);							//GPIO_D   引脚pin_8输出低电平   BEEP_F   引脚状态初始化蜂鸣器不响
    	
    }
    
    
    void GPIO_Init_E(void)						//GPIO_E
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_E;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);	//使能GPIO_E端口
    	
    	GPIO_InitStructurc_E.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_E配置				推挽输出
    	GPIO_InitStructurc_E.GPIO_Pin=GPIO_Pin_5;					//设置对应引脚
    	GPIO_InitStructurc_E.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOE,&GPIO_InitStructurc_E);					//GPIO_E初始化
    	GPIO_SetBits(GPIOE,GPIO_Pin_5);							//GPIO_E   引脚pin_5输出高电平  LED_E_5 引脚状态初始化
    	
    }
    
    
    void GPIO_Init_F(void)						//GPIO_F
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_F;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);	//使能GPIO_F端口
    	
    	GPIO_InitStructurc_F.GPIO_Mode=GPIO_Mode_IPU;		    	//GPIO_F配置		   输入上拉		低电平有效
    	GPIO_InitStructurc_F.GPIO_Pin=GPIO_Pin_8;					//设置对应引脚			按键1  控制电机A 正转
    	GPIO_InitStructurc_F.GPIO_Pin=GPIO_Pin_9;					//设置对应引脚			按键2  控制电机A 反转
    	GPIO_InitStructurc_F.GPIO_Pin=GPIO_Pin_10;					//设置对应引脚			按键3  控制电机B 正转
    	GPIO_InitStructurc_F.GPIO_Pin=GPIO_Pin_11;					//设置对应引脚			按键4  控制电机B 反转
    	GPIO_InitStructurc_F.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOF,&GPIO_InitStructurc_F);					//GPIO_F初始化
    }
    
    void GPIO_Init_G(void)						//GPIO_G
    {
    	GPIO_InitTypeDef GPIO_InitStructurc_G;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);	//使能GPIO_G端口
    	
    	GPIO_InitStructurc_G.GPIO_Mode=GPIO_Mode_Out_PP;			//GPIO_G配置				推挽输出
    	GPIO_InitStructurc_G.GPIO_Pin=GPIO_Pin_5;					//设置对应引脚
    	GPIO_InitStructurc_G.GPIO_Speed=GPIO_Speed_50MHz;			//选择最大反转速度(2、10、50)
    	GPIO_Init(GPIOG,&GPIO_InitStructurc_G);					//GPIO_G初始化
    	GPIO_SetBits(GPIOG,GPIO_Pin_5);							//GPIO_G   引脚pin_5输出高电平   引脚状态初始化
    }
    

    TIMER

    由于STM32f103中有8个定时器,这个里面我建立了三个文件夹,分布别是保存2个高级定时器TIM1、TIM8的ADVANCED_TIMER文件夹。保存2个基本定时器TIM6和TIM7的BASIC_TIMER文件夹。保存4个通用定时器TIM2、TIM3、TIM4、TIM5的UNIVERSAL_TIMER文件夹。
    我只配置了通用定时器
    在这里插入图片描述

    在这里插入图片描述
    UNIVERSAL_TIMER文件夹中有关于通用定时器的.h和.c文件
    这里我将4个通用定时器用于中断的配置和用定时器3的4个通道输出PWM都进行了初始化,(注意:高级定时器有8通道产生pwm,基本定时器没有通道产生pwm,通用定时器有4通道产生pwm)如果有需要只需要修改相关的接口参数,然后进行函数调用就可以了。

    U_Timer.h

    #ifndef __U_Timer_H
    #define __U_Timer_H
    
    #include "stm32f10x.h"
    #include "stm32f10x_rcc.h"				//stm官方时钟库
    #include "stm32f10x_tim.h"				//stm官方定时器库
    
    #include "delay.h"
    #include <GPIO.h>
    
    
    //定时器1和8是高级定时器,6和7是基本定时器,在U_Timer.c里初始化通用定时器
    
    void TIM2_Int_Init(u16 arr_2,u16 psc_2);				//通用定时器2   
    void TIM3_Int_Init(u16 arr_3,u16 psc_3);				//通用定时器3    在这里用于产生中断
    void TIM4_Int_Init(u16 arr_4,u16 psc_4);				//通用定时器4    
    void TIM5_Int_Init(u16 arr_5,u16 psc_5);				//通用定时器3    
    
    
    void TIM2_IRQHandler(void);   //TIM2中断服务函数
    void TIM3_IRQHandler(void);   //TIM3中断服务函数
    void TIM4_IRQHandler(void);   //TIM4中断服务函数
    void TIM5_IRQHandler(void);   //TIM5中断服务函数
    
    //在主函数中初始化   
    void TIM3_PWM_Init(u16 arr,u16 psc);					//定时器3PWM初始化		通道1、通道2、通道3、通道4
    #endif
    

    U_Timer.c

    #include <U_Timer.h>
    //通用定时器2中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器2!
    void TIM2_Int_Init(u16 arr_2,u16 psc_2)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure_2;
    	NVIC_InitTypeDef NVIC_InitStructure_2;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
    	
    	//定时器TIM2初始化
    	TIM_TimeBaseStructure_2.TIM_Period = arr_2; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
    	TIM_TimeBaseStructure_2.TIM_Prescaler =psc_2; //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure_2.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure_2.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure_2); //根据指定的参数初始化TIMx的时间基数单位
     
    	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
    
    	//中断优先级NVIC设置
    	NVIC_InitStructure_2.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
    	NVIC_InitStructure_2.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
    	NVIC_InitStructure_2.NVIC_IRQChannelSubPriority = 2;  //从优先级2级
    	NVIC_InitStructure_2.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure_2);  //初始化NVIC寄存器
    	
    	TIM_Cmd(TIM2, ENABLE);  //使能TIMx					 
    }
    
    //通用定时器3中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器3!
    void TIM3_Int_Init(u16 arr_3,u16 psc_3)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure_3;
    	NVIC_InitTypeDef NVIC_InitStructure_3;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
    	
    	//定时器TIM3初始化
    	TIM_TimeBaseStructure_3.TIM_Period = arr_3; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
    	TIM_TimeBaseStructure_3.TIM_Prescaler =psc_3; //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure_3.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure_3.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure_3); //根据指定的参数初始化TIMx的时间基数单位
     
    	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
    	//中断优先级NVIC设置
    	NVIC_InitStructure_3.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    	NVIC_InitStructure_3.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
    	NVIC_InitStructure_3.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    	NVIC_InitStructure_3.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure_3);  //初始化NVIC寄存器
    	
    	TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
    }
    
    //通用定时器4中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器3!
    void TIM4_Int_Init(u16 arr_4,u16 psc_4)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure_4;
    	NVIC_InitTypeDef NVIC_InitStructure_4;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
    	
    	//定时器TIM3初始化
    	TIM_TimeBaseStructure_4.TIM_Period = arr_4; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
    	TIM_TimeBaseStructure_4.TIM_Prescaler =psc_4; //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure_4.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure_4.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure_4); //根据指定的参数初始化TIMx的时间基数单位
     
    	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断
    
    	//中断优先级NVIC设置
    	NVIC_InitStructure_4.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    	NVIC_InitStructure_4.NVIC_IRQChannelPreemptionPriority = 3;  //先占优先级3级
    	NVIC_InitStructure_4.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    	NVIC_InitStructure_4.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure_4);  //初始化NVIC寄存器
    	
    	TIM_Cmd(TIM4, ENABLE);  //使能TIMx					 
    }
    
    //通用定时器5中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器3!
    void TIM5_Int_Init(u16 arr_5,u16 psc_5)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure_5;
    	NVIC_InitTypeDef NVIC_InitStructure_5;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能
    	
    	//定时器TIM3初始化
    	TIM_TimeBaseStructure_5.TIM_Period = arr_5; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
    	TIM_TimeBaseStructure_5.TIM_Prescaler =psc_5; //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure_5.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure_5.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure_5); //根据指定的参数初始化TIMx的时间基数单位
     
    	TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM5中断,允许更新中断
    
    	//中断优先级NVIC设置
    	NVIC_InitStructure_5.NVIC_IRQChannel = TIM3_IRQn;  //TIM5中断
    	NVIC_InitStructure_5.NVIC_IRQChannelPreemptionPriority = 3;  //先占优先级3级
    	NVIC_InitStructure_5.NVIC_IRQChannelSubPriority = 2;  //从优先级2级
    	NVIC_InitStructure_5.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure_5);  //初始化NVIC寄存器
    	
    	TIM_Cmd(TIM5, ENABLE);  //使能TIMx					 
    }
    
    /*-----------------------------------------------------------------------------------------------------*/
    /***********************************上一部分定时器初始化***********************************************/
    /********************************下一部分定时器中断服务函数********************************************/
    /*-----------------------------------------------------------------------------------------------------*/
    //定时器2中断服务程序
    void TIM2_IRQHandler(void)   //TIM2中断
    {
    	if (TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)  //检查TIM3更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //清除TIMx更新中断标志 
    		/*
    			---------------如果使用自己定义定时器中断代码-------------
    		*/	
    		}
    }
    
    //定时器3中断服务程序
    void TIM3_IRQHandler(void)   //TIM3中断
    {
    	if (TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)  //检查TIM3更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除TIMx更新中断标志 
    		/*
    			---------------如果使用自己定义定时器中断代码-------------
    		*/	
    		}
    }
    //定时器4中断服务程序
    void TIM4_IRQHandler(void)   //TIM4中断
    {
    	if (TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)  //检查TIM4更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //清除TIMx更新中断标志 
    		/*
    			--------------如果使用自己定义定时器中断代码-------------
    		*/	
    		}
    }
    //定时器5中断服务程序
    void TIM5_IRQHandler(void)   //TIM5中断
    {
    	if (TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)  //检查TIM5更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM5,TIM_IT_Update);  //清除TIMx更新中断标志 
    		/*
    			-------------如果使用自己定义定时器中断代码-------------
    		*/	
    		}
    }
    
    
    
    //TIM3 PWM部分初始化 
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
    	
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
     
     
       //初始化TIM3
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    	
    	//初始化TIM3 Channel2 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	
    	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1	    PA_6
    	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2		PA_7
    	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
    	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC4
    	
    	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器
    	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM2在CCR3上的预装载寄存器
    	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM2在CCR4上的预装载寄存器
     
    	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
    }
    

    USART

    包括USART.h和USART.c用于串口的初始化,STM32F103有5个串口,这里只配置了前三个串口。
    注意:我只配置了串口,为了方便使用,主程序中虽然调用串口初始化函数,但并没有使用串口。
    在这里插入图片描述

    USART.h

    #ifndef __USART_H
    #define __USART_H
    
    #include "stm32f10x.h"
    #include "sys.h" 
    #include "delay.h"
    
    void USART_Init_1(u32 bound_1);						//串口1初始化声明			32 bound_1   波特率
    
    void USART_Init_2(u32 bound_2);						//串口2初始化声明
    
    void USART_Init_3(u32 bound_3);						//串口3初始化声明
    //串口1用用APB2使能
    //串口2、3、4、5用APB1使能
    
    void USART1_IRQHandler(void);				//串口中断1服务函数
    void USART2_IRQHandler(void);				//串口中断2服务函数
    void USART3_IRQHandler(void);				//串口中断3服务函数
    #endif
    //这里不使用串口4和串口5    固对其不进行配置
    /*RXD:数据输入引脚。数据接受。
    -TXD:数据发送引脚。数据发送。
    串口号	        RXD	            TXD
    	1	        PA10          	PA9
    	2			PA3	  		    PA2
    	3		    PB11	     	PB10
    	4			PC11			PC10
    	5			PD2				PC12*/
    

    USART.c

    #include <USART.h>
    
    void USART_Init_1(u32 bound_1)						//串口1初始化
    {
    	GPIO_InitTypeDef GPIO_InitStrue_1;				//gpio配置结构体
    	USART_InitTypeDef USART_InitStrue_1;			//usart配置结构体
    	NVIC_InitTypeDef NVIC_InitStrue_1;			//串口1中断配置结构体
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);			//GPIOA配置时钟使能			
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);			//USART1配置时钟使能						用APB2使能
    	
    	//USART1_TX   发送       GPIOA.9初始化
    	GPIO_InitStrue_1.GPIO_Mode=GPIO_Mode_AF_PP;		//GPIO_A配置			复用推挽输出
    	GPIO_InitStrue_1.GPIO_Pin=GPIO_Pin_9;				//GPIO_A配置			设置引脚GPIOA_9
    	GPIO_InitStrue_1.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_A配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_1);				//初始化GPIOA_9引脚
    	
    	//USART1_RX	  接收       GPIOA.10初始化
    	GPIO_InitStrue_1.GPIO_Mode=GPIO_Mode_IN_FLOATING;	//GPIO_A配置			浮空输入
    	GPIO_InitStrue_1.GPIO_Pin=GPIO_Pin_10;			//GPIO_A配置			设置引脚GPIOA_10
    	GPIO_InitStrue_1.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_A配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_1);				//初始化GPIOA_10引脚
    	
    	USART_InitStrue_1.USART_BaudRate=bound_1;			//设置串口1的波特率
    	USART_InitStrue_1.USART_HardwareFlowControl=USART_HardwareFlowControl_None;		//无硬件数据流控制
    	USART_InitStrue_1.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;							//使能接收和发送引脚
    	USART_InitStrue_1.USART_Parity=USART_Parity_No;									//无奇偶校验位 
    	USART_InitStrue_1.USART_StopBits=USART_StopBits_1;								//一个停止位 
    	USART_InitStrue_1.USART_WordLength=USART_WordLength_8b;							//字长为 8 位 
    	
    	USART_Init(USART1,&USART_InitStrue_1);			//串口1初始化
    	
    	USART_Cmd(USART1,ENABLE);						//使能串口1
    	
    	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);	//开启接收中断
    	
    	NVIC_InitStrue_1.NVIC_IRQChannel=USART1_IRQn;						//串口1中断
    	NVIC_InitStrue_1.NVIC_IRQChannelCmd=ENABLE;							//IRQ通道使能
    	NVIC_InitStrue_1.NVIC_IRQChannelPreemptionPriority=1;				//抢占优先级1
    	NVIC_InitStrue_1.NVIC_IRQChannelSubPriority=1;						//子优先级1
    	NVIC_Init(&NVIC_InitStrue_1);
    	
    }
    
    void USART_Init_2(u32 bound_2)						//串口2初始化
    {
    	GPIO_InitTypeDef GPIO_InitStrue_2;				//gpio配置结构体
    	USART_InitTypeDef USART_InitStrue_2;			//usart配置结构体
    	NVIC_InitTypeDef NVIC_InitStrue_2;			//串口2中断配置结构体
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);			//GPIOA配置时钟使能			
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);			//USART2配置时钟使能			用APB1使能
    	
    	//USART1_TX   发送       GPIOA.2初始化
    	GPIO_InitStrue_2.GPIO_Mode=GPIO_Mode_AF_PP;		//GPIO_A配置			复用推挽输出
    	GPIO_InitStrue_2.GPIO_Pin=GPIO_Pin_2;				//GPIO_A配置			设置引脚GPIOA_2
    	GPIO_InitStrue_2.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_A配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_2);				//初始化GPIOA_2引脚
    	
    	//USART1_RX	  接收       GPIOA.3初始化
    	GPIO_InitStrue_2.GPIO_Mode=GPIO_Mode_IN_FLOATING;	//GPIO_A配置			浮空输入
    	GPIO_InitStrue_2.GPIO_Pin=GPIO_Pin_3;			//GPIO_A配置			设置引脚GPIOA_3
    	GPIO_InitStrue_2.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_A配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_2);				//初始化GPIOA_3引脚
    	
    	USART_InitStrue_2.USART_BaudRate=bound_2;			//设置串口2的波特率
    	USART_InitStrue_2.USART_HardwareFlowControl=USART_HardwareFlowControl_None;		//无硬件数据流控制
    	USART_InitStrue_2.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;							//使能接收和发送引脚
    	USART_InitStrue_2.USART_Parity=USART_Parity_No;									//无奇偶校验位 
    	USART_InitStrue_2.USART_StopBits=USART_StopBits_1;								//一个停止位 
    	USART_InitStrue_2.USART_WordLength=USART_WordLength_8b;							//字长为 8 位 
    	
    	USART_Init(USART2,&USART_InitStrue_2);			//串口2初始化
    	
    	USART_Cmd(USART2,ENABLE);						//使能串口2
    	
    	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);	//开启接收中断
    	
    	NVIC_InitStrue_2.NVIC_IRQChannel=USART2_IRQn;						//串口2中断
    	NVIC_InitStrue_2.NVIC_IRQChannelCmd=ENABLE;							//IRQ通道使能
    	NVIC_InitStrue_2.NVIC_IRQChannelPreemptionPriority=1;				//抢占优先级1
    	NVIC_InitStrue_2.NVIC_IRQChannelSubPriority=2;						//子优先级2
    	NVIC_Init(&NVIC_InitStrue_2);
    }
    
    void USART_Init_3(u32 bound_3)						//串口3初始化
    {
    	GPIO_InitTypeDef GPIO_InitStrue_3;				//gpio配置结构体
    	USART_InitTypeDef USART_InitStrue_3;			//usart配置结构体
    	NVIC_InitTypeDef NVIC_InitStrue_3;			//串口3中断配置结构体
    	
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);			//GPIOB配置时钟使能			
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);			//USART3配置时钟使能				用APB1使能
    	
    	//USART1_TX   发送       GPIOB.10初始化
    	GPIO_InitStrue_3.GPIO_Mode=GPIO_Mode_AF_PP;		//GPIO_A配置			复用推挽输出
    	GPIO_InitStrue_3.GPIO_Pin=GPIO_Pin_10;				//GPIO_B配置			设置引脚GPIOB_10
    	GPIO_InitStrue_3.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_B配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_3);				//初始化GPIOA_10引脚
    	
    	//USART1_RX	  接收       GPIOB.11初始化
    	GPIO_InitStrue_3.GPIO_Mode=GPIO_Mode_IN_FLOATING;	//GPIO_B配置			浮空输入
    	GPIO_InitStrue_3.GPIO_Pin=GPIO_Pin_11;			//GPIO_B配置			设置引脚GPIOB_1
    	GPIO_InitStrue_3.GPIO_Speed=GPIO_Speed_10MHz;		//GPIO_B配置			设置翻转速度
    	GPIO_Init(GPIOA,&GPIO_InitStrue_3);				//初始化GPIOB_11引脚
    	
    	USART_InitStrue_3.USART_BaudRate=bound_3;			//设置串口2的波特率
    	USART_InitStrue_3.USART_HardwareFlowControl=USART_HardwareFlowControl_None;		//无硬件数据流控制
    	USART_InitStrue_3.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;							//使能接收和发送引脚
    	USART_InitStrue_3.USART_Parity=USART_Parity_No;									//无奇偶校验位 
    	USART_InitStrue_3.USART_StopBits=USART_StopBits_1;								//一个停止位 
    	USART_InitStrue_3.USART_WordLength=USART_WordLength_8b;							//字长为 8 位 
    	
    	USART_Init(USART3,&USART_InitStrue_3);			//串口2初始化
    	
    	USART_Cmd(USART3,ENABLE);						//使能串口2
    	
    	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);	//开启接收中断
    	
    	
    	NVIC_InitStrue_3.NVIC_IRQChannel=USART3_IRQn;						//串口3中断
    	NVIC_InitStrue_3.NVIC_IRQChannelCmd=ENABLE;							//IRQ通道使能
    	NVIC_InitStrue_3.NVIC_IRQChannelPreemptionPriority=1;				//抢占优先级1
    	NVIC_InitStrue_3.NVIC_IRQChannelSubPriority=3;						//子优先级3
    	NVIC_Init(&NVIC_InitStrue_3);	
    
    }
    
    
    /********************************************************************************************************************/
    /*------------------------------------------------中断服务函数------------------------------------------------------*/
    /********************************************************************************************************************/
    void USART1_IRQHandler(void)					//串口中断1服务函数
    {
    	u8 res_1;									//定义接收数据存储变量
    	 if(USART_GetITStatus(USART1,USART_IT_RXNE))		//判断是否接收到
    	{
    		 res_1= USART_ReceiveData(USART1); 		//将接收到的数据存储在res_1中
    		 USART_SendData(USART1,res_1);   		//在上位机中输出显示接收到的数据
    	}
    
    }
    void USART2_IRQHandler(void)					//串口中断2服务函数
    {
    	u8 res_2;									//定义接收数据的存储变量
    	 if(USART_GetITStatus(USART2,USART_IT_RXNE))		//判断是否接收到
    	{
    		 res_2= USART_ReceiveData(USART2); 		//将接收到的数据存储在 res_2
    		 USART_SendData(USART2,res_2);    		//在上位机中输出显示接收到的数据  		
    	}
    }	
    void USART3_IRQHandler(void)					//串口中断3服务函数
    {
    	u8 res_3;									//定义接收数据的存储变量
    	 if(USART_GetITStatus(USART3,USART_IT_RXNE))		//判断是否接收到
    	{
    		 res_3= USART_ReceiveData(USART3); 		//将接收到的数据存储在 res_3 
    		 USART_SendData(USART3,res_3);    		//在上位机中输出显示接收到的数据  		   
    	}	
    }
    

    HARDWEAR

    在该文件中我写了LED闪烁和蜂鸣器1秒的滴滴响,主要用于开机启动,对于主程序没有什么影响,所以就不加以赘述。

    下面对main.c中的函数和主函数进行介绍

    电机控制函数

    这些是连接电机驱动的信号引脚,来控制电机正反转和停止。
    电机驱动可以选择L298N和TB6612
    都是两路的电机驱动,可以控制两个电机,通过PWM输出引脚连接使能端,进行调速,而信号引脚控制电机正反转和停止,

    在主函数里调用定时器输出pwm:

    	TIM_SetCompare1(TIM3,20);							//控制A电机的pwm  全速的20/100
    	TIM_SetCompare2(TIM3,20);							//控制B电机的pwm  全速的20/100
    

    对于占空比进行一下简单的说明
    上面的重装载值arr=99,预分频系数psc=719;(arr+1)(psc+1)
    T=arr * psc /72M,结果为1ms,也就是频率为1000Hz;
    PWM模式设置为TIM_OCMode_PWM2,arr=99,
    arr=20——占空比为20%;

    电机正反转函数:

    void Motor_A_CW(void);					//电机A正转
    void Motor_A_CCW(void);					//电机A反转
    void Motor_B_CW(void);					//电机B正转
    void Motor_B_CCW(void);					//电机B反转
    void Stop_AandB(void);							//电机A和B初始化停止
    

    按键扫描函数

    这里我分别写了四个按键扫描函数,在各个扫描函数中将if条件语句写了两次,用于二次判断,保证按键按下的稳定性。
    还有就是当 mode_1 (这里我以按键1为例)为 0 的时候,KEY_A()函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。
    当 mode _1为 1 的时候,KEY_A()函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。

    u8 Key_A_CW(u8 mode_1);					//按键1控制电机A正转
    u8 Key_A_CCW(u8 mode_2);				//按键2控制电机A反转
    u8 Key_B_CW(u8 mode_3);					//按键3控制电机B正转
    u8 Key_B_CCW(u8 mode_4);				//按键4控制电机B反转
    

    main.c中的所有的程序

    #include <head.h>										//包含所有的头文件和各个端口初始化
    
    #define A_IN1 PCout(0)				//宏定义   PCout位操作 GPIOC的输出引脚(已经在GPIO.c的 GPIO_Init_C()函数中初始化   低电平)   
    #define A_IN2 PCout(1)
    #define B_IN1 PCout(2)
    #define B_IN2 PCout(3)
    
    #define KEY_A PFin(8)				//宏定义   PFin位操作 检测GPIOF的输入引脚(已经在GPIO.c的 GPIO_Init_F()函数中初始化)   
    #define KEY_B PFin(9)
    #define KEY_C PFin(10)
    #define KEY_D PFin(11)
    
    #define KEY1_PRES 	1				//KEY1按下
    #define KEY2_PRES	2				//KEY2按下
    #define KEY3_PRES	3				//KEY3按下
    #define KEY4_PRES	4				//KEY4按下
    /****************函数声明******************/
    void Motor_A_CW(void);					//电机A正转
    void Motor_A_CCW(void);					//电机A反转
    void Motor_B_CW(void);					//电机B正转
    void Motor_B_CCW(void);					//电机B反转
    void Stop_AandB(void);							//电机A和B初始化停止
    
    u8 Key_A_CW(u8 mode_1);					//按键1控制电机A正转
    u8 Key_A_CCW(u8 mode_2);				//按键2控制电机A反转
    u8 Key_B_CW(u8 mode_3);					//按键3控制电机B正转
    u8 Key_B_CCW(u8 mode_4);				//按键4控制电机B反转
    
    /******************函数********************/
    void Motor_A_CW()						//电机A正转
    {
    	A_IN1=1;							//电机A  信号引脚1高电平						
    	A_IN2=0;							//电机A  信号引脚2低电平
    }	
    void Motor_A_CCW()						//电机A反转
    {
    	A_IN1=0;							//电机A  信号引脚1低电平						
    	A_IN2=1;							//电机A  信号引脚2高电平		
    }
    void Motor_B_CW()						//电机B正转
    {
    	B_IN1=1;							//电机B  信号引脚1高电平	
    	B_IN2=0;							//电机B  信号引脚2低电平		
    }
    void Motor_B_CCW()						//电机B反转
    {
    	B_IN1=0;							//电机B  信号引脚1低电平	
    	B_IN2=1;							//电机B  信号引脚2高电平	
    }
    void Stop_AandB()							//电机A和B初始化停止
    {
    	A_IN1=0;							//电机A  信号引脚1低电平						
    	A_IN2=0;							//电机A  信号引脚2低电平
    	B_IN1=0;							//电机B  信号引脚1低电平						
    	B_IN2=0;							//电机B  信号引脚2低电平
    }
    
    
    u8 Key_A_CW(u8 mode_1)					//按键扫描函数        按键1控制电机A正转
    {
    	static u8 key_up_1=1;				//按键按松开标志
    	if(mode_1)key_up_1=1; 				//mode=1  支持连按
    	if(key_up_1&&KEY_A==0)				//KEY_A==0端低电平  上拉输入低电平有效
    	{													
    		delay_us(10);					//延时
    		if(key_up_1&&KEY_A==0)			//二次判断
    		{
    			delay_ms(10);				//去抖动
    			key_up_1=0;					//标志位清零
    			if(KEY_A==0)
    				return KEY1_PRES;		//如果按下返回标志位
    		}
    	}
    	else if(KEY_A==1)
    		 key_up_1=1;					//没有按键按下
    	return 0;							// 无按键按下
    	
    }
    u8 Key_A_CCW(u8 mode_2)					//按键扫描函数        按键2控制电机A反转
    {
    	static u8 key_up_2=1;				//按键按松开标志
    	if(mode_2)key_up_2=1; 				//mode=1  支持连按
    	if(key_up_2&&KEY_A==0)				//KEY_B==0端低电平  上拉输入低电平有效
    	{													
    		delay_us(10);					//延时
    		if(key_up_2&&KEY_A==0)			//二次判断
    		{
    			delay_ms(10);				//去抖动
    			key_up_2=0;					//标志位清零
    			if(KEY_B==0)
    				return KEY2_PRES;		//如果按下返回标志位
    		}
    	}
    	else if(KEY_B==1)
    		 key_up_2=1;					//没有按键按下
    	return 0;							// 无按键按下
    }
    
    u8 Key_B_CW(u8 mode_3)					//按键扫描函数        按键3控制电机B正转
    {
    	static u8 key_up_3=1;				//按键按松开标志
    	if(mode_3)key_up_3=1; 				//mode=1  支持连按
    	if(key_up_3&&KEY_C==0)				//KEY_C==0端低电平  上拉输入低电平有效
    	{													
    		delay_us(10);					//延时
    		if(key_up_3&&KEY_A==0)			//二次判断
    		{
    			delay_ms(10);				//去抖动
    			key_up_3=0;					//标志位清零
    			if(KEY_C==0)
    				return KEY3_PRES;		//如果按下返回标志位
    		}
    	}
    	else if(KEY_C==1)
    		 key_up_3=1;					//没有按键按下
    	return 0;							// 无按键按下
    }
    u8 Key_B_CCW(u8 mode_4)					//按键扫描函数        按键4控制电机B反转
    {
    	static u8 key_up_4=1;				//按键按松开标志
    	if(mode_4)key_up_4=1; 				//mode=1  支持连按
    	if(key_up_4&&KEY_D==0)				//KEY_D==0端低电平  上拉输入低电平有效
    	{													
    		delay_us(10);					//延时
    		if(key_up_4&&KEY_D==0)			//二次判断
    		{
    			delay_ms(10);				//去抖动
    			key_up_4=0;					//标志位清零
    			if(KEY_D==0)
    				return KEY4_PRES;		//如果按下返回标志位
    		}
    	}
    	else if(KEY_D==1)
    		 key_up_4=1;					//没有按键按下
    	return 0;							// 无按键按下
    }
    
    /****************主函数********************/
    int main(void)
    {
    	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//中断优先级分组		
        HEAD_Init();											//all初始化函数
    	Stop_AandB();										//电机A和B初始化停止
    		
    	TIM_SetCompare1(TIM3,20);							//控制A电机的pwm  全速的20/100
    	TIM_SetCompare2(TIM3,20);							//控制B电机的pwm  全速的20/100
    	while(1)
    	{
    		Key_A_CW(1);									 //得到键值
    		Key_A_CCW(1);									 //得到键值
    		Key_B_CW(1);									 //得到键值
    		Key_B_CCW(1);									 //得到键值
    		
    		if(KEY1_PRES==1)								 //判断  标志位是否为1  如果是则执行电机转动程序
    		{
    			Motor_A_CW();						
    		}
    		else											 //如果不是则延时一会,重新循环检测
    			delay_ms(10);
    		if(KEY2_PRES==1)							  	 //判断  标志位是否为1  如果是则执行电机转动程序
    		{
    			Motor_A_CCW();
    		}
    		else											 //如果不是则延时一会,重新循环检测
    			delay_ms(10);
    		if(KEY3_PRES==1)								 //判断  标志位是否为1  如果是则执行电机转动程序
    		{
    			Motor_B_CW();
    		}else											 //如果不是则延时一会,重新循环检测
    			delay_ms(10);
    		if(KEY4_PRES==1)								 //判断  标志位是否为1  如果是则执行电机转动程序
    		{
    			Motor_B_CCW();
    		}
    		else											 //如果不是则延时一会,重新循环检测
    			delay_ms(10);
    	}
    }
    
    /*注意使用串口中断需要现在主函数里进行中断优先级分组  
    形式为: NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   共5组  0、1、2、3、4、*/
    
    
    

    由于没有使用中断,所有我把中断优先级分组给注释掉了

    总结

    程序中有详细的注释,如果想具体的了解可以详细的去看。之所以将GPIO和串口、定时器配置好,是因为我可以吧配置好的当做一个工程模板,下次使用复制一下可以直接取用,根据具体要求,修改修改接口参数就可以了,这样可以大大的节约基础配置的时间。这是我看智能车上逐飞英飞凌的库里就是这样写的,有很大的借鉴之处。

    展开全文
  • STM32F103实现步进电机正反转
  • 基于STM32的直流电机控制pwm控制启动,停止,正反转,转速。 ID:6980622002864004渣渣丶鹏

    基于STM32的直流电机控制pwm控制启动,停止,正反转,转速。

    请添加图片描述
    ID:6980622002864004渣渣丶鹏

    展开全文
  • 题目:基于STM32单片机直流电机控制加减速正反转系统设计 系统框图: 本设计由STM32F103C8T6单片机核心板电路+L298N电机驱动电路+按键电路+电源电路组成。 功能: 1、通过按键可以控制电机,正转、反转、加速、...
  • STM32控制步进电机正反向和加减速,所有程序代码,以及PCB,电路仿真
  • 此模块的功能是实现对直流电机正反转控制,但不能实现调速。优点是功率大,成本低,工作可靠,控制电压范围广、没有发热现象。板子供电电压由继电器额定工作电压决定,比如,继电器是12V的,板子供电电压就是12V。...
  • stm32f10x pwm控制四个电机正反转.zip 。
  • 今天还是想控制直流电机正反转及转速,尝试了很多办法。首先先看一下用控制电平的方法改变正反转及转速的程序。 main.c如下: int main(void) { u16 pwmval; u8 dir=1; u8 key,m1,m2; delay_init(); NVIC_...
  • 实现STM32与直流无刷电机正反转

    千次阅读 2021-04-21 14:16:12
    原理 通俗来讲就是通过电生磁,通电导线绕在磁体上,相邻磁体缠绕方式不同,就会产生不同的极。通过同性相斥,异性相吸的原理,使得电机能转动。...实现电机转动,必须知道相位,常见的三相电机为三相六状态。 ...
  • 本文仅简单驱动该模块并实现直流减速电机的正反控制,并无步进电机控制。 实验环境: (一)STM32F10X 单片机 (二)L298N驱动模块 (三)若干直流减速电机 第一步:L298N正确与STM32接线  我的L298N的模块如下...
  • 本文主要讲了步进电机如何控制正反转,下面一起来学习下
  • stm32f103驱动uln2003步进电机,实现正转和反转。板子使用的是fire-ISOV2,更改下GPIO可试用其他板子。
  • 1、通过按键可以控制电机正转、反转、加速、减速、停止。档位分8档。 2、按键顺序正转、反转、加速、减速、停止。 3.1.2系统总体结构 本系统具体框图如下图所示: 原理图: STM32单片机核心电路设计 STM32系列...
  • STM32用PWM实现小电机正反转

    万次阅读 多人点赞 2019-07-23 21:37:07
    利用可调的PWM脉冲实现步进电机正反转,思路大致是:利用TIM3(STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出)的两个通道输出两道PWM脉冲,控制电机的高低电平以实现电机正反转。 代码...
  • 基于STM32单片机直流电机控制加减速正反转系统.zip
  • STM32小案例01】用STM32简单使用L298N电机驱动模块 控制电机电动推杆)正反转 ​ 本文将简单介绍如何通过L298N电机驱动模块实现直流减速电机电动推杆)的正反转控制,后续会更新含PWM调速的教程,如有需要可...
  • 编码器(测电机正反转)程序,通过脉冲的先后,测电机正、反转与静止。 编码器(测电机正反转)程序,通过脉冲的先后,测电机正、反转与静止。
  • L298N介绍:
  • 手机APP蓝牙控制步进电机正反转+光敏控制电机带APP源码
  • 硬件 1.普中科技STM32-PZ6806D开发板,核心STM32F103ZET6。...3.若不需要使用PWM调速,只需要控制电机正反转,则逻辑A与B跳线帽插上即可,相当于始终使能。 4.若需要使用PWM调速,需将跳线帽拔起...
  • STM32步进电机加减速曲线控制keil5.rar
  • 当使用Hall信号作为位置信号时,需要输入数据,这个数据根据当前使用电机的特性进行输入,会在每次Hall信号变化时同步电角度,如果角度偏差较大时会影响控制效果,可能带来效率或者电机的震荡,初始测试还是有必要的...
  • keil编写,通过中断控制电机正反转,通过pwm的设计,连接l298n一类驱动器可实现普通直流电机的调速,串口控制,指令方便,使用无bug,欢迎下载调试学习!
  • STM32F103zet6通过按键控制L298N,驱动两直流电机正转反转以及停止。keil源文件
  • 实现的功能:按键KEY0控制两个电机的使能,按键WK_UP控制电机正反转,按键KEY1控制电机的加速,按键KEY2控制电机的减速。初始脉冲为5Hz,每加速一次,即按键按下一次增加1Hz,减速也是减小1Hz。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,152
精华内容 460
关键字:

stm32控制电机正反转