STM32F103+步進電機28BYJ-48 簡單應用之搖頭、轉圈、自定義模式demo


@

前言

具體細節內容可以參考:STM32F103+步進電機28BYJ-48+ULN2003 實現簡單的正反轉demo,這里不再贅述。

代碼下載:

碼雲 GitHub

功能介紹:

1、LED0在不同模式下根據不同時間進行翻轉。
2、按KEY_UP,翻轉LED1,切換模式,分別為

  • 不工作模式 共0.5秒
  • 搖頭模式 (順n個5.625度 停頓x個0.1秒 逆n個5.625度 停頓x個0.1秒) 共0.2x秒
  • 轉圈模式1 (順1圈,停頓y個0.1秒) 共0.1y秒
  • 轉圈模式2 (逆1圈,停頓z個0.1秒) 共0.1z秒
  • 自定義模式 (自行修改代碼) 共3.5秒

3、按KEY0,翻轉LED1,電機順時針旋轉5.625度。按KEY1,翻轉LED1,逆時針旋轉5.625度。(鍵盤外部中斷)

接線

+    —>   5V
-    —>   GND
IN1  —>   PF1
IN2  —>   PF2
IN3  —>   PF3
IN4  —>   PF4

在這里插入圖片描述

效果圖

搖頭模式

// 24 * 5.625 = 135
n = 24; 
// 0.2 * 10 = 2
x = 10;

(順n個5.625度 停頓x個0.1秒 逆n個5.625度 停頓x個0.1秒) 共0.2x秒
在這里插入圖片描述

轉圈模式1

// 0.1 * 5 = 0.5
y = 5;

(順1圈,停頓y個0.1秒) 共0.1y秒
在這里插入圖片描述

轉圈模式2

// 0.1 * 0 = 0
z = 0;

(逆1圈,停頓z個0.1秒) 共0.1z秒
在這里插入圖片描述

自定義模式

在這里插入圖片描述

核心代碼

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "beep.h"
#include "step.h"
#include "exti.h"

//IN4: PB6  d
//IN3: PB5  c
//IN2: PB4  b
//IN1: PB3  a

int main(void)
{
	// n個5.625度
	u8 n = 0;
	// 停頓x,y,z個0.1秒
	u8 x = 0, y = 0, z = 0;
	u8 i = 0;
	delay_init(); //延時函數初始化
	LED_Init();	  //初始化與LED連接的硬件接口
	BEEP_Init();  //初始化蜂鳴器端口
	EXTIX_Init(); // 初始化外部中斷輸入 
	Step_Motor_GPIO_Init(); // 步進電機初始化
	
	LED0 = 0;
	BEEP = 0;
	
	// 24 * 5.625 = 135
	n = 24; 
	// 0.2 * 10 = 2
	x = 10;
	// 0.1 * 5 = 0.5
	y = 5;
	// 0.1 * 0 = 0
	z = 0;
	
	while (1)
	{
		if(1 == mode) // 搖頭模式 (順n個5.625度 停頓x個0.1秒 逆n個5.625度 停頓x個0.1秒) 共0.2x秒
		{
			motor_circle(n, 0, 2);
			for(i = 0; i < x; i++)
			{
				delay_ms(100);
			}
			motor_circle(n, 1, 2);
			for(i = 0; i < x; i++)
			{
				delay_ms(100);
			}
		}
		else if(2 == mode) // 轉圈模式1 (順1圈,停頓y個0.1秒) 共0.1y秒
		{
			motor_circle(64, 0, 2);
			for(i = 0; i < y; i++)
			{
				delay_ms(100);
			}
		}
		else if(3 == mode) // 轉圈模式2 (逆1圈,停頓z個0.1秒) 共0.1z秒
		{
			motor_circle(64, 1, 2);
			for(i = 0; i < z; i++)
			{
				delay_ms(100);
			}
		}
		else if(4 == mode) // 自定義模式 (自行修改代碼) 共3.5秒
		{
			motor_circle(1, 0, 2);
			delay_ms(500);
			motor_circle(2, 0, 2);
			delay_ms(500);
			motor_circle(4, 0, 2);
			delay_ms(500);
			motor_circle(8, 0, 2);
			delay_ms(500);
			motor_circle(16, 0, 2);
			delay_ms(500);
			motor_circle(32, 0, 2);
			delay_ms(500);
			motor_circle(64, 0, 2);
			delay_ms(500);
		}
		else // 不工作模式 共0.5秒
		{
			delay_ms(500);
		}
		
		LED0 = !LED0;
	}
}


step.h

#ifndef  __STEP_H__
#define __STEP_H__
 
#include "stm32f10x.h"
 
void Step_Motor_GPIO_Init(void);
/*
	功能:轉1/64圈
	步距角5.625 360/5.625=64 減速比1/64
	故64*64個脈沖轉一圈
	n 圈數
	direction 方向 1正轉 非1反轉
	delay delay時長 >= 2
*/
void motor_circle(int n, int direction, int delay);

#endif

step.c

#include "sys.h"
#include "delay.h"
#include "step.h"

//IN4: PF4  d
//IN3: PF3  c
//IN2: PF2  b
//IN1: PF1  a

