你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【NUCLEO-L496ZG评测】第二部 : 基于LL库 ,进行GPIO 电平翻转测试

[复制链接]
harvardx 提问时间:2017-5-18 16:40 /
本帖最后由 harvardx 于 2017-5-18 21:24 编辑

       第一篇,  已经熟悉了开发环境,熟悉了最新的cubemx.
STM32CubeL4 Firmware Package 已经
更新到V1.8.0/ 21-April-2017,增加了 对B-L475E-IOT01 物联网开发板的支持. 对于我们使用的L496,更新了CMSIS中的
  • stm32l496xx.h and stm32l4a6xx.h device description files
    • FIREWALL
      • Fix FW_VDSSA_ADD_Msk and FW_VDSL_LENG_Msk definitions
    • TIM16
      • Fix TIM16_OR1_TI1_RMP_Msk definitio
      •         
     本篇,我们将利用LL库,实现同样的功能,这次我们的控制对象改为LD1, 我们要完成LD1的闪烁功能.
     上篇,我们是直接去写端口,延时,然后再写不同电平,延时, 然后循环的思路来实现.本篇采用不同的手段实现, 直接采用d端口的toggle功能来实现. 实际上就是把当前的端口值在和1异或一下.      具体的实现在stm32L4xx_II_gpio.h
  1. __STATIC_INLINE void LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
  2. {
  3.   WRITE_REG(GPIOx->ODR, READ_REG(GPIOx->ODR) ^ PinMask);
  4. }
复制代码

     LL库的整个体系结构清晰, 效率高, 在库函数和直接寄存器操作中间找到一个合适的切入点. 对效率要求高的应用,可以 试试看LL库.
     主要程序摘录如下: 按照250ms的周期间隔, 不断的反转LD1所在的电平.


  1. /**
  2.   ******************************************************************************
  3.   * @file    Examples_LL/GPIO/GPIO_InfiniteLedToggling/Src/main.c
  4.   * @author  MCD Application Team
  5.   * @version V1.8.0
  6.   * @date    21-April-2017
  7.   * @brief   This example describes how to configure and use GPIOs through
  8.   *          the STM32L4xx  GPIO LL API.
  9.   *          Peripheral initialization done using LL unitary services functions.
  10.   ******************************************************************************
  11.   * @attention
  12.   *
  13.   * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  14.   *
  15.   * Redistribution and use in source and binary forms, with or without modification,
  16.   * are permitted provided that the following conditions are met:
  17.   *   1. Redistributions of source code must retain the above copyright notice,
  18.   *      this list of conditions and the following disclaimer.
  19.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  20.   *      this list of conditions and the following disclaimer in the documentation
  21.   *      and/or other materials provided with the distribution.
  22.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  23.   *      may be used to endorse or promote products derived from this software
  24.   *      without specific prior written permission.
  25.   *
  26.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  30.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  32.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  33.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  34.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36.   *
  37.   ******************************************************************************
  38.   */

  39. /* Includes ------------------------------------------------------------------*/
  40. #include "main.h"

  41. /** @addtogroup STM32L4xx_LL_Examples
  42.   * @{
  43.   */

  44. /** @addtogroup GPIO_InfiniteLedToggling
  45.   * @{
  46.   */

  47. /* Private typedef -----------------------------------------------------------*/
  48. /* Private define ------------------------------------------------------------*/
  49. /* Private macro -------------------------------------------------------------*/
  50. /* Private variables ---------------------------------------------------------*/
  51. /* Private function prototypes -----------------------------------------------*/
  52. void     SystemClock_Config(void);
  53. void     Configure_GPIO(void);


  54. /* Private functions ---------------------------------------------------------*/

  55. /**
  56.   * @brief  Main program
  57.   * @param  None
  58.   * @retval None
  59.   */
  60. int main(void)
  61. {
  62.   /* Configure the system clock to 40 MHz */
  63.   SystemClock_Config();
  64.   
  65.   /* -2- Configure IO in output push-pull mode to drive external LED */
  66.   Configure_GPIO();

  67.   /* Toggle IO in an infinite loop */
  68.   while (1)
  69.   {
  70.     LL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_PIN);
  71.    
  72.     /* Insert delay 250 ms */
  73.     LL_mDelay(250);
  74.   }
  75. }

  76. /**
  77.   * @brief  This function configures GPIO
  78.   * @note   Peripheral configuration is minimal configuration from reset values.
  79.   *         Thus, some useless LL unitary functions calls below are provided as
  80.   *         commented examples - setting is default configuration from reset.
  81.   * @param  None
  82.   * @retval None
  83.   */
  84. void Configure_GPIO(void)
  85. {
  86.   /* Enable the LED1 Clock */
  87.   LED1_GPIO_CLK_ENABLE();

  88.   /* Configure IO in output push-pull mode to drive external LED1 */
  89.   LL_GPIO_SetPinMode(LED1_GPIO_PORT, LED1_PIN, LL_GPIO_MODE_OUTPUT);
  90.   /* Reset value is LL_GPIO_OUTPUT_PUSHPULL */
  91.   //LL_GPIO_SetPinOutputType(LED1_GPIO_PORT, LED1_PIN, LL_GPIO_OUTPUT_PUSHPULL);
  92.   /* Reset value is LL_GPIO_SPEED_FREQ_LOW */
  93.   //LL_GPIO_SetPinSpeed(LED1_GPIO_PORT, LED1_PIN, LL_GPIO_SPEED_FREQ_LOW);
  94.   /* Reset value is LL_GPIO_PULL_NO */
  95.   //LL_GPIO_SetPinPull(LED1_GPIO_PORT, LED1_PIN, LL_GPIO_PULL_NO);
  96. }

  97. /**
  98.   * @brief  System Clock Configuration
  99.   *         The system Clock is configured as follows :
  100.   *            System Clock source            = PLL (MSI)
  101.   *            SYSCLK(Hz)                     = 40000000
  102.   *            HCLK(Hz)                       = 40000000
  103.   *            AHB Prescaler                  = 1
  104.   *            APB1 Prescaler                 = 1
  105.   *            APB2 Prescaler                 = 1
  106.   *            MSI Frequency(Hz)              = 4000000
  107.   *            PLL_M                          = 1
  108.   *            PLL_N                          = 40
  109.   *            PLL_R                          = 2
  110.   *            Flash Latency(WS)              = 4
  111.   * @param  None
  112.   * @retval None
  113.   */
  114. void SystemClock_Config(void)
  115. {
  116.   /* MSI configuration and activation */
  117.   LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
  118.   LL_RCC_MSI_Enable();
  119.   while(LL_RCC_MSI_IsReady() != 1)
  120.   {
  121.   };
  122.   
  123.   /* Main PLL configuration and activation */
  124.   LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2);
  125.   LL_RCC_PLL_Enable();
  126.   LL_RCC_PLL_EnableDomain_SYS();
  127.   while(LL_RCC_PLL_IsReady() != 1)
  128.   {
  129.   };
  130.   
  131.   /* Sysclk activation on the main PLL */
  132.   LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  133.   LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  134.   while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  135.   {
  136.   };
  137.   
  138.   /* Set APB1 & APB2 prescaler*/
  139.   LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
  140.   LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);

  141.   /* Set systick to 1ms in using frequency set to 80MHz */
  142.   /* This frequency can be calculated through LL RCC macro */
  143.   /* ex: __LL_RCC_CALC_PLLCLK_FREQ(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, LL_RCC_MSIRANGE_6),
  144.                                   LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2)*/
  145.   LL_Init1msTick(40000000);
  146.   
  147.   /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
  148.   LL_SetSystemCoreClock(40000000);
  149. }

  150. #ifdef  USE_FULL_ASSERT

  151. /**
  152.   * @brief  Reports the name of the source file and the source line number
  153.   *         where the assert_param error has occurred.
  154.   * @param  file: pointer to the source file name
  155.   * @param  line: assert_param error line source number
  156.   * @retval None
  157.   */
  158. void assert_failed(char *file, uint32_t line)
  159. {
  160.   /* User can add his own implementation to report the file name and line number,
  161.      ex: printf("Wrong parameters value: file %s on line %d", file, line) */

  162.   /* Infinite loop */
  163.   while (1)
  164.   {
  165.   }
  166. }
  167. #endif

  168. /**
  169.   * @}
  170.   */

  171. /**
  172.   * @}
  173.   */

  174. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码




    由上看出, st的库描述,抽象,非常到位. 整个单片机要运作, 2大基础要做好. 各个内部模块都是时钟驱动的,所有第一要务要做好时钟配置.于是就有了函数:


                              void SystemClock_Config(void)

    这样,各个模块就可以有了生命之源,可以有条不紊的开动起来. 单片机运行,需要和外部打交道.IO口的配置就必须了. 那么再来个功能函数:
                             void Configure_GPIO(void);

    剩下的就是用户的事情了, 一般的单片机就是个前后台系统, 一个大的while1 搞定.不断的查询,计算,读取,处理. 构成用户的APP.  
    纵观整个,LL库写出的IO口点灯的基本程序, 结构清晰,功能明确, 函数和变量都命名规范. 可以非常容易的上手这款最新的L496单片机.
T4L3{_$WB_Q77B%ETT$%]GU.png GPIO_InfiniteLedToggling.zip (1.17 MB, 下载次数: 21)
收藏 1 评论4 发布时间:2017-5-18 16:40

举报

4个回答
黑溱郎 回答时间:2017-6-27 10:24:29
谢谢楼主分享。
harvardx 回答时间:2017-6-29 10:35:05
afonyang 回答时间:2018-4-4 14:55:40
好,解决了一个入门问题,LL_mDelay
stm8s003 回答时间:2018-4-20 23:21:03
好!不仅将了过程,而且有一定的经验总结,这个很好。看资料最怕没有总结的。

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版