zhouminjie 发表于 2022-3-27 22:17

【AT-START-F425测评】呼吸灯

#申请原创# 感谢这次能被选中测评雅特力开发板,因为疫情原因被隔离,板子一直不在身边没有及时完成测评,后面加油补上吧。之前的公司项目一直主要使用的ST的方案,国产的32位机暂时只接触过MM32,正好趁这次机会尝试下AT32;
这次先用开发板实现LED呼吸灯。
首先上官网查芯片资料,AT官网:https://www.arterytek.com/cn/index.jsp做的比较好,芯片相关资料丰富,方便用户查找。
下载F425的DS、RM、BSP、keil5版本的Pack。
在keil5的pack installer中安装F425的keil版本pack,安装完成后如下:

新建工程,拷贝BSP压缩包中libraries到工程中,新建其他.c.h文件:

参考AT例程,编写hal_led.c代码如下:
gpio_type *led_gpio_port               = {LEDR_GPIO, LEDY_GPIO, LEDG_GPIO}; //ledIO端口数组
unsigned short led_gpio_pin            = {LEDR_PIN, LEDY_PIN, LEDG_PIN}; //ledIO引脚数组
crm_periph_clock_type led_gpio_crm_clk = {LEDR_GPIO_CRM_CLK, LEDY_GPIO_CRM_CLK, LEDG_GPIO_CRM_CLK}; //ledIO端口时钟数组

/**
       @函数名   at32_led_init
   @描述   ledIO口初始化配置
   @参数   led-R、Y、G
   @返回值   无
   @注意   无
*/
static void at32_led_init(led_type led)
{
    gpio_init_type gpio_init_struct;

    /* enable the led clock */
    crm_periph_clock_enable(led_gpio_crm_clk, TRUE);

    /* set default parameter */
    gpio_default_para_init(&gpio_init_struct);

    /* configure the led gpio */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = led_gpio_pin;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(led_gpio_port, &gpio_init_struct);

}

/**
       @函数名   at32_led_on
   @描述   ledIO口设置低电平
   @参数   led-R、Y、G
   @返回值   无
   @注意   无
*/
void at32_led_on(led_type led)
{
    if(led > (LED_NUM - 1))
      return;

    if(led_gpio_pin)
      gpio_bits_reset(led_gpio_port, led_gpio_pin);
}

/**
       @函数名   at32_led_off
   @描述   ledIO口设置高电平
   @参数   led-R、Y、G
   @返回值   无
   @注意   无
*/
void at32_led_off(led_type led)
{
    if(led > (LED_NUM - 1))
      return;

    if(led_gpio_pin)
      gpio_bits_set(led_gpio_port, led_gpio_pin);
}

/**
       @函数名   at32_led_toggle
   @描述   ledIO口电平取反
   @参数   led-R、Y、G
   @返回值   无
   @注意   无
*/
void at32_led_toggle(led_type led)
{
    if(led > (LED_NUM - 1))
      return;

    if(led_gpio_pin)
      led_gpio_port->odt ^= led_gpio_pin;
}

/**
       @函数名   hal_ledInit
   @描述   led初始化配置
   @参数   无
   @返回值   无
   @注意   无
*/
void hal_ledInit(void)
{
    at32_led_init(LEDR);
    at32_led_init(LEDY);
    at32_led_init(LEDG);
    at32_led_off(LEDR);
    at32_led_off(LEDY);
    at32_led_off(LEDG);
}
hal_timer.c代码如下:
crm_clocks_freq_type crm_clocks_freq_struct = {0}; //系统频率时钟源数组

/**
       @函数名   hal_timerInit
   @描述   timer1初始化,10us定时中断
   @参数   无
   @返回值   无
   @注意   无
*/
void hal_timerInit(void)
{
    /* get system clock */
    crm_clocks_freq_get(&crm_clocks_freq_struct);

    /* enable tmr1 clock */
    crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);

    /* tmr1 configuration */
    /* time base configuration */
    /* systemclock.ahb_freq(96Mhz)/96/10 = 100khz(10us)*/ //(crm_clocks_freq_struct.ahb_freq / 1000000) - 1) = 96000000/1000000-1 = 96-1 =95
    tmr_base_init(TMR1, (10 - 1), (crm_clocks_freq_struct.ahb_freq / 1000000) - 1);
    tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);

    /* overflow interrupt enable */
    tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);

    /* tmr1 overflow interrupt nvic init */
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
    nvic_irq_enable(TMR1_BRK_OVF_TRG_HALL_IRQn, 0, 0);

    /* enable tmr1 */
    tmr_counter_enable(TMR1, TRUE);

}
breathing_led.c代码如下:
static unsigned short PWMCount = 0; //呼吸周期计数
static unsigned short PWMDutyCount = 1; //呼吸周期内占空比计数
static unsigned char Direction = 0; //呼吸方向

/**
       @函数名   Breathing
   @描述   GPIO模拟实现呼吸灯,10us定时器中断函数中调用,呼(吸)周期4ms(呼吸共8ms),每执行一次,周期计数加1,
                呼(吸)周期内占空比计数加(减)1,周期计数=周期占空比计数,led点亮,周期计数>=400,led熄灭
   @参数   无
   @返回值   无
   @注意   无
*/
void Breathing(void)
{
    PWMCount++;

    if(PWMCount >= 400)
    {
      at32_led_off(LEDR);
      at32_led_off(LEDY);
      at32_led_off(LEDG);
      PWMCount = 0;

      if(Direction == 0)
      {
            PWMDutyCount++;

            if(PWMDutyCount > 399)
            {
                Direction = 1;
            }
      }
      else
      {
            PWMDutyCount--;

            if(PWMDutyCount <= 1)
            {
                Direction = 0;
            }
      }
    }
    else if(PWMCount == PWMDutyCount)
    {
      at32_led_on(LEDR);
      at32_led_on(LEDY);
      at32_led_on(LEDG);
    }
}
调试编译下载hex,效果如下:

工程代码:


hejun96 发表于 2022-4-7 09:33

楼主的这个做法比较好,但如果周期是4ms,也就是pwm的频率是250Hz了,对LED来说一般的频率是在1KHz左右会比较好,是不是能再改进下 ?

zhouminjie 发表于 2022-4-10 12:50

感谢建议,我再改进下

zhouminjie 发表于 2022-4-10 12:52

hejun96 发表于 2022-4-7 09:33
楼主的这个做法比较好,但如果周期是4ms,也就是pwm的频率是250Hz了,对LED来说一般的频率是在1KHz左右会比 ...

感谢建议,我再改进下

febgxu 发表于 2022-5-16 10:13

推荐使用pwm控制的

touser 发表于 2022-5-16 11:22

AT-START-F425性能怎么样

tabmone 发表于 2022-5-16 14:05

为什么要使用延时呢?

usysm 发表于 2022-5-16 16:31

呼吸灯做出来好看一些。
页: [1]
查看完整版本: 【AT-START-F425测评】呼吸灯