gaoyang9992006 发表于 2026-3-12 22:06:36

今天拿出来Ai8051U最小开发板写一个函数指针的流水灯

使用AiCube创建工程,将LED的P2端口设置为开漏模式,将按钮P32引脚设置为内部上拉电阻。并设置P32引脚上的INT0外部中断模式为下降沿中断,这样按下就可以触发中断。
接下来编写代码



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


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


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
u8 code ledNum[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
u8 ledIndex;
u8 funindex=0;

void led1(void);
void led2(void);
void (*fun)(void);
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
//<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
// 在此添加用户主函数初始化代码

//<<AICUBE_USER_MAIN_INITIAL_END>>


SYS_Init();

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

while (1)
{
    //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
    // 在此添加主函数中用户主循环代码
    fun();
    //<<AICUBE_USER_MAIN_LOOP_END>>
}
}

////////////////////////////////////////
// 系统初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基

    //<<AICUBE_USER_PREINITIAL_CODE_BEGIN>>
    // 在此添加用户预初始化代码
    //<<AICUBE_USER_PREINITIAL_CODE_END>>

    PORT2_Init();                     //P2口初始化
    PORT3_Init();                     //P3口初始化
    EXTI0_Init();                     //INT0初始化

    //<<AICUBE_USER_INITIAL_CODE_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_INITIAL_CODE_END>>

    EnableGlobalInt();                  //使能全局中断
}

////////////////////////////////////////
// 微秒延时函数
// 入口参数: us (设置延时的微秒值)
// 函数返回: 无
////////////////////////////////////////
void delay_us(uint16_t us)
{
    do
    {
      NOP(34);                        //(MAIN_Fosc + 500000) / 1000000 - 6
    } while (--us);
}


////////////////////////////////////////
// 毫秒延时函数
// 入口参数: ms (设置延时的毫秒值)
// 函数返回: 无
////////////////////////////////////////
void delay_ms(uint16_t ms)
{
    uint16_t i;

    do
    {
      i = MAIN_Fosc / 6000;
      while (--i);
    } while (--ms);
}


//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码
void led1(void)
{
      delay_ms(250);
      P2 = ~ledNum;    //输出低驱动      
      ledIndex++;
      if(ledIndex > 7)
      {
          ledIndex = 0;
      }
}

void led2(void)
{
      delay_ms(250);
      P2 = ledNum;    //输出低驱动      
      ledIndex++;
      if(ledIndex > 7)
      {
          ledIndex = 0;
      }
}
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>


然后在exit.c修改中断函数

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


#include "config.h"


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
//<<AICUBE_USER_INCLUDE_END>>


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



////////////////////////////////////////
// 外部中断INT0初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void EXTI0_Init(void)
{
    INT0_FallingInt();                  //设置外部中断为下降沿中断
    INT0_SetIntPriority(0);             //设置中断为最低优先级
    INT0_EnableInt();                   //使能外部中断

    //<<AICUBE_USER_EXTI0_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_EXTI0_INITIAL_END>>
}


////////////////////////////////////////
// 外部中断INT0中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void EXTI0_ISR(void) interrupt INT0_VECTOR
{
    //<<AICUBE_USER_EXTI0_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
   funindex++;
if(funindex>=2) funindex=0;
    //<<AICUBE_USER_EXTI0_ISR_CODE1_END>>
}


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


这样在中断函数里就可以快速修改索引序号,因为只有2个流水灯花样函数,这里就让这个变量只可以是0或者1,如果有更多花样可以继续添加。
现在编译烧录,单片机就默认单个点亮流动,按下后会立马触发中断进入第二种花样单个熄灭流动。

jwd 发表于 2026-3-13 08:01:31

谢谢楼主分享
页: [1]
查看完整版本: 今天拿出来Ai8051U最小开发板写一个函数指针的流水灯