今天拿出来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,如果有更多花样可以继续添加。
现在编译烧录,单片机就默认单个点亮流动,按下后会立马触发中断进入第二种花样单个熄灭流动。
谢谢楼主分享
页:
[1]