新手上路
- 积分
- 39
- 金钱
- 39
- 注册时间
- 2016-5-24
- 在线时间
- 6 小时
|
1金钱
遥控时想实现连按重复上次操作(如连按小车前进,不按小车停止),但是现在只能实现按下走一定的延时时间后又停止再按才能走,必须要有一定频率的按键操作才能实现重复上次操作的功能,估计是重复码无法识别,求解决
#include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int
sbit led=P0^0;
sbit IR_INPUT = P3^3; //红外接收引脚
bit irflag = 0; //红外接收标志,收到一帧正确数据后置 1
unsigned char ircode[4]; //红外代码接收缓冲区
unsigned char code LedChar[] = { //??????????
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x84
};
unsigned char LedBuff[4] = {
0xC0, 0xC0, 0xC0, 0xC0
};
#define u16 unsigned int
#define u8 unsigned char
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
sbit key4 = P3^7;
sbit key3 = P3^6;
sbit key2 = P3^5;
sbit key1 = P3^4;
u8 pp;
char sum;
sbit L_PWM=P1^4;
sbit R_PWM=P1^5;
#define L_go IN1=1;IN2=0 //左轮进
#define L_back IN1=0;IN2=1 //左轮退
#define L_stop IN1=0;IN2=0 //左轮停
#define R_go IN3=1;IN4=0 //右轮进
#define R_back IN3=0;IN4=1 //右轮退
#define R_stop IN3=0;IN4=0 //右轮停止
#define car_go L_go;R_go //车向前进
#define car_back L_back;R_back //车倒退
#define car_stop L_stop;R_stop //车停止
#define car_lift R_go;L_stop //车左转
#define car_right L_go;R_stop //车右转
#define car_lift360 L_back;R_go //可以理解为左大转弯
#define car_right360 R_back;L_go //可以理解为右大转弯
void delay(unsigned int t){
while(t--);
}
void delay_ms(u16 x)
{
u8 i;
while(x--)
for(i=0;i<120;i++);
}
void T0_Init()
{
TMOD&=0Xf0;
TMOD|=0x01;
TH0=0XFC; //定时器0实现1ms产生一次中断,若是设置10格调速,则PWM的周期就是10ms
TL0=0X07;
ET0=1;
TR0=1;
EA=1;
}
void time0()interrupt 1
{
TMOD&=0Xf0;
TMOD|=0x01;
TH0=0XFC; //定时器0实现1ms产生一次中断,若是设置10格调速,则PWM的周期就是10ms
TL0=0X07;
pp++;
if(pp>9) pp=0;
if(sum!=0&&sum!=9)
{
if(pp<=sum)
{ L_PWM=1;
R_PWM=1;
}
else
{
L_PWM=0;
R_PWM=0;
}
}
else if(sum==0)
{
L_PWM=0;
R_PWM=0;
}
else if(sum==9)
{
L_PWM=1;
R_PWM=1;
}
}
/* 初始化红外接收功能 */
void InitInfrared(){
IR_INPUT = 1; //确保红外接收引脚被释放
TMOD &= 0x0F; //清零 T1 的控制位
TMOD |= 0x10; //配置 T1 为模式 1
TR1 = 0; //停止 T1 计数
ET1 = 0; //禁止 T1 中断
IT1 = 1; //设置 INT1 为负边沿触发
EX1 = 1; //使能 INT1 中断
}
/* 获取当前高电平的持续时间 */
unsigned int GetHighTime(){
TH1 = 0; //清零 T1 计数初值
TL1 = 0;
TR1 = 1; //启动 T1 计数
while (IR_INPUT){ //红外输入引脚为 1 时循环检测等待,变为 0 时则结束本循环
//当 T1 计数值大于 0x4000,即高电平持续时间超过约 18ms 时,
//强制退出循环,是为了避免信号异常时,程序假死在这里。
if (TH1 >= 0x40){
break;
}
}
TR1 = 0; //停止 T1 计数
return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数
}
/* 获取当前低电平的持续时间 */
unsigned int GetLowTime(){
TH1 = 0; //清零 T1 计数初值
TL1 = 0;
TR1 = 1; //启动 T1 计数
while (!IR_INPUT){ //红外输入引脚为 0 时循环检测等待,变为 1 时则结束本循环
//当 T1 计数值大于 0x4000,即低电平持续时间超过约 18ms 时,
//强制退出循环,是为了避免信号异常时,程序假死在这里。
if (TH1 >= 0x40){
break;
}
}
TR1 = 0; //停止 T1 计数
return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数
}
/* INT1 中断服务函数,执行红外接收及解码 */
void EXINT1_ISR() interrupt 2{
unsigned char i, j;
unsigned char byt;
unsigned int time;
//接收并判定引导码的 9ms 低电平
time = GetLowTime();
//时间判定范围为 8.5~9.5ms,
//超过此范围则说明为误码,直接退出
if ((time<7833) || (time>8755)){
IE1 = 0; //退出前清零 INT1 中断标志
return;
}
//接收并判定引导码的 4.5ms 高电平
time = GetHighTime();
//时间判定范围为 4.0~5.0ms,
//超过此范围则说明为误码,直接退出
if ((time<3686) || (time>4608)){
IE1 = 0;
return;
}
else if((time>1612)&&(time<2534))
{irflag = 1;
IE1 = 0;
return;
}
//接收并判定后续的 4 字节数据
for (i=0; i<4; i++){ //循环接收 4 个字节
for (j=0; j<8; j++){ //循环接收判定每字节的 8 个 bit
//接收判定每 bit 的 560us 低电平
time = GetLowTime();
//时间判定范围为 340~780us,
//超过此范围则说明为误码,直接退出
if ((time<313) || (time>718)){
IE1 = 0;
return;
}
//接收每 bit 高电平时间,判定该 bit 的值
time = GetHighTime();
//时间判定范围为 340~780us,
//在此范围内说明该 bit 值为 0
if ((time>313) && (time<718)){
byt >>= 1; //因低位在先,所以数据右移,高位为 0
//时间判定范围为 1460~1900us,
//在此范围内说明该 bit 值为 1
}else if ((time>1345) && (time<1751)){
byt >>= 1; //因低位在先,所以数据右移,
byt |= 0x80; //高位置 1
}else{ //不在上述范围内则说明为误码,直接退出
IE1 = 0;
return;
}
}
ircode[i] = byt; //接收完一个字节后保存到缓冲区
}
irflag = 1; //接收完毕后设置标志
IE1 = 0; //退出前清零 INT1 中断标志
}
void Date_kandle()
{
if (irflag){ //接收到红外数据时刷新显示
irflag = 0;
LedBuff[0] = LedChar[ircode[0] >> 4]; //用户码显示
LedBuff[1] = LedChar[ircode[0]&0x0F];
LedBuff[2] = LedChar[ircode[2] >> 4]; //键码显示
LedBuff[3] = LedChar[ircode[2]&0x0F];
}
}
void main(){
u8 i,tmp;
EA = 1; //开总中断
// T0_Init();
InitInfrared(); //初始化红外功能
//PT1=1;
while (1)
{
if(irflag)
{
irflag = 0;
tmp=ircode[2];
switch(tmp)//led=~led;break;
{
case 0x40: car_go;break;
case 0x19: car_back;break;
case 0x07: car_lift;break;
case 0x09: car_right;break;
default: break;
}
delay_ms(1000);
}else car_go;
/* Date_kandle();
for(i=0;i<4;i++)
{
P2=0X01<<i;
P1=LedBuff[i];
delay_ms(5);
}*/
}
} |
|