找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 801|回复: 2
收起左侧

为啥我的步进电机不还原?附单片机程序原理图

[复制链接]
ID:1026086 发表于 2022-5-16 00:37 | 显示全部楼层 |阅读模式
E5~`K1FGVPB0OS_CG)L%B$X.jpg

单片机源程序如下:
#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char                // 以后unsigned char就可以用uchar代替
#define uint  unsigned int                // 以后unsigned int 就可以用uint 代替


sbit ADC_CS     = P1^6;                         // ADC0832的CS引脚
sbit ADC_CLK    = P1^7;                         // ADC0832的CLK引脚
sbit ADC_DAT    = P3^2;                         // ADC0832的DI/DO引脚
sbit KeyMode_P  = P3^3;                                // 模式切换
sbit KeyDown_P  = P3^6;                                // 减按键
sbit KeyUp_P    = P3^7;                                // 加按键
sbit Led_P      = P2^0;                                // 指示灯
uchar gLight      = 40;                                // 窗帘开关的阈值
uchar gMode=1;                                                                // 1是手动模式,2是亮度自动模式
uchar code Clock[]={0x80,0x40,0x20,0x10};                         // 步进电机顺时针旋转数组
uchar code AntiClock[]={0x10,0x20,0x40,0x80};                // 步进电机逆时针旋转数组
/*********************************************************/
// 毫秒级的延时函数,time是要延时的毫秒数
/*********************************************************/
void DelayMs(uint time)
{
        uint i,j;
        for(i=0;i<time;i++)
                for(j=0;j<112;j++);
}

void KeyScanf3()
{
        if(KeyMode_P==0)
        {
                gMode++;                                                        // 切换到下一模式
                if(gMode==3)                                        // 如果到尽头了
                        gMode=1;                                                // 回到第一种模式
                DelayMs(10);                                        // 去除按键按下的抖动
                while(!KeyMode_P);                // 等待按键是否
                DelayMs(10);                                        // 去除按键松开的抖动
        }
}
/*********************************************************/
// ADC0832的时钟脉冲
/*********************************************************/
void WavePlus()
{
        _nop_();
        ADC_CLK = 1;
        _nop_();
        ADC_CLK = 0;
}


/*********************************************************/
// 获取指定通道的A/D转换结果
/*********************************************************/
uchar Get_ADC0832()
{
        uchar i;
        uchar dat1=0;
        uchar dat2=0;
        
        ADC_CLK = 0;                                // 电平初始化
        ADC_DAT = 1;
        _nop_();
        ADC_CS = 0;
        WavePlus();                                        // 起始信号
        ADC_DAT = 1;
        WavePlus();                                        // 通道选择的第一位
        ADC_DAT = 0;      
        WavePlus();                                        // 通道选择的第二位
        ADC_DAT = 1;
        
        for(i=0;i<8;i++)                // 第一次读取
        {
                dat1<<=1;
                WavePlus();
                if(ADC_DAT)
                        dat1=dat1|0x01;
                else
                        dat1=dat1|0x00;
        }
        
        for(i=0;i<8;i++)                // 第二次读取
        {
                dat2>>= 1;
                if(ADC_DAT)
                        dat2=dat2|0x80;
                else
                        dat2=dat2|0x00;
                WavePlus();
        }
        
        _nop_();                                                // 结束此次传输
        ADC_DAT = 1;
        ADC_CLK = 1;
        ADC_CS  = 1;   

        if(dat1==dat2)                        // 返回采集结果
                return dat1;
        else
                return 0;
}

/*********************************************************/
// 开窗
/*********************************************************/
void Open()
{
        uint i,j;
        for(j=0;j<255;j++)                // 控制步进电机正转
        {
                for(i=0;i<4;i++)
                {
                        P2=Clock[ i];
                        DelayMs(3);
                }
        }
        Led_P=0;
}
/*********************************************************/
// 关窗
/*********************************************************/
void Close()
{
        uint i,j;
        for(j=0;j<255;j++)                // 控制步进电机反转
        {
                for(i=0;i<4;i++)
                {
                        P2=AntiClock[ i];
                        DelayMs(3);
                }
        }
        Led_P=1;
}
/*********************************************************/
// 主函数
/*********************************************************/
void main()
{
        uchar light;
while(1)
        {
                light=Get_ADC0832();
                light=light/2.5;                                        // 缩小光照检测结果(在0-99)
                if(light>99)                                                        // 如果大于99
                        light=99;                                                                // 则依然保持99
                KeyScanf3();                                                        // 按键扫描(模式切换)
                /*手动控制模式*/
                if(gMode==1)
                {
                        if(KeyDown_P==0)                // 如果关窗帘键按下了        
                        {
                                if(Led_P==0)                        // 如果窗帘当前是打开的
                                {
                                        Close();                                // 则关闭窗帘
                                }
                        }
                        if(KeyUp_P==0)                        // 如果开窗帘键按下了
                        {
                                if(Led_P==1)                        // 如果窗帘当前是关闭的
                                {
                                        Open();                                        // 则打开窗帘
                                }
                        }        
                }
               
        
                /*光线控制模式*/
                if(gMode==2)
                {
                        if(light<gLight)                // 当前光线小于设置的阈值
                        {
                                if(Led_P==0)                        // 如果窗帘当前是打开的
                                {
                                        Close();                                // 则关闭窗帘
                                }
                        }
                        else                                                                // 当前光线大于或等于设置的阈值
                        {
                                if(Led_P==1)                        // 如果窗帘当前是关闭的
                                {
                                        Open();                                        // 则打开窗帘
                                }
                        }        
                }
               
                DelayMs(100);                                                        // 延时0.1秒
        }
}
回复

使用道具 举报

ID:161164 发表于 2022-5-16 09:30 | 显示全部楼层
啥叫还原?
回复

使用道具 举报

ID:123289 发表于 2022-5-16 10:35 | 显示全部楼层
这里的“还原”是指什么?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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