按照需求整了一个按键控制步进电机基本工作的程序,但是现在要求加入红外控制,也就是要求红外达到和键盘一样的控制效果,然后我现在对红外一窍不通,只能大概看懂解码程序和解码原理,有没有大佬可以指点一下
这里是单片机主程序
#include "public.h" //延时子程序
#include "ired.h" //红外解码程序
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//定义TC1508S控制步进电机管脚
sbit IN_A=P1^0;
sbit IN_B=P1^1;
sbit IN_C=P1^2;
sbit IN_D=P1^3;
//定义独立按键控制脚
sbit KEY1=P2^7;
sbit KEY2=P2^6;
sbit KEY3=P2^5;
sbit KEY4=P2^4;
//使用宏定义独立按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
//红外按键键值
#define KEY5_PRESS 0X44
#define KEY6_PRESS 0X40
#define KEY7_PRESS 0X43
#define KEY8_PRESS 0X45
// 定义步进电机速度,值越小,速度越快
// 最小不能小于1
#define STEPMOTOR_MAXSPEED 1
#define STEPMOTOR_MINSPEED 9
/*******************************************************************************
* 函 数 名 : step_motor_send_pulse
* 函数功能 : 输出一个数据给TC1508S从而实现向步进电机发送一个脉冲
* 输 入 : step:指定步进序号,可选值0~7
dir:方向选择,1:顺时针,0:逆时针
* 输 出 : 无
*******************************************************************************/
void step_motor_send_pulse(u8 step,u8 dir)
{
u8 temp=step;
if(dir==0) //如果为逆时针旋转
temp=7-step;//调换节拍信号
switch(temp)//8个节拍控制:(A+)->(A+B+)->(B+)->(B+A-)->(A-)->(A-B-)->(B-)>(B-A+)
{
case 0: IN_A=1;IN_B=0;IN_C=0;IN_D=0;break;
case 1: IN_A=1;IN_B=0;IN_C=1;IN_D=0;break;
case 2: IN_A=0;IN_B=0;IN_C=1;IN_D=0;break;
case 3: IN_A=0;IN_B=1;IN_C=1;IN_D=0;break;
case 4: IN_A=0;IN_B=1;IN_C=0;IN_D=0;break;
case 5: IN_A=0;IN_B=1;IN_C=0;IN_D=1;break;
case 6: IN_A=0;IN_B=0;IN_C=0;IN_D=1;break;
case 7: IN_A=1;IN_B=0;IN_C=0;IN_D=1;break;
default: IN_A=0;IN_B=0;IN_C=0;IN_D=0;break;//停止相序
}
}
/*******************************************************************************
* 函 数 名 : key_scan
* 函数功能 : 检测独立按键是否按下,按下则返回对应键值
* 输 入 : mode=0:单次扫描按键
mode=1:连续扫描按键
* 输 出 : KEY1_PRESS:K1按下
KEY2_PRESS:K2按下
KEY3_PRESS:K3按下
KEY4_PRESS:K4按下
KEY_UNPRESS:未有按键按下
*******************************************************************************/
u8 key_scan(u8 mode)
{
static u8 key=1;
if(mode)key=1;//连续扫描按键
if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下
{
delay_10us(1000);//消抖
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下
{
key=1;
}
return KEY_UNPRESS;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 ired_buf[3];
u8 ired_tempx=0;
u8 ired_tempy=0;
u8 key=0;
u8 dir=0;//默认逆时针方向
u8 speed=STEPMOTOR_MINSPEED;//默认最小速度旋转
u8 step=0;
ired_init();//红外初始化
while(1)
{
key=key_scan(0);
if(key==KEY1_PRESS|ired_tempx==KEY5_PRESS)//换向
{
dir=!dir;
}
else if(key==KEY2_PRESS)//加速
{
if(speed>STEPMOTOR_MAXSPEED)
speed-=1;
}
else if(key==KEY3_PRESS)//减速
{
if(speed<STEPMOTOR_MINSPEED)
speed+=1;
}
step_motor_send_pulse(step++,dir);
if(step==8)step=0;
delay_ms(speed);
if(speed==9)
SMG_A_DP_PORT=~gsmg_code[1];//显示1
if(speed==8)
SMG_A_DP_PORT=~gsmg_code[2];//显示2
if(speed==7)
SMG_A_DP_PORT=~gsmg_code[3];//显示3
if(speed==6)
SMG_A_DP_PORT=~gsmg_code[4];//显示4
if(speed==5)
SMG_A_DP_PORT=~gsmg_code[5];//显示5
if(speed==4)
SMG_A_DP_PORT=~gsmg_code[6];//显示6
if(speed==3)
SMG_A_DP_PORT=~gsmg_code[7];//显示7
if(speed==2)
SMG_A_DP_PORT=~gsmg_code[8];//显示8
if(speed==1)
SMG_A_DP_PORT=~gsmg_code[9];//显示9
}
}
然后这个是红外解码程序
#include "ired.h"
u8 gired_data[4];//存储4个字节接收码(地址码+地址反码+控制码+控制反码)
/*******************************************************************************
* 函 数 名 : ired_init
* 函数功能 : 红外端口初始化函数,外部中断0配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ired_init(void)
{
IT0=1; //下降沿触发
EX0=1; //打开中断0允许
EA=1; //打开总中断
IRED=1; //初始化端口
}
void ired() interrupt 0 //外部中断0服务函数
{
u8 ired_high_time=0;
u16 time_cnt=0;
u8 i=0,j=0;
if(IRED==0)
{
time_cnt=1000;
while((!IRED)&&(time_cnt))//等待引导信号9ms低电平结束,若超过10ms强制退出
{
delay_10us(1);//延时约10us
time_cnt--;
if(time_cnt==0)return;
}
if(IRED)//引导信号9ms低电平已过,进入4.5ms高电平
{
time_cnt=500;
while(IRED&&time_cnt)//等待引导信号4.5ms高电平结束,若超过5ms强制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt==0)return;
}
for(i=0;i<4;i++)//循环4次,读取4个字节数据
{
for(j=0;j<8;j++)//循环8次读取每位数据即一个字节
{
time_cnt=600;
while((IRED==0)&&time_cnt)//等待数据1或0前面的0.56ms结束,若超过6ms强制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt==0)return;
}
time_cnt=20;
while(IRED)//等待数据1或0后面的高电平结束,若超过2ms强制退出
{
delay_10us(10);//约0.1ms
ired_high_time++;
if(ired_high_time>20)return;
}
gired_data[ i]>>=1;//先读取的为低位,然后是高位[ i]
if(ired_high_time>=8)//如果高电平时间大于0.8ms,数据则为1,否则为0
gired_data[ i]|=0x80;[ i]
ired_high_time=0;//重新清零,等待下一次计算时间
}
}
}
if(gired_data[2]!=~gired_data[3])//校验控制码与反码,错误则返回
{
for(i=0;i<4;i++)
gired_data[ i]=0;
return;
}
}
}
现在我还偏小白,恳请各位大佬越详细越好
|