jarry315 发表于 2021-1-28 12:44

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

本帖最后由 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”。Src.zip初次接触东软载波电子,编程习惯与之前有很大的不同,慢慢熟悉之后,发现也不是很难上手。再次感谢21IC论坛以及东软载波电子,祝那些收到开发板的小伙伴们开箱快乐,学习进步。
页: [1]
查看完整版本: 【东软载波ES32F369x+无阻塞LED智能闪烁】