⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redcode.c

📁 含20个经典例程
💻 C
📖 第 1 页 / 共 2 页
字号:
	testconend2:
	for(j=2;j<codelen-1;j++){//检查首帧和重复帧的数据吻合性,若数据不吻合,则认为出错
		if(abs(sigdata[j]-sigdata[j+200])>200){
			error();
			goto testend;
		}
	}
	//EEPROM第0页和1页存储代码的长度
	tcf.tempval=keysave/CODELEN;//tcf.tempval为代码索引号,即按键值
	tcf.tempval*=2;//代码长度为2字节存储,所以要索引号乘2
	flashwa(tcf.bytek.hi,tcf.bytek.low);//写入EEPROM存储地址,即tcf.tempval值
	tcf.tempval=codelen;
	flashwb(tcf.bytek.hi,0);
	flashwb(tcf.bytek.low,1);//写入代码长度
	tcf.tempval=keysave;//代码数据的存储首地址
	flashwa(tcf.bytek.hi,tcf.bytek.low);
	for(k=0,j=0;k<codelen;k++){//页写入,一次性写入1页
		tcf.tempval=sigdata[k];
		if(j>60){
			j=0;
			flashwb(tcf.bytek.hi,0);
			flashwb(tcf.bytek.low,1);
			keysave+=64;
			tcf.tempval=keysave;
			flashwa(tcf.bytek.hi,tcf.bytek.low);//跳到下一页要先写地址
			continue;
		}
		j+=2;
		flashwb(tcf.bytek.hi,0);
		flashwb(tcf.bytek.low,0);
		
	}
	flashwb(0x00,0);//代码结束时写入0x0000,其作用是再最后一次写操作后产生帧结束信号
	//结束当前写操作
	flashwb(0x00,1);
	//若要完善程序,可在此加入校验代码
	//即读取EEPROM存入的数据与缓冲区内数据比较,若数据不吻合,则重新写入
	EA=0;
	ledl=1;
	testend:;
}
void readdata(void){//将EEPROM数据读入缓冲区,即为待发送代码
	j=0;
	//读取发送指令代码的长度
	tcf.tempval=keysave/CODELEN;
	tcf.tempval*=2;
	flashd.bytek.hi=flashra(tcf.bytek.hi,tcf.bytek.low,0);
	flashd.bytek.low=flashrb(1);
	codelen=flashd.tempval;
	//读取代码数据
	tcf.tempval=keysave;
	flashd.bytek.hi=flashra(tcf.bytek.hi,tcf.bytek.low,0);
	flashd.bytek.low=flashrb(0);
	sigdata[0]=flashd.tempval;
	j+=2;
	for(k=1;k<codelen;){
		if(j>60){
			keysave+=64;
			j=0;
			flashd.bytek.hi=flashrb(0);
			flashd.bytek.low=flashrb(1);
			sigdata[k]=flashd.tempval;
			k++;
			tcf.tempval=keysave;
			flashd.bytek.hi=flashra(tcf.bytek.hi,tcf.bytek.low,0);
			flashd.bytek.low=flashrb(0);
			sigdata[k]=flashd.tempval;
			k++;
			j=2;
			}
		else{
			flashd.bytek.hi=flashrb(0);
			flashd.bytek.low=flashrb(0);
			sigdata[k]=flashd.tempval;
			k++;
			j+=2;
			}
		}
	flashd.bytek.hi=flashrb(0);
	flashd.bytek.low=flashrb(1);//此作用是在最后一次读数据时,产生帧结束信号,结束读取操作
}
void pca0ini(){//T2产生38KHZ方波,要52芯片才有此功能(89c52或89s52均可),51不具备
	T2MOD=0x02;
	T2CON=0x00;
	RCAP2H=0xff;
	RCAP2L=0x6f;
	TH2=RCAP2H;
	TL2=RCAP2L;
}
void encode(void){//将指令发送出去
	ledl=0;
	ledg=1;
	pca0ini();
	TR2=1;
	TR0=0;
	sigout=0;
	isodd=0;
	for(k=0;k<codelen;k++){
		TR0=0;
		//设置定时时间,即代码中的数据值
		tcf.tempval=0xffff-sigdata[k];
		TH0=tcf.bytek.hi;
		TL0=tcf.bytek.low;
		TF0=0;
		TR0=1;
		if(isodd){
			sigout=0;
			isodd=0;
			while(!TF0);
		}
		else{
			isodd=1;
			if(tcf.tempval<0xfff0){//若脉宽时间值大于0xfff0,则不发送红外,即sigout=0
				sigout=1;
				}
			while(!TF0);
		}
	}
	sigout=0;
	ledg=0;
	ledl=1;
}
void error(){
	for(k=0;k<20;k++){//指示灯闪烁4秒,指示代码接收错误
		ledl=0;
		delay1ms(100);
		ledl=1;
		delay1ms(100);
		}
	iserror=1;//并将全局变量错误标志位iserror置1
}
uchar scankey(){//键盘扫描函数
	//need to avoid dead lock
	idata uchar scantmp;
	ledl=1;
	ledg=0;
	if(iskeyboard){//键盘接口下的处理
		P2&=0x03;//p2.7-p2.2为kh5-kh0,将其置0,则若有按键按下,kv5-kv0不全为1		
		if(keyv()==0x3f)//kv5-kv0全为1,则无按键按下,返回0
			return 0;
		delay1ms(20);
		for(k=1;k<7;k++){//将kh5-kh0逐口扫描,确定按键值,
		//若出现串键,则取khi中最大的为有效值
				P2|=0xfc;//将kh5-kh0置1
				scantmp=0x02<<k;//将控制位左移k位
				scantmp=~scantmp;//变为反码,即控制位为0,其他位为1
				P2&=scantmp;//将控制位清零
				delay1ms(1);
				if(keyv()!=0x3f){//读取kv5-kv0的值
				//若kv5-kv0串键,取kvi中i值最大的作为有效值,有效返回值为1-6
					scantmp=6*v_val-6;//kv5-kv0的值和kh5-kh0的值确定按键
					scantmp+=k;
					keysave=scantmp;//键盘返回值为1-36
					ledl=0;
					return scantmp;
					}
		}
		return 0;//其他方式认为是无效按键,返回0
	}
		else{//对MCU并口接口的处理,即由另一个MCU控制其发射接收
			kv5=0;//告诉MCU要取键值,对方MCU检测到kv5为0,则发送键值
			delay1ms(10);//由于对方MCU可能在处理其它程序,延时一段时间确保
			//对方MCU能检测到kv5为0,kv5可接到对方MCU外部事件中断口/INT0
			//或/INT1上提高实时性
			P2|=0xfc;//端口应遵循先置1后读取
			scantmp=keyv2()<<6;//读取kv1-kv0,并将其作为数据第7位和第6位
			scantmp+=P2>>2;//读取kh5-kh0,作为数据的低6位
			keysave=scantmp;//数据有效值为1-255,共可处理255个按键值
			P2|=0xfc;//再读一次键值
			scantmp=keyv2()<<6;
			scantmp+=P2>>2;
			kv5=1;//读完指令将kv5置1,告知对方MCU已经获取其键值
			//所以对方MCU的处理方法为保持键值电平至kv5为1为止
			delay1ms(10);
			if(keysave!=scantmp)//将两次读取值比较,若不一致,则返回0
				return 0;
			ledl=0;
			return scantmp;
		}

}
void decode(){//将按键值转化成EEPROM首入地址,并对红外接收处理
	getkey();
	if(!iskeyboard)
		kv5=1;
	testcon();
	

}
void copyflash(uint adr,uchar len){//EEPROM拷贝测试程序
//读者可将此程序稍加修改,成为拷贝sigdata数组数据到EEPROM指定地址的拷贝函数
	for(k=200;k<len+200;k++){//拷入固定值
		sigdata[k]=13000+k;
		}
	tcf.tempval=adr;
	flashwa(tcf.bytek.hi,tcf.bytek.low);
	for(k=200,j=0;k<200+len;k++){
		tcf.tempval=sigdata[k];
		if(j>60){
			j=0;
			flashwb(tcf.bytek.hi,0);
			flashwb(tcf.bytek.low,1);
			keysave+=64;
			tcf.tempval=keysave;
			flashwa(tcf.bytek.hi,tcf.bytek.low);
			continue;
		
		}
		j+=2;
		flashwb(tcf.bytek.hi,0);
		flashwb(tcf.bytek.low,0);
	}
	flashwb(0x00,0);
	flashwb(0x00,1);
}
void sendcode(){//发送红外指令
	if(iskeyboard)
		while(scankey()==0);//一直等待按键输入
	getkey();
	readdata();//将EEPROM代码数据读入外部内存缓冲区
	do{
		encode();
		_nop_();
		encode();
		sigout=0;
		delay1ms(400);//每隔400ms连续发送2次代码,一般红外接收器均须2次重复代码
		}while(scankey()!=0);
}
uchar keyv2(){//由MCU接口模式下调用
	idata uchar keytmp;
	delay1ms(20);
		keydown=kv0;
		if(keydown)
			keytmp=1;
		else{
			keytmp=0;
			v_val=1;
			}
		keydown=kv1;
		if(keydown)
			keytmp+=2;
		else
			v_val=2;
		return keytmp;
}
uchar keyv(){//由键盘接口模式下调用
	idata uchar keytmp;
	delay1ms(20);
		keydown=kv0;
		if(keydown)
			keytmp=1;
		else{
			keytmp=0;
			v_val=1;
			}
		keydown=kv1;
		if(keydown)
			keytmp+=2;
		else
			v_val=2;
		keydown=kv2;
		if(keydown)
			keytmp+=4;
		else
			v_val=3;
		keydown=kv3;
		if(keydown)
			keytmp+=8;
		else
			v_val=4;
		keydown=kv4;
		if(keydown)
			keytmp+=16;
		else
			v_val=5;
		keydown=kv5;
		if(keydown)
			keytmp+=32;
		else
			v_val=6;
		return keytmp;
}
void xramcheck(){//外部内存检测程序
	ramerror=0;
	for(k=0;k<400;k++){
		sigdata[k]=k+20;
		}
	for(k=0;k<400;k++){
		if(sigdata[k]!=k+20){
			ramerror=1;
			break;
			}
		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -