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;
}