u8 forward[4] = {0x03,0x06,0x0c,0x09}; // 正轉
u8 reverse[4]= {0x03,0x09,0x0c,0x06}; // 反轉

//引腳初始化
void Step_Motor_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
}

//引腳映射
void SetMotor(unsigned char InputData)
{
	if(InputData == 0x03)
	{
		GPIO_SetBits(GPIOF,GPIO_Pin_1);
		GPIO_SetBits(GPIOF,GPIO_Pin_2);
		GPIO_ResetBits(GPIOF,GPIO_Pin_3);
		GPIO_ResetBits(GPIOF,GPIO_Pin_4);
	}
	else if(InputData == 0x06)
	{
		GPIO_ResetBits(GPIOF,GPIO_Pin_1);
		GPIO_SetBits(GPIOF,GPIO_Pin_2);
		GPIO_SetBits(GPIOF,GPIO_Pin_3);
		GPIO_ResetBits(GPIOF,GPIO_Pin_4);
	}
	else if(InputData == 0x09)
	{
		GPIO_SetBits(GPIOF,GPIO_Pin_1);
		GPIO_ResetBits(GPIOF,GPIO_Pin_2);
		GPIO_ResetBits(GPIOF,GPIO_Pin_3);
		GPIO_SetBits(GPIOF,GPIO_Pin_4);
	}
	else if(InputData == 0x0c)
	{	
		GPIO_ResetBits(GPIOF,GPIO_Pin_1);
		GPIO_ResetBits(GPIOF,GPIO_Pin_2);
		GPIO_SetBits(GPIOF,GPIO_Pin_3);
		GPIO_SetBits(GPIOF,GPIO_Pin_4);
	}
	else if(InputData == 0x00)
	{
		GPIO_ResetBits(GPIOF,GPIO_Pin_1);
		GPIO_ResetBits(GPIOF,GPIO_Pin_2);
		GPIO_ResetBits(GPIOF,GPIO_Pin_3);
		GPIO_ResetBits(GPIOF,GPIO_Pin_4);
	}
}

/*
	功能:轉1/64圈
	步距角5.625 360/5.625=64 減速比1/64
	故64*64個脈沖轉一圈
	n 圈數
	direction 方向 1正轉 非1反轉
	delay delay時長ms >= 2
*/
void motor_circle(int n, int direction, int delay)
{
    int i, j;
    for(i = 0; i < n * 8; i++)
    {
		for(j = 0; j < 4; j++)
		{
			if(1 == direction)
			{
				SetMotor(0x00);
				SetMotor(forward[j]);
			}
			else
			{
				SetMotor(0x00);
				SetMotor(reverse[j]);
			}
			
			delay_ms(delay > 2 ? delay : 2);
		}
    }
}

exti.h

#ifndef __EXTI_H
#define __EXIT_H	 
#include "sys.h"

// 工作模式標志位
extern u8 mode;

void EXTIX_Init(void);//外部中斷初始化		 					    
#endif


exti.c

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "beep.h"
#include "exti.h"
#include "step.h"

u8 mode = 0;

//外部中斷0服務程序
void EXTIX_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    KEY_Init();	 //	按鍵端口初始化

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能復用功能時鍾

    //GPIOE.3	  中斷線以及中斷初始化配置 下降沿觸發 //KEY1
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
    EXTI_InitStructure.EXTI_Line=EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStructure);	  	//根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器

    //GPIOE.4	  中斷線以及中斷初始化配置  下降沿觸發	//KEY0
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
    EXTI_InitStructure.EXTI_Line=EXTI_Line4;
    EXTI_Init(&EXTI_InitStructure);	  	//根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器


    //GPIOA.0	  中斷線以及中斷初始化配置 上升沿觸發 PA0  WK_UP
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

    EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&EXTI_InitStructure);		//根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器


    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按鍵WK_UP所在的外部中斷通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//搶占優先級2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;					//子優先級3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中斷通道
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;			//使能按鍵KEY1所在的外部中斷通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//搶占優先級2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子優先級1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中斷通道
    NVIC_Init(&NVIC_InitStructure);  	  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;			//使能按鍵KEY0所在的外部中斷通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//搶占優先級2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子優先級0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中斷通道
    NVIC_Init(&NVIC_InitStructure);  	  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

}

//外部中斷0服務程序
void EXTI0_IRQHandler(void)
{
    delay_ms(10);//消抖
    if(WK_UP==1)	 	 //WK_UP按鍵 工作模式切換
    {
        mode++;
		mode = mode > 4 ? 0 : mode; 
    }
    EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中斷標志位
}


//外部中斷3服務程序
void EXTI3_IRQHandler(void)
{
    delay_ms(10);//消抖
    if(KEY1==0)	 //按鍵KEY1
    {
        // 逆時針轉5.625度
        motor_circle(1, 1, 2);
		LED1 = !LED1;
    }
    EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中斷標志位
}

void EXTI4_IRQHandler(void)
{
    delay_ms(10);//消抖
    if(KEY0==0)	 //按鍵KEY0
    {
		// 順時針轉5.625度
        motor_circle(1, 0, 2);
		LED1 = !LED1;
    }
    EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE4上的中斷標志位
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM