wuzhengmin 发表于 2026-3-3 20:20:42

我们看看步进电机的驱动函数:
step_motor.C



#include "step_motor.h"

void Step_Motor_Run(u8 step,u8 dir,u8 speed,u16 angle,u8 sta)
//step是节拍数,dir是方向 speed是速度 ganle是角度 sta是运行或停止
{
        u16 j ;
        u8 i = 0 ;
        if(sta==1)
        {
                if(dir==0)//顺时针转
                {
                        //28BYJ-48电机一个脉冲转过的角度:5.625/64,4096个脉冲转1圈
                        //90°就是1024个脉冲,angle度对应的脉冲=(64/45)*angle*8
                       
                        for(j=0;j<64*angle/45;j++)
                        {
                                for(i=0;i<8;i+=8/step) //step是步进--就是节拍数
                                {
                                        switch(i) //8拍8步
                                        {
                                                case 0:MOTOR_IN1=1;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                                //第一步,A 色=0,其他=1,输入刚好相反
                                                case 1:MOTOR_IN1=1;MOTOR_IN2=1;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                                //第二步,A 色=0,B 色=0,其他=1,输入刚好相反
                                                case 2:MOTOR_IN1=0;MOTOR_IN2=1;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                                //第三步,A 色=1,B 色=0,其他=1,输入刚好相反
                                                case 3:MOTOR_IN1=0;MOTOR_IN2=1;MOTOR_IN3=1;MOTOR_IN4=0;break;
                                                //第四步,A 色=1,B 色=0,B 色=0,其他=1,输入刚好相反
                                                case 4:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=1;MOTOR_IN4=0;break;
                                                //第五步,A 色=1,B 色=1,C 色=0,D 色=1,输入刚好相反
                                                case 5:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=1;MOTOR_IN4=1;break;
                                                case 6:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=1;break;
                                                case 7:MOTOR_IN1=1;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=1;break;
                                               
                                        }
                                        delay_ms(speed);
                                       
                                }
                        }
                               
                       
                       
                }
                else//逆时针转,把上面的switch倒过来
                {
                                for(j=0;j<64*angle/45;j++)
                        {
                                for(i=0;i<8;i+=8/step) //step是步进--就是节拍数
                                {
                                        switch(i) //8拍8步
                                        {
                                                case 0:MOTOR_IN1=1;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=1;break;
                                                //第一步,A 色=0,其他=1,输入刚好相反
                                                case 1:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=1;break;
                                                //第二步,A 色=0,B 色=0,其他=1,输入刚好相反
                                                case 2:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=1;MOTOR_IN4=1;break;
                                                //第三步,A 色=1,B 色=0,其他=1,输入刚好相反
                                                case 3:MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=1;MOTOR_IN4=0;break;
                                                //第四步,A 色=1,B 色=0,B 色=0,其他=1,输入刚好相反
                                                case 4:MOTOR_IN1=0;MOTOR_IN2=1;MOTOR_IN3=1;MOTOR_IN4=0;break;
                                                //第五步,A 色=1,B 色=1,C 色=0,D 色=1,输入刚好相反
                                                case 5:MOTOR_IN1=0;MOTOR_IN2=1;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                                case 6:MOTOR_IN1=1;MOTOR_IN2=1;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                                case 7:MOTOR_IN1=1;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=0;break;
                                               
                                        }
                                        delay_ms(speed);
                                       
                                }
                        }
                               
               
                }
               
        }
        else//sta==0 ,电机停止
        {
                MOTOR_IN1=0;MOTOR_IN2=0;MOTOR_IN3=0;MOTOR_IN4=0;//电机停止
        }
}



wuzhengmin 发表于 2026-3-3 20:21:19

#ifndef __STEP_MOTOR_
#define __STEP_MOTOR_

#include "config.h"

#define MOTOR_IN1 P10
#define MOTOR_IN2 P11
#define MOTOR_IN3 P13
#define MOTOR_IN4 P14

#define STEPMOTOR_MAXSPEED1
#define STEPMOTOR_MINSPEED5

void Step_Motor_Run(u8 step,u8 dir,u8 speed,u16 angle,u8 sta);
//step是节拍数,dir是方向 speed是速度 ganle是角度 sta是运行或停止

#endif

wuzhengmin 发表于 2026-3-3 20:22:08

看看主函数:
//<<AICUBE_USER_HEADER_REMARK_BEGIN>>
////////////////////////////////////////
// 在此添加用户文件头说明信息
// 文件名称: main.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2026-03-03) 创建文件
////////////////////////////////////////
//<<AICUBE_USER_HEADER_REMARK_END>>


