关于自己做的板子使用rt-thread无法启动问题

自己做的板子(用的是f103zet6),使用rt-thread框架的程序,验证了可以在stm32f103zet6的战舰开发板上运行(LED闪烁,msh可用),然后烧录到自己做的板子,没有进入主程序(LED未闪烁),且msh未打印。

然后,下载了标准库的串口实验例程,在开发板和自己做的板子上均能正常运行。
既然程序能运行,那么就拍出了硬件问题,那就理解代码吧。

进入debug模式,运行rtthread_startup程序:

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();

    /* board level initialization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();

    /* show RT-Thread version */
    rt_show_version();

    /* timer system initialization */
    rt_system_timer_init();

    /* scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* create init_thread */
    rt_application_init();

    /* timer thread initialization */
    rt_system_timer_thread_init();

    /* idle thread initialization */
    rt_thread_idle_init();

#ifdef RT_USING_SMP
    rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/

    /* start scheduler */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}

代码死在rt_hw_board_init里面。

RT_WEAK void rt_hw_board_init()
{
#ifdef SCB_EnableICache
    /* Enable I-Cache---------------------------------------------------------*/
    SCB_EnableICache();
#endif

#ifdef SCB_EnableDCache
    /* Enable D-Cache---------------------------------------------------------*/
    SCB_EnableDCache();
#endif

    /* HAL_Init() function is called at the beginning of the program */
    HAL_Init();

    /* System clock initialization */
    SystemClock_Config();
    rt_hw_systick_init();

    /* Heap initialization */
#if defined(RT_USING_HEAP)
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif

    /* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
    rt_hw_pin_init();
#endif

    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
    rt_hw_usart_init();
#endif

    /* Set the shell console output device */
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

    /* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif
}

代码死在SystemClock_Config里。


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
                              |RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

代码死在 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK),说明是时钟初始化问题。
网上搜索得到的一些解决方案:

1、硬件上别接错了,使用OSC_IN脚; 2、注意HSEBYP的写操作前,要关闭HSE; 3、你可以使用STM32CUBEMX配置下相关代码比对下;

问题解决了, RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE; 去掉RCC_OSCILLATORTYPE_HSI这个就可以了,我也是看到别人遇到同样的问题这样解决了,试了下,程序运行了,可能新的CubeMX真有这个BUG
实际上这里我们仔细研究一下代码,基于bsp的时钟配置中,我们使能了LSI、HSE、LSE,而实际上在我们的电路板上,只设计了8MHz的外部晶振,没有使用外部32.768k的晶振,而开发板是有的,固件库的时钟配置也不会去主动配置外部晶振的时钟,所以这里会配置失败,修改如下即可正常运行:


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
                              /*| RCC_OSCILLATORTYPE_LSE*/;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  /*RCC_OscInitStruct.LSEState = RCC_LSE_ON;*/
  /*RCC_OscInitStruct.HSIState = RCC_HSI_ON;*/
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

以下是两个STM32板子进行串口通信使用RT-Thread邮箱的例子: 首先,需要在两个板子上分别配置好串口和RT-Thread,然后在发送数据的板子上创建一个邮箱: ```c #include <rtthread.h> #define MAILBOX_NAME "mailbox1" #define MAILBOX_SIZE 10 static struct rt_mailbox mailbox; void mailbox_sender_entry(void *parameter) { char message[20] = "Hello, RT-Thread!"; rt_uint32_t timeout = 50; while (1) { rt_err_t result = rt_mb_send(&mailbox, (rt_uint32_t)message, sizeof(message)); if (result != RT_EOK) { rt_kprintf("Failed to send message to mailbox: %d\n", result); } rt_thread_mdelay(timeout); } } int mailbox_sender_init(void) { rt_err_t result = rt_mb_init(&mailbox, MAILBOX_NAME, sizeof(char), MAILBOX_SIZE); if (result != RT_EOK) { rt_kprintf("Failed to initialize mailbox: %d\n", result); return -1; } rt_thread_t thread = rt_thread_create("mailbox_sender", mailbox_sender_entry, RT_NULL, 1024, 25, 10); if (thread != RT_NULL) { rt_thread_startup(thread); } else { rt_kprintf("Failed to create mailbox_sender thread\n"); return -1; } return 0; } ``` 然后,在接收数据的板子上创建一个邮箱接收数据: ```c #include <rtthread.h> #define MAILBOX_NAME "mailbox1" #define MAILBOX_SIZE 10 static struct rt_mailbox mailbox; void mailbox_receiver_entry(void *parameter) { while (1) { char message[20]; rt_err_t result = rt_mb_recv(&mailbox, (rt_uint32_t *)&message, RT_WAITING_FOREVER); if (result == RT_EOK) { rt_kprintf("Received message from mailbox: %s\n", message); } else { rt_kprintf("Failed to receive message from mailbox: %d\n", result); } } } int mailbox_receiver_init(void) { rt_err_t result = rt_mb_init(&mailbox, MAILBOX_NAME, sizeof(char), MAILBOX_SIZE); if (result != RT_EOK) { rt_kprintf("Failed to initialize mailbox: %d\n", result); return -1; } rt_thread_t thread = rt_thread_create("mailbox_receiver", mailbox_receiver_entry, RT_NULL, 1024, 25, 10); if (thread != RT_NULL) { rt_thread_startup(thread); } else { rt_kprintf("Failed to create mailbox_receiver thread\n"); return -1; } return 0; } ``` 最后,在两个板子上分别调用初始化函数即可: ```c int main(void) { rt_thread_mdelay(5000); if (mailbox_sender_init() != 0) { rt_kprintf("Failed to initialize mailbox_sender\n"); } if (mailbox_receiver_init() != 0) { rt_kprintf("Failed to initialize mailbox_receiver\n"); } return 0; } ``` 这样,就可以在两个板子之间实现串口通信了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值