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

【STM32MP1板卡试用】+裸机环境下调试M4内核程序

[复制链接]
胤幻1988 发布时间:2021-6-7 14:54
通过上篇文章对STM32MP1双核机制的分析。我们知道M4内核的程序,不能够下载到FLASH当中。那怎么调试M4的程序呢。下面我们就开始讲一讲。
STM32MP1跟普通M4核MCU开发没有太大的区别,一样调用HAL库,一样可以通过CUBEMX工具生成
初始化代码。当然在能控制的外设方面比真正的M4单片机要少一些,上文已描述过。我们在这里就不多说了。
我们打开CUBEMX工具,选择对应型号,配置工程:
我们想控制板上一颗LED,并且串口能够收发数据。
LED引脚电路位置:
Z1.png
与STLINK相连的调试串口UART4电路位置:

z2.png
Z3.png
Z4.png
CUBEMX配置:

Z7.png
Z8.png
配置时钟:
Z9.png
Z11.png

工程配置时,选择让每一个外设生成独立文件:
Z13.png
然后生成代码,我们这里没有官方的STM32CUBEIDE开发,用MDK。
生成的代码,我们不直接用,仅作为参考。
修改自己的led程序:
C:
  1. void led_init(void)
  2. {
  3.     GPIO_InitTypeDef gpio_init_struct;
  4.     LED0_GPIO_CLK_ENABLE(); /* LED0时钟使能 */


  5.     gpio_init_struct.Pin = LED0_GPIO_PIN;                   /* LED0引脚 */
  6.     gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
  7.     gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
  8.     gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速 */
  9.     HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_init_struct);       /* 初始化LED0引脚 */


  10.     LED0(0);    /* 关闭 LED0 */

  11. }
复制代码
H:
  1. #define LED0_GPIO_PORT                  GPIOE
  2. #define LED0_GPIO_PIN                   GPIO_PIN_12
  3. #define LED0_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

  4. /******************************************************************************************/


  5. /* LED端口定义 */
  6. #define LED0(x)   do{ x ? \
  7.                       HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
  8.                       HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
  9.                   }while(0)       /* LED0 = RED */

  10. /* LED取反定义 */
  11. #define LED0_TOGGLE()    do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0)   /* LED0 = !LED0 */


  12. #define LED0_STATION     HAL_GPIO_ReadPin(LED0_GPIO_PORT, LED0_GPIO_PIN)

  13. void led_init(void);    /* 初始化 */
复制代码
UART4.C
主要处理都在接收回传函数里面,此接收函数一直参考正点原子。
  1. * 接收缓冲, 最大USART_REC_LEN个字节. */
  2. uint8_t g_usart_rx_buf[USART_REC_LEN];

  3. /*  接收状态
  4. *  bit15,      接收完成标志
  5. *  bit14,      接收到0x0d
  6. *  bit13~0,    接收到的有效字节数目
  7. */
  8. uint16_t g_usart_rx_sta = 0;

  9. uint8_t g_rx_buffer[RXBUFFERSIZE];    /* HAL库使用的串口接收缓冲 */

  10. UART_HandleTypeDef g_uart4_handle;    /* UART句柄 */


  11. /**
  12. * @brief       串口X初始化函数
  13. * @param       baudrate: 波特率, 根据自己需要设置波特率值
  14. * @note        注意: 必须设置正确的时钟源, 否则串口波特率就会设置异常.
  15. *              这里的USART的时钟源在sys_stm32_clock_init()函数中已经设置过了.
  16. * @retval      无
  17. */
  18. void usart_init(uint32_t baudrate)
  19. {
  20.     g_uart4_handle.Instance = USART_UX;                    /* USART4 */
  21.     g_uart4_handle.Init.BaudRate = baudrate;               /* 波特率 */
  22.     g_uart4_handle.Init.WordLength = UART_WORDLENGTH_8B;   /* 字长为8位数据格式 */
  23.     g_uart4_handle.Init.StopBits = UART_STOPBITS_1;        /* 一个停止位 */
  24.     g_uart4_handle.Init.Parity = UART_PARITY_NONE;         /* 无奇偶校验位 */
  25.     g_uart4_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;   /* 无硬件流控 */
  26.     g_uart4_handle.Init.Mode = UART_MODE_TX_RX;            /* 收发模式 */
  27.     HAL_UART_Init(&g_uart4_handle);                        /* HAL_UART_Init()会使能UART4 */
  28.    
  29.     /* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */
  30.     HAL_UART_Receive_IT(&g_uart4_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
  31. }

  32. /**
  33. * @brief       UART底层初始化函数
  34. * @param       huart: UART句柄类型指针
  35. * @note        此函数会被HAL_UART_Init()调用
  36. *              完成时钟使能,引脚配置,中断配置
  37. * @retval      无
  38. */
  39. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  40. {
  41.     GPIO_InitTypeDef gpio_init_struct;
  42.         RCC_PeriphCLKInitTypeDef rcc_periphclk_init_struct;
  43.         
  44.     if(huart->Instance == UART4)                                   /* 如果是串口4,进行串口4 MSP初始化 */
  45.     {
  46.         USART_UX_CLK_ENABLE();                                      /* USART4时钟使能 */
  47.         USART_TX_GPIO_CLK_ENABLE();                                 /* 发送引脚时钟使能 */
  48.         USART_RX_GPIO_CLK_ENABLE();                                 /* 接收引脚时钟使能 */

  49.         gpio_init_struct.Pin = USART_TX_GPIO_PIN;                   /* 指定TX引脚 */
  50.         gpio_init_struct.Mode = GPIO_MODE_AF_PP;                    /* 复用推挽输出 */
  51.         gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
  52.         gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
  53.         gpio_init_struct.Alternate = USART_TX_GPIO_AF;              /* 复用为UART4 */
  54.         HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct);       /* 初始化发送引脚 */

  55.         gpio_init_struct.Pin = USART_RX_GPIO_PIN;                   /* 指定RX引脚 */
  56.         gpio_init_struct.Alternate = USART_RX_GPIO_AF;              /* 复用为UART4 */
  57.         HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct);       /* 初始化接收引脚 */
  58.                
  59.                 /* 设置UART4时钟源=PLL4Q=74.25MHz  */
  60.                 rcc_periphclk_init_struct.Uart24ClockSelection = RCC_UART24CLKSOURCE_PLL4;
  61.                 HAL_RCCEx_PeriphCLKConfig(&rcc_periphclk_init_struct);

  62. #if USART_EN_RX
  63.         HAL_NVIC_EnableIRQ(USART_UX_IRQn);                          /* 使能USART4中断通道 */
  64.         HAL_NVIC_SetPriority(USART_UX_IRQn, 3, 3);                  /* 抢占优先级3,子优先级3 */
  65. #endif
  66.     }
  67. }

  68. /**
  69. * @brief       Rx传输回调函数
  70. * @param       huart: UART4句柄类型指针
  71. * @retval      无
  72. */
  73. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  74. {
  75.     if(huart->Instance == UART4)                              /* 如果是串口4 */
  76.     {
  77.         if((g_usart_rx_sta & 0x8000) == 0)                    /* 接收未完成 */
  78.         {
  79.             if(g_usart_rx_sta & 0x4000)                       /* 接收到了0x0d */
  80.             {
  81.                 if(g_rx_buffer[0] != 0x0a)
  82.                 {
  83.                     g_usart_rx_sta = 0;                       /* 接收错误,重新开始 */
  84.                 }
  85.                 else
  86.                 {
  87.                     g_usart_rx_sta |= 0x8000;                 /* 接收完成了 */
  88.                 }
  89.             }
  90.             else                                              /* 还没收到0X0D */
  91.             {
  92.                 if(g_rx_buffer[0] == 0x0d)
  93.                 {
  94.                     g_usart_rx_sta |= 0x4000;
  95.                 }
  96.                 else
  97.                 {
  98.                     g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = g_rx_buffer[0] ;
  99.                     g_usart_rx_sta++;
  100.                     if(g_usart_rx_sta > (USART_REC_LEN - 1))
  101.                     {
  102.                         g_usart_rx_sta = 0;                   /* 接收数据错误,重新开始接收 */
  103.                     }
  104.                 }
  105.             }
  106.         }
  107.     }
  108. }

  109. /**
  110. * @brief       串口4中断服务函数
  111. * @param       无
  112. * @retval      无
  113. */
  114. void USART_UX_IRQHandler(void)
  115. {
  116.     uint32_t timeout = 0;
  117.     uint32_t maxDelay = 0x1FFFF;

  118.     HAL_UART_IRQHandler(&g_uart4_handle); /* 调用HAL库中断处理公用函数 */

  119.     timeout = 0;
  120.     while (HAL_UART_GetState(&g_uart4_handle) != HAL_UART_STATE_READY) /* 等待就绪 */
  121.     {
  122.         timeout++;                       /* 超时处理 */
  123.         if(timeout > maxDelay)
  124.         {
  125.             break;
  126.         }
  127.     }
  128.      
  129.     timeout=0;
  130.    
  131.     /* 一次处理完成之后,重新开启中断并设置RxXferCount为1 */
  132.     while (HAL_UART_Receive_IT(&g_uart4_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)
  133.     {
  134.         timeout++;                  /* 超时处理 */
  135.         if (timeout > maxDelay)
  136.         {
  137.             break;
  138.         }
  139.     }

  140. }
复制代码
main函数调用:
  1. if (g_usart_rx_sta & 0x8000)        /* 接收到了数据 */
  2.                 {
  3.                                 len = g_usart_rx_sta & 0x3fff;  /* 得到此次接收到的数据长度 */
  4.                         printf("\r\nYou send message is: \r\n");
  5.                                 for (t = 0; t < len; t++)
  6.                                 {
  7.                                                 USART_UX->TDR = g_usart_rx_buf[t];
  8.                                                 while ((USART_UX->ISR & 0X40) == 0);  /* 等待发送结束 */
  9.                                 }
  10.                                 printf("\r\n\r\n"); /* 插入换行 */
  11.                                 g_usart_rx_sta = 0;
  12.                 }
  13.                 else
  14.                 {
  15.                                 times++;
  16.                                 if (times % 5000 == 0)
  17.                                 {
  18.                                                 printf("\r\nSTM32MP1_DK1 UART4 TEST!\r\n");
  19.                                                 printf("JasonQiu@ST community \r\n\r\n\r\n");
  20.                                 }
  21.                                 if (times % 200 == 0) printf("Please putchar!\r\n");
  22.                                 if (times % 30  == 0)
  23.                                 {
  24.                                         LED0_TOGGLE();
  25.                                         printf("The led station is %d \r\n\r\n\r\n",LED0_STATION);
  26.                                 }
  27.                                 delay(10);
  28.                 }
复制代码
编译无误后,此时我们需要修改MCU的BOOT MODE :
我们选择从内部RAM启动的模式:
AAAA3.png
ZZ2.png

MDK中,有几次配置要注意:

TT1.png
ZZ3.png
ZZ5.png
ZZ7.png

下载后直接运行,看下输出的状态:
SSS1.png
板子LED状态:
f34 (1).gif
好了,M4核的裸机开发就到这了。
收藏 评论0 发布时间:2021-6-7 14:54

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版