#include "config.h"                     //默认已包含stdio.h、intrins.h等头文件


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
#include "key.h"
#include "step_motor.h"
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
    //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
    // 在此添加用户主函数初始化代码
        u8 key=0;//保存按键值
        u8 run=0;//1运行0停止
        u8 dir=0;//0是逆时针1是顺时针
        u8 speed = STEPMOTOR_MAXSPEED;
    //<<AICUBE_USER_MAIN_INITIAL_END>>

    SYS_Init();

    //<<AICUBE_USER_MAIN_CODE_BEGIN>>
    // 在此添加主函数中运行一次的用户代码
    //<<AICUBE_USER_MAIN_CODE_END>>

    while (1)
    {
      USBLIB_OUT_Done();            //查询方式处理USB接收的数据

      //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
      // 在此添加主函数中用户主循环代码
                key = KEY_Scan(0); //mode=0 单击 mode=1 长按
                if(key==KEY1_PRESS) run=!run;      //K1控制启停
                else if(key==KEY2_PRESS) dir=!dir;//K2控制方向
                else if(key==KEY3_PRESS)         //K3控制减速
                {
                        speed++;
                        if(speed>STEPMOTOR_MINSPEED )
                        speed= STEPMOTOR_MINSPEED;

                }
                else if(key==KEY4_PRESS)         //K4控制加速
                {
                        speed--;
                        if(speed<STEPMOTOR_MAXSPEED )
                        speed= STEPMOTOR_MAXSPEED;

                }

                Step_Motor_Run(8,dir,speed,1,run);//第4个变量是角度
      //<<AICUBE_USER_MAIN_LOOP_END>>
    }
}

wuzhengmin 发表于 2026-3-4 18:31:57

14.1-外部中断实验-简介1-外部中断实验-简介
本讲主要内容
1.实验介绍
2.硬件设计
3.软件设计
4.实验现象


wuzhengmin 发表于 2026-3-4 18:48:15

1.2 实验目的
使用K1和K2配置外部中断功能,K3和K4配置普通I0口中断功能,K1-K4控制LED1-LED4亮灭。
我的实验板HC6800-ES V2.0 K1 对应P5.1 K2对应P5.2 K3对应P3.2 K4对应P3.3,所以我要把K3和K4配置外部中断功能,K1和K2配置普通I0口中断功能,K1-K4控制LED1-LED4亮灭。
重点是软件配置:




wuzhengmin 发表于 2026-3-4 18:52:10

简单说:4个开关是高阻输入 使能上拉

P20---P23设置为推挽输出 使能上拉

使能系统时钟

使能外部中断1外部中断2


IO口中断我们是这样:K1对应P51 和K2 对应P50 要允许IO口下降沿中断

wuzhengmin 发表于 2026-3-4 19:02:20

按上面的设置,生成框架:

wuzhengmin 发表于 2026-3-4 19:07:58

特别注意普通IO口中断的设置:

直接在管脚IO口设置选择就OK

wuzhengmin 发表于 2026-3-4 20:02:07

这里IO口中断,键的判断:

wuzhengmin 发表于 2026-3-4 20:17:43

看看port.c:

//<<AICUBE_USER_HEADER_REMARK_BEGIN>>
////////////////////////////////////////
// 在此添加用户文件头说明信息
// 文件名称: port.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2026-03-04) 创建文件
////////////////////////////////////////
//<<AICUBE_USER_HEADER_REMARK_END>>


#include "config.h"


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
#include "key.h"
#include "led.h"
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// P2口初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PORT2_Init(void)
{
    SetP2nInitLevelHigh(PIN_ALL);       //设置P2初始化电平
    SetP2nQuasiMode(PIN_7 | PIN_6 | PIN_5 | PIN_4); //设置P2.7,P2.6,P2.5,P2.4为准双向口模式
    SetP2nPushPullMode(PIN_3 | PIN_2 | PIN_1 | PIN_0); //设置P2.3,P2.2,P2.1,P2.0为推挽输出模式

    EnableP2nPullUp(PIN_3 | PIN_2 | PIN_1 | PIN_0); //使能P2.3,P2.2,P2.1,P2.0内部上拉电阻
    DisableP2nPullUp(PIN_7 | PIN_6 | PIN_5 | PIN_4); //关闭P2.7,P2.6,P2.5,P2.4内部上拉电阻
    DisableP2nPullDown(PIN_ALL);      //关闭P2内部下拉电阻
    DisableP2nSchmitt(PIN_ALL);         //使能P2施密特触发
    SetP2nSlewRateNormal(PIN_ALL);      //设置P2一般翻转速度
    SetP2nDrivingNormal(PIN_ALL);       //设置P2一般驱动能力
    SetP2nDigitalInput(PIN_ALL);      //使能P2数字信号输入功能

    //<<AICUBE_USER_PORT2_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_PORT2_INITIAL_END>>
}

