[MM32硬件] 【EV Board (MM32L0136C7P)测评】玩透基于Systick的多种应用

[复制链接]
1230|5
 楼主| lilijin1995 发表于 2022-11-27 20:36 | 显示全部楼层 |阅读模式
本帖最后由 lilijin1995 于 2022-12-1 19:39 编辑

各位大佬,大家好,我又来水帖子了,本期给大家带来的是MM32L0136C7P的评估板测试。
哈哈,又是一个玩梗的案子。

2022年11月27日:
基于Systick实现1ms中断
● 开箱晒图:
收到EVB-l0136正是我换了新工作台面的日子,可谓双喜临门!!!
86215638357e04f4a0.jpg
特性介绍:
  • Arm Cortex-M0+ 内核
  • 板载 MM32L0136C7P(LQFP64)
  • 外扩 UART、SPI、Micro-USB 接口
  • 4 x Key、4 x LED
  • 4 x 功能选择开关
  • I2S Speaker
  • 板载段码 LCD 屏

主控芯片介绍:
       MM32L0136 微控制器搭载 Arm ® Cortex ® -M0+ 内核,最高工作频率可达 48MHz。内置
64KB 高速存储器,并集成了丰富的 I/O 端口和外设模块。MM32L0136 包含 1 个 12 位的 ADC、
1 个比较器、2 个 16 位通用定时器、2 个 16 位基本定时器、1 个低功耗定时器和 1 个 RTC
计数器,还包含标准的通信接口:2 个 UART 接口、1 个低功耗 UART 接口、2 个 SPI 接
口、2 个 I2S 接口和 1 个 I2C 接口。此外,MM32L0136 还内置了段码式液晶驱动模块(SLCD)
和红外信号调制模块(IRM)。
MM32L0136 工作电压为 1.8V ∼ 5.5V,工作温度范围(环境温度)为 -40°C ∼ +85°C。内置
多种省电工作模式保证低功耗应用的要求。
这些丰富的外设配置,使得本产品微控制器适合于多种应用场合:
       • 空调遥控器
       • 温控器
       • 耳、额温枪
       • 便携医疗设备
       • 气、水、热表
       • 小家电
MM32L0136 提供 LQFP64 和 LQFP48 封装形式。
● 上电测试:
       收到后,简单了玩了以下,板子可播放音乐因为有I2S Speak,强!!!并且断码屏也有对应的显示。简单看了以下外设例程
9603063835adca63f8.png

另外有其他应用例程
701863835b08c940f.png
同时有如下组件
3944963835b261195f.png
例程可如此丰富,满足了绝大部分应用场景。
● 搭建开发环境:
软件安装、驱动安装、例程库资源下载。
SDK 软件请从 https://mindsdk.mindmotion.com.cn 下载,需要注册一下
我习惯于使用MDK开发,而使用MDK需要对应的MCU支持包,这里官网可以下载,并且一步到位,提供了多款MCU的。
9718663835db729a36.png

● 例程测试:
看了多个例程,而且我发现所有例程竟然没有一个例程是基于systick实现delay的,所以我的第一个想法是自己实现一个delay,但前提又是基于Systick需要有一个准确的时基。所以这里先来实现一个准确的1ms的SysTick_Handler。测试的话就用LED2对应的PB9。
首先我创建了一个MyBSP文件夹和代码分组存放我们自己写的代码,以下是Systick.c

  1. #include "Systick.h"
  2. #include "clock_init.h"
  3. #include "board_init.h"

  4. u8 i = 0;
  5. u32 Counter = 0;

  6. void SysTick_Handler(void)
  7. {
  8.     Counter++;
  9.     if(Counter >= 500) {
  10.         Counter = 0;
  11.                 GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, (i == 0) ? (i = 1) : (i = 0)); /* led off. */
  12.     }
  13. }

  14. void Systick_init(void)
  15. {
  16.     if (SysTick_Config(CLOCK_SYSTICK_FREQ)) {
  17.         // Capture error
  18.         while (1);
  19.     }
  20.     // Configure the SysTick handler priority
  21.     NVIC_SetPriority(SysTick_IRQn, 0x0);//SysTickinterrupt priority class set
  22. }




其中GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, (i == 0) ? (i = 1) : (i = 0))是翻转LED2.
SysTick_Config是系统Tick配置初始化系统计时器及其中断,并启动系统计时计时器。CLOCK_SYSTICK_FREQ是两个中断之间的滴答数如下定义
  1. <font face="楷体, 楷体_GB2312">#define CLOCK_SYS_FREQ         48000000u
  2. #define CLOCK_SYSTICK_FREQ     (CLOCK_SYS_FREQ/1000u)</font>
系统时钟是48MHz,Systick=CLOCK_SYS_FREQ/1000  则是配置了1ms中断,即1ms进入SysTick_Handler一次,Counter 自加500次则每500ms翻转一次,也就是说灯闪烁1Hz频率。使用逻辑分析仪测得正是1Hz。

46469638364b3858bc.png

2022年11月28日:
基于Systick实现us与ms延迟
我们上节基于systick实现了1ms中断,我们今天实现两个延迟函数,delayus与delayms。
首先是初始化:
  1. #define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)
这里SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8是选择系统时钟源8分频,所以CLOCK_SYSTICK_FREQ=CLOCK_SYS_FREQ/8000000,
最后通过我们在main函数中测试一下。

首先是delayus测试,
  1. int main(void)
  2. {
  3.         u8 i = 0;
  4.     BOARD_Init();
  5.         delay_init();

  6.     while (1)
  7.     {

  8.                 delay_us(1);
  9.                
  10.                 GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, (i == 0) ? (i = 1) : (i = 0)); /* led off. */

  11.     }
  12. }
目的是翻转LED2,测得时序如下:
473736384bc2859a2c.png

可以看到us延迟不准确,然后C语言编译之后指令周期肯定不是1us,但总感觉不是那么准了。这里就不深究了。
接着我们测试ms
  1. <font face="楷体, 楷体_GB2312">int main(void)
  2. {
  3.         u8 i = 0;
  4.     BOARD_Init();
  5.         delay_init();

  6.     while (1)
  7.     {

  8.                 delay_ms(1);
  9.                
  10.                 GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, (i == 0) ? (i = 1) : (i = 0)); /* led off. */

  11.     }
  12. }</font>

测得的时序如下,
309806384bd37e6301.png
ms是准的。

2022年11月30日:

3.3.1简介
MultiTimer 是一个软件定时器扩展模块,可无限扩展你所需的定时器任务,取代传统的标志位判断方式, 更优雅更便捷地管理程序的时间触发时序。
3.3.2使用方法
  • 配置系统时间基准接口,安装定时器驱动;
  • 实例化一个定时器对象;
  • 设置定时时间,超时回调处理函数, 用户上下指针,启动定时器;
  • 在主循环调用定时器后台处理函数

3.3.3功能限制
1.定时器的时钟频率直接影响定时器的精确度,尽可能采用1ms/5ms/10ms这几个精度较高的tick;

2.定时器的回调函数内不应执行耗时操作,否则可能因占用过长的时间,导致其他定时器无法正常超时;

3.由于定时器的回调函数是在 MultiTimerYield 内执行的,需要注意栈空间的使用不能过大,否则可能会导致栈溢出。

3.3.4移植到EV Board (MM32L0136C7P)
第一步是配置好时基函数:

  1. u32 Counter = 0;

  2. void SysTick_Handler(void)
  3. {
  4.     Counter++;

  5. }

  6. uint32_t HAL_GetTick(void)
  7. {
  8.   return Counter;
  9. }


第二步是实例化两个定时器对象,一个用于按键扫描,一个用于控制LED的灯。
  1. MultiTimer timer1;
  2. MultiTimer timer2;
第三步,设置定时时间,超时回调处理函数, 用户上下指针,启动定时器;


  1. static uint8_t keydown=0;

  2. void KeyTimer1Callback(MultiTimer* timer, void *userData)
  3. {
  4.         if(GPIO_ReadInDataBit(GPIOD,GPIO_PIN_5)==0)
  5.         {
  6.                 printf("Key0 dowm!\r\n");
  7.                 keydown=1;
  8.         }else{
  9.                 keydown=0;
  10.                 printf("Key0 up!\r\n");
  11.         }
  12.     MultiTimerStart(timer, 10, KeyTimer1Callback, userData);
  13. }

  14. void LEDTimer2Callback(MultiTimer* timer, void *userData)
  15. {
  16.         if(keydown==1)
  17.         {
  18.                 GPIO_WriteBit(GPIOB,GPIO_PIN_10,0);
  19.                 printf("LED ON!\r\n");
  20.         }else{
  21.                 GPIO_WriteBit(GPIOB,GPIO_PIN_10,1);
  22.                 printf("LED OFF!\r\n");           
  23.         }
  24.     MultiTimerStart(timer, 10, LEDTimer2Callback, userData);
  25. }



最后,在主循环调用定时器后台处理函数
  1. int main(void)
  2. {
  3.     u8 i = 0;
  4.     BOARD_Init();
  5.     Systick_init();
  6.     MultiTimerInstall(PlatformTicksGetFunc);
  7.     MultiTimerStart(&timer1, 5, KeyTimer1Callback, NULL);
  8.     MultiTimerStart(&timer2, 10, LEDTimer2Callback, NULL);
  9.     while (1)
  10.     {
  11.                 MultiTimerYield();
  12.     }
  13. }








cemaj 发表于 2022-12-6 13:24 | 显示全部楼层
Systick的功能确实强大很多。
lihuami 发表于 2022-12-6 17:26 | 显示全部楼层
Systick基准时钟的代表              
yeates333 发表于 2022-12-6 17:47 | 显示全部楼层
可以做延时函数的。              
sanfuzi 发表于 2022-12-12 11:51 | 显示全部楼层
还是使用定时器比较好一些。              
robertesth 发表于 2022-12-12 13:41 | 显示全部楼层
MM32L0136C7P的systick如何作为驱动时钟?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

165

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部