STM32使用数字编码旋钮控制程序

STM32数字编码旋钮的使用,控制LED灯

废话不多说,直接先上程序,后面补充使用中的问题,网上能找到的很多资料要不不好理解,其中有一种会出现死锁的问题,要略加修改,这里是已经修改完成的。这里是调节速度的旋钮,用8个led灯代表8个档位。

用外部中断,上升沿和下降沿都进中断

exti.c
#include "exti.h"
 u8  SP_flag;//速度旋钮A口为低电平
 u8  Current_SP_status;//当前速度状态
 extern int led_SP;//速度LED
//初始化
void My_EXTI_Init(void)
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef  EXTI_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);
    //EXTI9_5 NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//exti9_5中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IQR通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数舒适化NVIC寄存器
    //配置线路
	EXTI_InitStructure.EXTI_Line=EXTI_Line6; 
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Rising_Falling;//上升沿下降沿都触发中断
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure);



void EXTI9_5_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line6)==1)
		{if(SP_Adj_A==1) //A脚为高电平  读取B脚 如果为1则正转 为0反转
			{
				Current_SP_status=SP_Adj_B;  //读取B的状态
				SP_flag=1; //  	      //A为高标志位
				if(SP_flag==1)
						{
							SP_flag=0; //
							if(Current_SP_status==1) //正转   下面写要实现的程序就行(底下的正转也要写)
								{
									led_SP++;
									if(led_SP==9)
										{
											led_SP=8;
										}
								}
							else if(Current_SP_status==0) //反转  下面写要实现的程序就行(底下的反转也要写)
								{
									led_SP--;
									if(led_SP==0)
										{
											led_SP=1;
										}
								}
					}
		}
		if(SP_Adj_A==0) //A脚为低电平  读取B脚 如果为0则正转 为1反转
			{
				Current_SP_status=SP_Adj_B;
				SP_flag=1; 
				if(SP_flag==1)
					{
						SP_flag=0; //
						if(Current_SP_status==0) //正转
							{
								led_SP++;
								if(led_SP==9)
									{
										led_SP=8;
									}
							}
						else if(Current_SP_status==1) //反转
							{
								led_SP--;
								if(led_SP==0)
									{
										led_SP=1;
									}
							}
					}
			}	 
	}
	EXTI_ClearITPendingBit(EXTI_Line6 );
	}

exti.h文件

#ifndef _exti_H
#define _exti_H
#include "system.h"

void My_EXTI_Init(void);

#endif

main.c文件

#include "system.h"
#include "SP.h"
#include "exti.h"
u8  led_SP=1;//led SP标志位

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  My_EXTI_Init();
  TIM3_Init(10,36000-1);//5ms
  SP_Init();

while(1)
{
				switch(led_SP)
					{
			case(1):	
				SP_A_L;SP_B_L;SP_C_H; break;//
			case(2):
			  SP_A_H;SP_B_L;SP_C_H; break;//
				case(3):
		    SP_A_L;SP_B_H;SP_C_H; break;//				
			case(4):
				SP_A_H ;SP_B_H;SP_C_H; break;//
			case(5):
		    SP_A_L;SP_B_L;SP_C_L; break;//			
			case(6):
				SP_A_H;SP_B_L;SP_C_L; break;//
			case(7):
				SP_A_L;SP_B_H;SP_C_L; break;//
			case(8):
				SP_A_H;SP_B_H;SP_C_L; break;//			
          }
}

SP.c

#include "SP.h"
#include "system.h"

void SP_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(SP_PROT_RCC,ENABLE);
	GPIO_InitStructure.GPIO_Pin=SP_A_PIN;  
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	 
	GPIO_Init(SP_A_PORT,&GPIO_InitStructure); 	 
   GPIO_SetBits(SP_A_PORT,SP_A_PIN); 
	
	GPIO_InitStructure.GPIO_Pin=SP_B_PIN; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  
	GPIO_Init(SP_B_PORT,&GPIO_InitStructure); 	  
  GPIO_SetBits(SP_B_PORT,SP_B_PIN); 
	
	GPIO_InitStructure.GPIO_Pin=SP_C_PIN;  
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	
	GPIO_Init(SP_C_PORT,&GPIO_InitStructure); 
  GPIO_SetBits(SP_C_PORT,SP_C_PIN);
}

SP.h

#ifndef _SP_H
#define _SP_H

#include "system.h"

#define SP_A_PIN             GPIO_Pin_12  
#define SP_A_PORT            GPIOC
#define SP_PROT_RCC          RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC


#define SP_B_PIN             GPIO_Pin_2   
#define SP_B_PORT            GPIOD



#define SP_C_PIN             GPIO_Pin_3  
#define SP_C_PORT            GPIOB 


#define SP_A_H  GPIO_SetBits(SP_A_PORT, SP_A_PIN) 
#define	SP_A_L  GPIO_ResetBits(SP_A_PORT, SP_A_PIN)
#define SP_B_H  GPIO_SetBits(SP_B_PORT, SP_B_PIN) 
#define	SP_B_L  GPIO_ResetBits(SP_B_PORT, SP_B_PIN)
#define SP_C_H  GPIO_SetBits(SP_C_PORT, SP_C_PIN) 
#define	SP_C_L  GPIO_ResetBits(SP_C_PORT, SP_C_PIN)

void SP_Init(void);
#endif

这里讲一下过程中容易出现的问题,在学习的教程中只判断A口低电平时候B口是上升沿或者下降沿,并且用了while判断A口状态,每两次转旋钮才会出一次状态,但是只转一下,不转第二下的话会出现死锁,所以,这样分两个部分,在A口是高电平和低电平都判断低电平,且不用while语句就不会出现死锁。
另外这里的译码器不是唯一真值表,具体自己的情况自己判断。

发布了2 篇原创文章 · 获赞 5 · 访问量 33

猜你喜欢

转载自blog.csdn.net/qq_43255107/article/details/105434324