打印

【东软载波ES32F369x+无阻塞LED智能闪烁】

[复制链接]
449|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 jarry315 于 2021-1-28 12:47 编辑

LED最为一个常用的电子元件,控制方式也很简单,以下是本人亲测的一款状态机方式的无阻塞式LED频闪控制。
特点是,闪烁次数可调,闪烁周期可调,闪烁时长可调。常用作故障指示,也可以用于蜂鸣器鸣叫等等,比如,故障1=闪烁1下,故障2=闪烁2下。。。

在此,非常感谢21IC论坛和东软载波电子提供的ES32F369x开发板。
以下是申请到的开发套件的全家福

来一张开发板的特写

还提供了东软载波电子的产品线选型指南一份,里面包含了多个系列,包含8位、32位、带LCD、带Touch Key、Cortex-M0、Cortex-M3、RF等等

还有开发工具

最后,还有一份精美的日历



废话不多说,接下来进入正题,准备工作:
SDK下载:http://www.essemi.com/article/c141.html
原理图:http://www.essemi.com/file-download-1561-left.html
MDK5:https://www.keil.com/demo/eval/arm.htm
Keil 5 芯片支持包:http://www.essemi.com/data/source/Eastsoft.ES32_DFP.1.0.9.zip
此外,东软官网也有他们自己提供的开发软件:http://www.essemi.com/article/c52.html

安装开发环境

iDesigner运行环境安装顺序:
1.dotNetFx40_Full_x86_x64.exe
2.dotNetFx40LP_Full_x86_x64中文补丁包.exe
3.VSIsoShell_cn.exe
注:请严格按照以上顺序安装!!

本人使用的是KEIL 5开发的,安装过程就略过了,论坛中有大神贴出来,想了解的小伙伴可以自行搜索一下即可。

接下来,还是大家最关心的代码了
此程序主要是在官方的范例代码的基础上整合起来的,主要用到的范例为:
ES32_SDK_V1.09\Projects\ES32F36xx\Examples_ALD\KEY_LED_ADC
ES32_SDK_V1.09\Projects\ES32F36xx\Examples_ALD\TIMER\01_base

首先,在app目录下,新建代码文件:alarm.c

/*******************************************************************************
*        蜂鸣器鸣叫参数
*/
unsigned char        isMute,NextMute;

struct        AlarmFormat{
        unsigned int        cnt;        // 鸣叫计数器
        unsigned int        time;        // 次数
        unsigned int        period;        // 周期
        unsigned int        pulse;        // 时长
} AlarmData;



/*******************************************************************************
*        函数声明
*/

void        setAlarm( unsigned int count, unsigned int pulse, unsigned int period );
void        alarm( void );
void        Hal_Led_on(void);
void        Hal_Led_off(void);


/******************************************************************************
*        蜂鸣器鸣叫
*/
void        Di(void){        //短鸣叫
        setAlarm( 1, 5,10);        // 测试异步蜂鸣器方式鸣叫
}
void        Dii(void){        //长鸣叫
        setAlarm( 1, 50,55);        // 测试异步蜂鸣器方式鸣叫
}
void        Didi(void){        //长鸣叫
        setAlarm( 2, 5,10);        // 测试异步蜂鸣器方式鸣叫
}



void        setMute(unsigned char cmd){
        if(cmd)        NextMute = 1;
        else{
                NextMute = 0;
                isMute   = 0;
        }

}
/*******************************************************************************
*函数:alarm()
*说明:蜂鸣器鸣叫方式
*        TimerA1周期执行。
*/

void        alarm( void ) {
        //======================================================================
        // 不鸣叫时,直接退出
        if( AlarmData.time == 0 ){
                isMute = NextMute;
                return;
        }
        //======================================================================
        // 鸣叫的脉宽>周期时,全程鸣叫
        if(isMute == 0){
                if( AlarmData.period <= AlarmData.pulse ) {
                        Hal_Led_on();
                }
                else{
                        // 计数器 < 脉宽时,一直鸣叫
                        if( AlarmData.cnt <= AlarmData.pulse ) {
                                Hal_Led_on();
                        }
                        // 脉宽 < 计数器 < 周期时,不鸣叫
                        else{        //  if( AlarmData.cnt <= AlarmData.period ) {
                                Hal_Led_off();
                        }
                }
        }
        //======================================================================
        // 报警次数递减
        if( AlarmData.cnt >= AlarmData.period ) {
                AlarmData.cnt = 0;
                AlarmData.time --;
                if( AlarmData.time == 0) {
                        Hal_Led_off();
                }
        }

        AlarmData.cnt++;
}