////////////////////////////////////////
// P3口初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PORT3_Init(void)
{
    SetP3nInitLevelHigh(PIN_ALL);       //设置P3初始化电平
    SetP3nQuasiMode(PIN_7 | PIN_6 | PIN_5 | PIN_2); //设置P3.7,P3.6,P3.5,P3.2为准双向口模式
    SetP3nHighZInputMode(PIN_4 | PIN_3 | PIN_1 | PIN_0); //设置P3.4,P3.3,P3.1,P3.0为高阻输入模式

    EnableP3nPullUp(PIN_4 | PIN_3);   //使能P3.4,P3.3内部上拉电阻
    DisableP3nPullUp(PIN_7 | PIN_6 | PIN_5 | PIN_2 | PIN_1 | PIN_0); //关闭P3.7,P3.6,P3.5,P3.2,P3.1,P3.0内部上拉电阻
    DisableP3nPullDown(PIN_ALL);      //关闭P3内部下拉电阻
    DisableP3nSchmitt(PIN_ALL);         //使能P3施密特触发
    SetP3nSlewRateNormal(PIN_ALL);      //设置P3一般翻转速度
    SetP3nDrivingNormal(PIN_ALL);       //设置P3一般驱动能力
    SetP3nDigitalInput(PIN_ALL);      //使能P3数字信号输入功能

    //<<AICUBE_USER_PORT3_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_PORT3_INITIAL_END>>
}

////////////////////////////////////////
// P5口初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PORT5_Init(void)
{
    SetP5nInitLevelHigh(PIN_ALL);       //设置P5初始化电平
    SetP5nQuasiMode(PIN_7 | PIN_6 | PIN_5 | PIN_4 | PIN_3 | PIN_2); //设置P5.7,P5.6,P5.5,P5.4,P5.3,P5.2为准双向口模式
    SetP5nHighZInputMode(PIN_1 | PIN_0); //设置P5.1,P5.0为高阻输入模式

    EnableP5nPullUp(PIN_1 | PIN_0);   //使能P5.1,P5.0内部上拉电阻
    DisableP5nPullUp(PIN_7 | PIN_6 | PIN_5 | PIN_4 | PIN_3 | PIN_2); //关闭P5.7,P5.6,P5.5,P5.4,P5.3,P5.2内部上拉电阻
    DisableP5nPullDown(PIN_ALL);      //关闭P5内部下拉电阻
    DisableP5nSchmitt(PIN_ALL);         //使能P5施密特触发
    SetP5nSlewRateNormal(PIN_ALL);      //设置P5一般翻转速度
    SetP5nDrivingNormal(PIN_ALL);       //设置P5一般驱动能力
    SetP5nDigitalInput(PIN_ALL);      //使能P5数字信号输入功能

    SetP5nFallingInt(PIN_1 | PIN_0);    //设置P5.1,P5.0为下降沿中断

    EnableP5nInt(PIN_1 | PIN_0);      //使能P5.1,P5.0口中断

    SetP5IntPriority(0);                //设置中断为最低优先级

    //<<AICUBE_USER_PORT5_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_PORT5_INITIAL_END>>
}


////////////////////////////////////////
// P5中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PORT5_ISR(void) interrupt P5INT_VECTOR
{
    //<<AICUBE_USER_PORT5_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
    uint8_t intf;
        intf = CheckP5nFlag(PIN_ALL);       //读取中断请求标志
    ClearP5nFlag(PIN_ALL);            //清除中断请求标志
       
        if(intf & 0X01)//判断是否P50按下01就是P50,02就是P51,04就是P52,08--P53,10--P54
        {               
                        delay_ms(10);
                        if(intf & 0X01)
                        {
                                printf_usb("K2(P50)按下!\r\n");                // 发送字符串“K2(P50)按下!”
                                LED2=!LED2; //LED1反转
                        }
        }
        else if(intf & 0X02)//判断是否P51按下01就是P50,02就是P51,04就是P52,08--P53,10--P54
               {               
                        delay_ms(10);
                        if(intf & 0X02)
                        {
                                printf_usb("K1(P51)按下!\r\n");                // 发送字符串“K1(P51)按下!”
                                LED1=!LED1; //LED1反转
                        }
               }

    //<<AICUBE_USER_PORT5_ISR_CODE1_END>>
}


//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>


页: 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26 27
查看完整版本: 学习休眠唤醒遇到的问题:1无法开启休眠 2舍弃一下功能后能进入休眠但无法唤醒