stm32项目6:红外输入数字与开关灯

该STM32项目实现了通过红外遥控器输入两位数字并控制开关灯的功能。代码基于正点原子例码修改,数码管显示可调整,并有消除鬼影设计。红外接收部分使用TIM3中断服务函数处理信号,LED灯状态受遥控器按键控制。
摘要由CSDN通过智能技术生成

stm32项目6:红外输入数字与开关灯

本项目实现了通过红外遥控器输入两位数字和开关灯,注释中有具体说明。

代码是基于正点原子例码更改的,更改最后面的smg_wei可以调整显示的位数,但显示超过4位会出现闪烁,显示超过2位除右边两位外显示内容均与第一位相同。

main.c文件

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "smg.h"
#include "remote.h"
#include "timer.h"
#include "beep.h"

//共阴数字数组
// 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, 全灭
u8 smg_num[] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e, 0x01, 0x00};
u8 key = 0; //按键值
u8 num = 0xfc;
u8 num1 = 0xfc; 
u8 smg_wei = 0; //数码管位选
u8 smg_duan = 0; //数码管段选
u8 smg_flag = 0; //数码管显示标志0:正常显示 1:消除鬼影
u8 t = 0;
int a=0;
	int b=0;
int main(void)
{

    HAL_Init();                    	//初始化HAL库
    Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M
    delay_init(72);                 //初始化延时函数
    uart_init(115200);	 	        //串口初始化为115200
    LED_Init();		  		        //初始化LED
    BEEP_Init();                    //初始化蜂鸣器
    LED_Init();		  		        //初始化LED
    LED_SMG_Init();                 //初始化数码管
    TIM4_Init(19, 7199);            //数码管2ms定时显示
    Remote_Init();			        //红外接收初始化

    while (1)
    {
    }

}
//定时器4中断服务函数调用
void TIM4_IRQHandler(void)
{
    if (__HAL_TIM_GET_IT_SOURCE(&TIM4_Handler, TIM_IT_UPDATE) != RESET)
    {
        __HAL_TIM_CLEAR_IT(&TIM4_Handler, TIM_IT_UPDATE);

        key = Remote_Scan();

        if (key)
        {
            switch (key)
            {
                case 104:
									a=1;
                    
                    num = smg_num[a];
                    
                    break; //按键1 在第一位输入1

                case 152:
									a=2;
                    
                    num = smg_num[a];
                    
                    break;     //按键2 在第一位输入2

                case 176:
									a=3;
                    
                    num = smg_num[a];
                    
                    break;     //按键'3'

                case 48:
									a=4;
                    
                    num = smg_num[a];
                    
                    break;      //按键'4'

                case 24:
									a=5;
                    
                    num = smg_num[a];
                    
                    break;      //按键'5'

                case 122:
									a=6;
                    
                    num = smg_num[a];
                    
                    break;     //按键'6'

                case 16:
									a=7;
                    
                    num = smg_num[a];
                    
                    break;      //按键'7'

                case 56:
									a=8;
                   
                    num = smg_num[a];
                    
                    break;      //按键'8'

                case 90:
									a=9;
                   
                    num = smg_num[a];
                    
                    break;      //按键'9'

                case 66:
									a=0;
                    
                    num = smg_num[a];
                    
                    break;      //按键'0'
//翻转LED灯时,长按会连续翻转。由于翻转速度快,实际表现为中等速度常亮。
                case 82:
             LED0=!LED0;        
           LED1=!LED1; 
           LED2=!LED2;
				   LED3=!LED3;
			     LED4=!LED4;
				   LED5=!LED5; 
				   LED6=!LED6;
				   LED7=!LED7;
                    break;     //按键'DELETE'翻转所有LED灯

                case 162:
                    LED0=!LED0;
                    break;//按键'POWER'翻转LED0

                case 98:
                    LED4=!LED4;
                    break;//°´¼ü'UP'

                case 226:
                    LED1=!LED1;
                    break;//按键'ALIENTEK'

                case 34:
                    LED6=!LED6;
                    break;//按键'LEFT'

                case 2:
                    num1 = smg_num[a];
                    break;//按键'PLAY'复制第一位数字到第二位

                case 194:
                    LED7=!LED7;
                    break;//按键'RIGHT'

                case 224:
                     LED2=!LED2;
                    break;//按键'VOL-'

                case 168:
                    LED5=!LED5;
                    break;//按键'DOWN'

                case 144:
                     LED3=!LED3;
                    break;//按键'VOL+'
            }
        }

        if (smg_wei == 6) //数码管位
        {
            smg_duan = num1;
        }
        else if (smg_wei == 7)
        {
            smg_duan = num;
        }

        if (smg_flag) LED_Write_Data(0x00, smg_wei); //消除鬼影(段码不显示)
        else 	  LED_Write_Data(smg_duan, smg_wei); //正常显示

        LED_Refresh();//数码管数据更新
        smg_flag = !smg_flag;

        if (smg_flag == 0) //正常显示才更新位码
        {
            smg_wei++;

            if (smg_wei == 8) smg_wei = 6;
        }

        
    }
}

为了方便移植,下面提供三个外设配置文件

smg.c

#include "smg.h"
#include "delay.h"

//ÊýÂë¹ÜÇý¶¯IO³õʼ»¯
void LED_SMG_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
	
   __HAL_RCC_GPIOB_CLK_ENABLE();  
   __HAL_RCC_GPIOC_CLK_ENABLE();  
   __HAL_RCC_AFIO_CLK_ENABLE();   
   __HAL_AFIO_REMAP_SWJ_NOJTAG(); 
	
	//74HC595  DS-PB3 LCLK-PB4 SCK-PB5
    GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  	
    GPIO_Initure.Pull=GPIO_PULLUP;          	
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);   	

	//74HC138  A0-PC10 A1-PC11 A2-PC12
	GPIO_Initure.Pin=GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
	HAL_GPIO_Init(GPIOC,&GPIO_Initure);   	

    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);
}

