C51:红外通信控制舵机转动

前言

不知道该说什么好。我买了STM32了,opencv终于有用武之地了。


PPM与PWM

PPM,pulse position modulation.比如调制tont_{on}ton​长度,保持tofft_{off}toff​不变。
PWM,pulse width modulation.比如调制占空比tonT\frac{t_{on}}{T}Tton​​,但是周期不变。

C51:红外通信控制舵机转动

我的单片机上的遥控器是发送PPM编码形式的数据。通过不同长度的tont_{on}ton​来定义0和1
C51:红外通信控制舵机转动

红外传输的数据格式

接收完这个32位数据后,用数据反码和数据码比对,作为校验有无错误的措施。
可以看出,周期和起始码的控制是比较麻烦的。
C51:红外通信控制舵机转动

红外遥控原理图

发送端发送脉冲信号,到接收端后转变成数字信号。
C51:红外通信控制舵机转动

红外接收模块

C51:红外通信控制舵机转动
C51:红外通信控制舵机转动

发送模块

C51:红外通信控制舵机转动

用红外接收产生外部中断

通过原理图得知,接收模块的输出端接的是外部中断INT0口。所以可以把接收内容的代码写在外部中断的函数里。

#include"reg52.h"

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit IR_IN=P3^2;//INT0
unsigned char IR_Receive[6];
unsigned char time;
unsigned char leds[3];
unsigned char code table[]={
	0x3f,0x06,0x5b,0x4f,0x66, //01234
	0x6d,0x7d,0x07,	0x7f,0x6f,//56789
	0x77,0x7c,0x39,0x5e,0x79, //abcde
	0x71,0X76 //fh
};

void delay(unsigned int i);
void show();
void IR_Init();
void main(){
	IR_Init();
	while(1)show();
}

void delay(unsigned int i){
	while(i--);
}

void show(){
	unsigned int j;
	leds[0]=table[16];///h
	leds[1]=table[IR_Receive[2]%16];
	leds[2]=table[IR_Receive[2]/16];
	for(j=0;j<3;j++){
		switch(j){
			case 0:
			LSC=0,LSB=0,LSA=0;
			break;
			case 1:
			LSC=0,LSB=0,LSA=1;
			break;
			case 2:
			LSC=0,LSB=1,LSA=0;
			break;
		}

		P0=leds[j];
		delay(100);
		P0=0;
	}

}
void IR_Init(){

	TCON=0x01;//IT0=1
	IE=0x81;//EA=1,EX0=1
	IR_IN=1;//initialize the port
}

void IR_Read()interrupt 0{
	unsigned char i,j;
	unsigned int error;
	

	delay(700);//~7ms
	if(IR_IN==0){
		error=1000;
		while(IR_IN==0&&error>0){ //~9ms
			delay(1);//~10us
			error--;
		}

		if(IR_IN==1){
			error=500;
			while(IR_IN==1&&error>0){ //~4.5ms
				delay(1);
				error--;
			}

			//4X8=32位数据 用户码16位 ,数据码8位,反数据码8位
			for(i=0;i<4;i++){
				for(j=0;j<8;j++){
					time=0;
					
					error=60;
					while(IR_IN==0&&error>0){//~560us
						delay(1);
						error--;
					}

					error=500;
					while(IR_IN==1&&error>0){ //计算高电平的时间长度
						delay(10);//~100us
						error--;
						if(++time>30)return;
					}

					//数据从低位开始传递
					IR_Receive[i]>>=1;
					if(time>=8)
						IR_Receive[i]|=0x80;
					

				}
			} 

		}

		//将数据码和数据反码进行比对
		if(IR_Receive[2]!=~IR_Receive[3])
			return;//出错
	}

}

经过显示,我们明白遥控器上21个按键的编码如下。

45H(开关)       46H(Mode)          47H(声音开关)
44H(播放)       40H(后退)           43H(前进)
07H(EQ)			15H(VOL-)			09H(VOL+)
16H(0)			19H(RPT)            0DH(U/SD)
0CH(1)			18H(2)              5EH(3)
08H(4)          1CH(5)              5AH(6)
42H(7)          52H(8)              4AH(9)

舵机转动

舵机是靠PWM控制的,所以需要改tont_{on}ton​就行了。

C51:红外通信控制舵机转动

上一篇:RTM 全网首发 Exchange 2019 CU1 ISO Download


下一篇:hdu6602---线段树