新手上路
- 积分
- 27
- 金钱
- 27
- 注册时间
- 2017-9-5
- 在线时间
- 3 小时
|

楼主 |
发表于 2017-9-8 11:11:25
|
显示全部楼层
#include "IRCtrol.h"
#include "interface.h"
unsigned char ir_rec_flag=0;//接收数据标志位 1 有新数据 0 没有
unsigned char IRCOM[4];
//use time3 realize delay systick已经在main函数中使用了,在中断中不能重复使用
void Time3Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 1;
TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1);//72M / 72 = 1us
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
}
//1us 延时
void DelayUs(vu32 nCount)
{
u16 TIMCounter = nCount;
TIM_Cmd(TIM3, ENABLE);
TIM_SetCounter(TIM3, TIMCounter);
while (TIMCounter>1)
{
TIMCounter = TIM_GetCounter(TIM3);
}
TIM_Cmd(TIM3, DISABLE);
}
//外部中断配置 红外遥控配置
void IRCtrolInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;//定义一个外部中断相关的结构体
NVIC_InitTypeDef NVIC_InitStructure; //定义一个中断的结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);
GPIO_InitStructure.GPIO_Pin = IRIN_PIN;//配置使能GPIO管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//配置GPIO模式,输入上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置GPIO端口速度
GPIO_Init(IRIN_GPIO , &GPIO_InitStructure);
GPIO_EXTILineConfig(IRIN_PORTSOURCE , IRIN_PINSOURCE);
EXTI_InitStructure.EXTI_Line = IRIN_EXITLINE;//将对应的GPIO口连接到中断线上
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//中断事件类型,下降沿
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择模式,中断型
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能该中断
EXTI_Init(&EXTI_InitStructure);//将配置好的参数写入寄存器
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //阶级为0,不可嵌套
NVIC_InitStructure.NVIC_IRQChannel = IRIN_IRQCH;//打开PINA_8的外部中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//主优先级0,最高
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级,最低
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该模块中断
NVIC_Init(&NVIC_InitStructure); //中断初始化,将结构体定义的数据执行
Time3Init();
}
/*******************************************************************************
* 函 数 名 :DelayIr
* 函数功能 :0.14MS 延时
* 输 入 :无
* 输 出 :无
*******************************************************************************/
void DelayIr(unsigned char x)
{
while(x--)
{
DelayUs(140);
}
}
void IRIntIsr(void)
{
unsigned char j,k,N=0;
DelayIr(15);
if (IRIN==1)
{
return;
}
continue_time = 40;//连发信号,表示指令持续 40*5 = 200ms 无指令停车
//确认IR信号出现
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{DelayIr(1);}
for (j=0;j<4;j++) //收集四组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
{DelayIr(1);}
while (!IRIN) //等 IR 变为高电平
{DelayIr(1);}
while (IRIN) //计算IR高电平时长
{
DelayIr(1);
N++;
if (N>=30)
{
return;} //0.14ms计数过长自动离开。
} //高电平计数完毕
IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //数据最高位补“1”
N=0;
}//end for k
}//end for j
k = ~IRCOM[3];
if (IRCOM[2] != k)
{
return; }
//指令转换
switch(IRCOM[2])
{
case 0x46: ctrl_comm = COMM_UP;break;
case 0x15: ctrl_comm = COMM_DOWN;break;
case 0x44: ctrl_comm = COMM_LEFT;break;
case 0x43: ctrl_comm = COMM_RIGHT;break;
case 0x40: ctrl_comm = COMM_STOP;break;
case 0x16: ctrl_comm = COMM_AUTORUN;break;
case 0x19: ctrl_comm = COMM_XUNJI;break;
default : return;
}
ir_rec_flag = 1;
}
//连接方式 :请参考interface.h文件
//部份源码来源网络--请试用24小时后删除
#include "stm32f10x.h"
#include "interface.h"
#include "LCD1602.h"
#include "IRCtrol.h"
#include "motor.h"
#include "UltrasonicCtrol.h"
#include "redvoid.h"
//全局变量定义
unsigned int speed_count=0;//占空比计数器 50次一周期
char front_left_speed_duty=SPEED_DUTY;
char front_right_speed_duty=SPEED_DUTY;
char behind_left_speed_duty=SPEED_DUTY;
char behind_right_speed_duty=SPEED_DUTY;
unsigned char tick_5ms = 0;//5ms计数器,作为主函数的基本周期
unsigned char tick_1ms = 0;//1ms计数器,作为电机的基本计数器
unsigned char tick_200ms = 0;//刷新显示
char ctrl_comm = COMM_STOP;//控制指令
char ctrl_comm_last = COMM_STOP;//上一次的指令
unsigned char continue_time=0;
//循迹,通过判断三个光电对管的状态来控制小车运动
void SearchRun(void)
{
//三路都检测到
if(SEARCH_M_IO == BLACK_AREA && SEARCH_L_IO == BLACK_AREA && SEARCH_R_IO == BLACK_AREA)
{
ctrl_comm = COMM_UP;
return;
}
if(SEARCH_R_IO == BLACK_AREA)//右
{
ctrl_comm = COMM_RIGHT;
}
else if(SEARCH_L_IO == BLACK_AREA)//左
{
ctrl_comm = COMM_LEFT;
}
else if(SEARCH_M_IO == BLACK_AREA)//中
{
ctrl_comm = COMM_UP;
}
}
int main(void)
{
delay_init();
GPIOCLKInit();
UserLEDInit();
// LCD1602Init();
IRCtrolInit();
TIM2_Init();
MotorInit();
//UltraSoundInit();
RedRayInit();
ServoInit();
while(1)
{
if(tick_5ms >= 5)
{
tick_5ms = 0;
tick_200ms++;
if(tick_200ms >= 40)
{
tick_200ms = 0;
LEDToggle(LED_PIN);
}
//do something
if(ir_rec_flag == 1)//接收到红外信号
{
ir_rec_flag = 0;
switch(ctrl_comm)
{
case COMM_UP: CarGo();break;
case COMM_DOWN: CarBack();break;
case COMM_LEFT: CarLeft();break;
case COMM_RIGHT: CarRight();break;
case COMM_STOP: CarStop();break;
case COMM_AUTORUN: VoidRun();break;
case COMM_XUNJI: SearchRun();break;
default : break;
}
LCD1602WriteCommand(ctrl_comm);
}
}
}
}
|
|