找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 864|回复: 3
收起左侧

关于单片机红外控制步进电机程序看不懂

[复制链接]
ID:1069874 发表于 2023-4-12 12:42 | 显示全部楼层 |阅读模式
按照需求整了一个按键控制步进电机基本工作的程序,但是现在要求加入红外控制,也就是要求红外达到和键盘一样的控制效果,然后我现在对红外一窍不通,只能大概看懂解码程序和解码原理,有没有大佬可以指点一下

这里是单片机主程序
#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;        
                }
        }               
}

现在我还偏小白,恳请各位大佬越详细越好
回复

使用道具 举报

ID:646520 发表于 2023-4-12 16:14 | 显示全部楼层
就是个红外编码协议,你照着协议看,就能看懂了,参考下这篇https://blog.51cto.com/u_15127526/3910375
回复

使用道具 举报

ID:230500 发表于 2023-4-12 22:52 | 显示全部楼层
有一说一 代码注释写的很工整规范,值得学习!
回复

使用道具 举报

ID:291668 发表于 2023-4-12 23:27 | 显示全部楼层
基本功扎实,后市可期!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表