/*******************************************************************************
*函数:setAlarm()
*说明:设置报警方式
*参数:count        鸣叫的次数
*        pulse        鸣叫时长,<周期时,间歇鸣叫。>周期时,一直鸣叫
*        period        鸣叫的周期
*/
void        setAlarm( unsigned int count, unsigned int pulse, unsigned int period ) {
        AlarmData.time   = count;        // 报警鸣叫次数
        AlarmData.period = period;        // 报警周期
        AlarmData.pulse  = pulse;        // 报警时长
}

其次,打开KEY_LED_ADC范例,改写main()函数
int main(){
        int diff;

        /* Initialize ALD */
        ald_cmu_init();
        /* Configure system clock */
        ald_cmu_pll1_config(CMU_PLL1_INPUT_HOSC_3, CMU_PLL1_OUTPUT_48M);
        ald_cmu_clock_config(CMU_CLOCK_PLL1, 48000000);
        /* Enable peripheral */
        ald_cmu_perh_clock_config(CMU_PERH_GPIO, ENABLE);
        ald_cmu_perh_clock_config(CMU_PERH_ADC0, ENABLE);
        ald_cmu_perh_clock_config(CMU_PERH_ALL, ENABLE);

        /* Initialize peripheral */
        timer_config();

        bsp_light_init();
        bsp_adc_init();

        bsp_key_init();
        bsp_key_bond_func(BSP_KEY_ALL, key_handle);

        while (1) {
                if(timerFlag){
                        timerFlag=0;
                        if(FlashType==0)                setAlarm(0,0,1000);
                        else if(FlashType==1)        setAlarm(1,200,1000);
                        else if(FlashType==2)        setAlarm(2,200,1000);
                        else if(FlashType==3)        setAlarm(3,200,1000);
                        else                                         setAlarm(4,500,1000);
                }
        }
}
注意:需要新建控制LED的函数,如下:
void        Hal_Led_on(void){
        bsp_light_ctrl(BSP_LIGHT_1, BSP_LIGHT_ON);
}

void        Hal_Led_off(void){
        bsp_light_ctrl(BSP_LIGHT_1, BSP_LIGHT_OFF);
}

然后,在按键事件代码中,添加以下代码:

unsigned char        FlashType;
void key_handle(bsp_key_event_t event){
        switch ((uint32_t)event) {
                //---------------------------------------------------------------------
                case BSP_KEY1_PRESS:
                        FlashType=1;
                        break;
                case BSP_KEY1_RELEASE:
                        break;
                //---------------------------------------------------------------------
                case BSP_KEY2_PRESS:
                        FlashType=2;
                        break;
                case BSP_KEY2_RELEASE:
                        break;
                //---------------------------------------------------------------------
                case BSP_KEY3_PRESS:
                        FlashType=0;
                        break;
                case BSP_KEY3_RELEASE:
                        break;

                //---------------------------------------------------------------------
                case BSP_KEY4_PRESS:
                        FlashType=3;
                        break;
                case BSP_KEY4_RELEASE:
                        break;

                //---------------------------------------------------------------------
                case BSP_KEY5_PRESS:
                        FlashType=4;
                        break;
                case BSP_KEY5_RELEASE:
                        break;
                //---------------------------------------------------------------------
                default:
                        break;
        }
        return;
}
在定时器中断中,添加void alarm(void),如下:

unsigned int        timerCnt;
unsigned char        timerFlag;
void ald_timer_period_elapsed_callback(struct timer_handle_s *arg){
        alarm();
        timerCnt++;
        if(timerCnt>=10000){
                timerFlag = 1;
                timerCnt  = 0;
        }
}
此代码的关机函数为:alarm(),和setAlarm( unsigned int count, unsigned int pulse, unsigned int period )setAlarm()是设置闪烁方式的,alarm()是实现自动闪烁的,一般放在定时器中断中。这样就能实现指示灯的自动闪烁了,同样,这些代码也可以用在蜂鸣器鸣叫程序中。

代码编写完成,进行编译,烧写代码
值得注意的是,使用ES-LINK II烧写软件时,Debug器件应选择“CMSIS-DAP Debugger”

运行代码后,按开发板上的方向按键,指示灯LED1就会周期闪烁了。
最后,上传代码。由于论坛上传的附件有大小限制,因此只上传了“main.c”和“alarm.c”,小伙伴们只需将这两个文件放入代码目录下的“src”文件夹下即可,如“...\ES32_SDK_V1.09\Projects\ES32F36xx\Examples_ALD\KEY_LED_ADC\01_base\Src”。
[url=]Src.zip[/url]
初次接触东软载波电子,编程习惯与之前有很大的不同,慢慢熟悉之后,发现也不是很难上手。再次感谢21IC论坛以及东软载波电子,祝那些收到开发板的小伙伴们开箱快乐,学习进步。

Src.zip

4.43 KB

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

1

粉丝