按照需求整了一個按鍵控制步進電機基本工作的程序,但是現(xiàn)在要求加入紅外控制,也就是要求紅外達到和鍵盤一樣的控制效果,然后我現(xiàn)在對紅外一竅不通,只能大概看懂解碼程序和解碼原理,有沒有大佬可以指點一下
這里是單片機主程序
#include "public.h" //延時子程序
#include "ired.h" //紅外解碼程序
#define SMG_A_DP_PORT P0 //使用宏定義數(shù)碼管段碼口
//共陰極數(shù)碼管顯示0~F的段碼數(shù)據(jù)
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
/*******************************************************************************
* 函 數(shù) 名 : step_motor_send_pulse
* 函數(shù)功能 : 輸出一個數(shù)據(jù)給TC1508S從而實現(xiàn)向步進電機發(fā)送一個脈沖
* 輸 入 : step:指定步進序號,可選值0~7
dir:方向選擇,1:順時針,0:逆時針
* 輸 出 : 無
*******************************************************************************/
void step_motor_send_pulse(u8 step,u8 dir)
{
u8 temp=step;
if(dir==0) //如果為逆時針旋轉
temp=7-step;//調換節(jié)拍信號
switch(temp)//8個節(jié)拍控制:(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;//停止相序
}
}
/*******************************************************************************
* 函 數(shù) 名 : key_scan
* 函數(shù)功能 : 檢測獨立按鍵是否按下,按下則返回對應鍵值
* 輸 入 : mode=0:單次掃描按鍵
mode=1:連續(xù)掃描按鍵
* 輸 出 : 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;//連續(xù)掃描按鍵
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;
}
/*******************************************************************************
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
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個字節(jié)接收碼(地址碼+地址反碼+控制碼+控制反碼)
/*******************************************************************************
* 函 數(shù) 名 : ired_init
* 函數(shù)功能 : 紅外端口初始化函數(shù),外部中斷0配置
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void ired_init(void)
{
IT0=1; //下降沿觸發(fā)
EX0=1; //打開中斷0允許
EA=1; //打開總中斷
IRED=1; //初始化端口
}
void ired() interrupt 0 //外部中斷0服務函數(shù)
{
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++)//循環(huán)4次,讀取4個字節(jié)數(shù)據(jù)
{
for(j=0;j<8;j++)//循環(huán)8次讀取每位數(shù)據(jù)即一個字節(jié)
{
time_cnt=600;
while((IRED==0)&&time_cnt)//等待數(shù)據(jù)1或0前面的0.56ms結束,若超過6ms強制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt==0)return;
}
time_cnt=20;
while(IRED)//等待數(shù)據(jù)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,數(shù)據(jù)則為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;
}
}
}
現(xiàn)在我還偏小白,懇請各位大佬越詳細越好
|