//num:ÒªÏÔʾµÄÊýÂë¹Ü±àºÅ 0-7(¹²8¸öÊýÂë¹Ü)
void LED_Wei(u8 num)
{
    LED_A0=num&0x01;
	LED_A1=(num&0x02)>>1;
	LED_A2=(num&0x04)>>2;
}

void LED_Write_Data(u8 duan,u8 wei)
{
	u8 i;
	for( i=0;i<8;i++)//ÏÈËͶÎ
	{
		LED_DS=(duan>>i)&0x01;
		LED_SCK=0;
		delay_us(5);
		LED_SCK=1;
	}
    LED_Wei(wei);//ºóÑ¡ÖÐλ
}

void LED_Refresh(void)
{
	LED_LCLK=1;
	delay_us(5);
	LED_LCLK=0;
}

remote.c

#include "remote.h"
#include "delay.h"  	

TIM_HandleTypeDef TIM3_Handler;     

void Remote_Init(void)
{  
    TIM_IC_InitTypeDef TIM3_CH3Config;  
    
    TIM3_Handler.Instance=TIM3;                          
    TIM3_Handler.Init.Prescaler=(72-1);                	
    TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    
    TIM3_Handler.Init.Period=10000;                      
    TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
	TIM3_Handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_IC_Init(&TIM3_Handler);
    
    //³õʼ»¯TIM3ÊäÈ벶»ñ²ÎÊý
    TIM3_CH3Config.ICPolarity=TIM_ICPOLARITY_RISING;   
    TIM3_CH3Config.ICSelection=TIM_ICSELECTION_DIRECTTI;
    TIM3_CH3Config.ICPrescaler=TIM_ICPSC_DIV1;          
    TIM3_CH3Config.ICFilter=0x03;                       
    HAL_TIM_IC_ConfigChannel(&TIM3_Handler,&TIM3_CH3Config,TIM_CHANNEL_3);
    HAL_TIM_IC_Start_IT(&TIM3_Handler,TIM_CHANNEL_3);   
    __HAL_TIM_ENABLE_IT(&TIM3_Handler,TIM_IT_UPDATE);   
}


void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_TIM3_CLK_ENABLE();            
    __HAL_RCC_GPIOB_CLK_ENABLE();			
	
    GPIO_Initure.Pin=GPIO_PIN_0;            
    GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;  	
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);

    HAL_NVIC_SetPriority(TIM3_IRQn,1,3); 	
    HAL_NVIC_EnableIRQ(TIM3_IRQn);       	
}


u8 	RmtSta=0;	  	  
u16 Dval;		
u32 RmtRec=0;		   		    
u8  RmtCnt=0;	

void TIM3_IRQHandler(void)
{
	HAL_TIM_IRQHandler(&TIM3_Handler);
} 


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
 		if(RmtSta&0x80)//ÉÏ´ÎÓÐÊý¾Ý±»½ÓÊÕµ½ÁË
		{	
			RmtSta&=~0X10;						
			if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;
			if((RmtSta&0X0F)<14)RmtSta++;
			else
			{
				RmtSta&=~(1<<7);//Çå¿ÕÒýµ¼±êʶ
				RmtSta&=0XF0;	//Çå¿Õ¼ÆÊýÆ÷	
			}						 	   	
		}	
	}
}


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
		if(RDATA)
		{
			TIM_RESET_CAPTUREPOLARITY(&TIM3_Handler,TIM_CHANNEL_3);   
			TIM_SET_CAPTUREPOLARITY(&TIM3_Handler,TIM_CHANNEL_3,TIM_ICPOLARITY_FALLING);
			__HAL_TIM_SET_COUNTER(&TIM3_Handler,0);  	 	  
		  	RmtSta|=0X10;							
		}else //ϽµÑز¶»ñ
		{
			Dval=HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_3);
			TIM_RESET_CAPTUREPOLARITY(&TIM3_Handler,TIM_CHANNEL_3);   	
			TIM_SET_CAPTUREPOLARITY(&TIM3_Handler,TIM_CHANNEL_3,TIM_ICPOLARITY_RISING);
			if(RmtSta&0X10)							
			{
 				if(RmtSta&0X80)//½ÓÊÕµ½ÁËÒýµ¼Âë
				{
					
					if(Dval>300&&Dval<800)			
					{
						RmtRec<<=1;					
						RmtRec|=0;					
					}else if(Dval>1400&&Dval<1800)	
					{
						RmtRec<<=1;					
						RmtRec|=1;					
					}else if(Dval>2200&&Dval<2600)	2500Ϊ±ê×¼Öµ2.5ms
					{
						RmtCnt++; 					
						RmtSta&=0XF0;					
					}
 				}else if(Dval>4200&&Dval<4700)		
				{
					RmtSta|=1<<7;					
					RmtCnt=0;						
				}						 
			}
			RmtSta&=~(1<<4);
		}
	}
}


u8 Remote_Scan(void)
{        
	u8 sta=0;       
	u8 t1,t2;  
	if(RmtSta&(1<<6))
	{ 
	    t1=RmtRec>>24;			
	    t2=(RmtRec>>16)&0xff;	
 	    if((t1==(u8)~t2)&&t1==REMOTE_ID) 
	    { 
	        t1=RmtRec>>8;
	        t2=RmtRec; 	
	        if(t1==(u8)~t2)sta=t1; 
		}   
		if((sta==0)||((RmtSta&0X80)==0))
		{
		 	RmtSta&=~(1<<6);
			RmtCnt=0;		
		}
	}  
    return sta;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路易斯720

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值