以下是irsensor初始化程序设计
#include "stm32f10x.h"
#ifndef __IRSENSOR_H
#define __IRSENSOR_H
#define RCC_APB2Periph_GPIO RCC_APB2Periph_GPIOB
#define GPIO_Pinx GPIO_Pin_14
#define GPIO GPIOB
#define IRGet_Pin_Status GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)
//以下是中断线的配置
#define GPIO_PortSourceGPIO GPIO_PortSourceGPIOB
#define GPIO_PinSource_PIN GPIO_PinSource14
#define EXTI_Linex EXTI_Line14
//定义结构体,这是在程序写完后的优化,不是预先设计
typedef struct
{
unsigned char key[5]; //key[2]为command,实际命令码,key[0],key[1]为地址码和地址反码;
uint8_t count; //连续递增的计数值
int cnt; //32位的编码计次
}NEC;
void IR_init(void); //IR引脚初始化,EXTI中断线初始化;
void number_back(uint16_t *num); //改变地址传参,指针截引用改变内值 ,返回红外的数据;
#endif
以下是Irsensor传感器的c代码编写:
#include "stm32f10x.h" // Device header
#include "IRsensor.h"
#include "string.h"
#include "Delay.h"
#include "dz.h"
#include "timer.h"
uint16_t flag=0;
NEC nec={0}; //NEC结构体类型的初始化书写;
uint16_t number;
//2,中断定义的建模顺序:开启AFIO以及引脚GPIO的时钟+引脚定义+外部中断(EXIT)定义+NVIC(中断控制器)
void IR_init(void)
{
DZ_init();
//配置AFIO时钟以及引脚GPIO引脚的时钟;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO|RCC_APB2Periph_AFIO , ENABLE);//使能APB2,在总线B的时钟;
//引脚定义
GPIO_InitTypeDef GPIOB_INSTRUCT;//引脚定义声明
GPIOB_INSTRUCT.GPIO_Mode=GPIO_Mode_IN_FLOATING ;//接受信号配置上拉;
GPIOB_INSTRUCT.GPIO_Pin=GPIO_Pinx;
GPIOB_INSTRUCT.GPIO_Speed=GPIO_Speed_50MHz;//
GPIO_Init(GPIO,&GPIOB_INSTRUCT );
//外部中断定义
EXTI_InitTypeDef GPIOB_EXIT;
GPIO_EXTILineConfig(GPIO_PortSourceGPIO, GPIO_PinSource_PIN); //中断线配置;
GPIOB_EXIT.EXTI_Line=EXTI_Linex;
GPIOB_EXIT.EXTI_LineCmd=ENABLE;
GPIOB_EXIT.EXTI_Mode=EXTI_Mode_Interrupt ; //启用中断模式;
GPIOB_EXIT.EXTI_Trigger=EXTI_Trigger_Rising_Falling; //由于NEC编码中有上升沿和下降沿一并存在,所以上升下降皆需要;
EXTI_Init(&GPIOB_EXIT);
//中断控制器的定义//在misc,h中
NVIC_InitTypeDef GPIOB_NVIC;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //整个芯片的分组代 码只用一种,所以若有其他module使用,则只能是其一种;
GPIOB_NVIC.NVIC_IRQChannel=EXTI15_10_IRQn;
GPIOB_NVIC.NVIC_IRQChannelCmd=ENABLE;
GPIOB_NVIC.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级因 为选择了2组值在0~2浮动,这里选择了1
GPIOB_NVIC.NVIC_IRQChannelSubPriority=1; //响应优先级因为选择了2组,所以值在0~2浮动,这里选择了1
NVIC_Init(&GPIOB_NVIC);
NVIC_EnableIRQ(EXTI15_10_IRQn); //中断寄存器使能线
}
//返回外来参数
void number_back(uint16_t *num)
{
*num=number;
}
//外部中断(高电平低电平都会触发)
void EXTI15_10_IRQHandler(void) //中断函数名,需要在启动文件stm32f10x_md.s中寻找;
{
if( EXTI_GetFlagStatus(EXTI_Linex) != RESET)
{
//引脚变化即刻计时
switch(nec.count)//count初始为零
{
case 0:
TIME_OPEN();//计时器打开
TIME_CLEAR();//计时器清零
nec.count++;
break;
case 1:
TIME_CLOSE();//计时器关闭
if(TIME_GET<10000&&TIME_GET>8000)//9.5ms的电平
{
nec.count++;
TIME_OPEN();//计时器打开
TIME_CLEAR();//计时器清零
}
else
{
nec.count=0;
}
break;
case 2:
TIME_CLOSE();//定时器关闭
if(TIME_GET<5500&&TIME_GET>3500)//4.5ms的电平
{
nec.cnt=0;
memset(nec.key,0,sizeof(nec.key));
nec.key[2]=0;
//以上操作是清空数据为,且保证每次循环都有空间。
nec.count++;
}
else
{
nec.count=0;
}
break;
default://以下到达实际nec编码,由于低电平时间一样,所以此时判断高电平时间来决定是1还是0逻辑
if(IRGet_Pin_Status) { TIME_OPEN();TIME_CLEAR(); }//高电平时打开计时器
else
{
TIME_CLOSE();
if(TIME_GET<700&&TIME_GET>400) { } //检测位逻辑0的电平,不执行任何操作
else
if(TIME_GET<1800&&TIME_GET>1500) //脉宽宽度取长一点,以免用不了;
{nec.key[nec.cnt/8] |=1<<(nec.cnt%8);} //检测到逻辑1的操作,执行位移的操作
else
{nec.count=0;}//不为高低电平,就说明传入信息有误,赋值为零,从新开始
if(nec.cnt>=32)
{
nec.count=0; //连续算法的终端位,为下一次信号连续做准备。
if(nec.key[2]-0x40==0)
{
flag=1;
number=0x40;
}
else
if(nec.key[2]!=0x40)
{
flag=1;
number=0x01;
}
}
nec.cnt++;
}
}
EXTI_ClearITPendingBit(EXTI_Linex);//清除中断位(pending bit)标志位;
}
}
//使用红外时解除
//定时4中断,溢出就参数清零
//void TIM4_IRQHandler (void)//计数器4一旦溢出,就触发itconfig的同时也出发其中断函数,进行全局状态的清除,保持信号的连续。
//{
// TIME_CLEAR();
// TIME_CLOSE();
// nec.count=0;
// nec.cnt=0;
// TIM_ClearITPendingBit(TIM,TIM_IT_Update);
//}
基于stm32f103的红外遥控程序设计
于 2024-10-18 00:22:15 首次发布