分享到:
1.找到ucosIII的源码,这里我找到的是野火提供的官方的基于Eval-STM32F107的源码。
2.MDK新建工程,添加ucosIII的.c和.h文件,这些就不必说了,是通用的做法。
3.修改启动文件,把原来的PendSV_Handler函数和SysTick_Handler函数替代为OS_CPU_PendSVHandler和OS_CPU_SysTickHandler,总共有三个地方需要修改。
4.在stm32f1xx_it.c中把PendSV_Handler和SysTick_Handler函数屏蔽掉。.h中的声明也屏蔽掉。
5.在stm32f1xx_hal_msp.c中增加CPU_TS_TmrInit和CPU_TS_TmrRd的定义
/**
* @brief Timestamp initialization function
* @param None
* @retval None
*/
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void CPU_TS_TmrInit (void)
{
}
#endif
/**
* @brief Read timestamp function
* @param None
* @retval None
*/
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR CPU_TS_TmrRd (void)
{
return (SysTick->VAL);
}
#endif
6.在系统的时钟初始化中配置systick的时钟源和嘀嗒时间。以及设置中断的优先级层数。
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_HSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL_NONE;
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();
}
/** Configure the Systick interrupt time
*/
// __HAL_RCC_PLLI2S_ENABLE();
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
7.配置只有一个任务ucos系统,使ucos运行起来,闪烁一个led。定义一个任务的三要素,任务栈,任务控制块,任务主题函数即可。
int main(void)
{
OS_ERR err;
BSP_Init();
CPU_Init();
OSInit(&err);
while (1)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);
// USART1_SendByte(0xAA);
delay_ms(1000);
// printf("** Test finished successfully. ** \r\n");
// Key_Out(0x00);
}
// OSTaskCreate((OS_TCB *)&MyTaskTCB,
// (CPU_CHAR *)"MyTask",
// (OS_TASK_PTR)&MyTask,
// (void *)0,
// (OS_PRIO) APP_TASK_START_PRIO,
// (CPU_STK *)&MyTaskStk[0],
// (CPU_STK_SIZE)APP_TASK_START_STK_SIZE / 10,
// (CPU_STK_SIZE)APP_TASK_START_STK_SIZE,
// (OS_MSG_QTY)0,
// (OS_TICK)0,
// (void *)0,
// (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
// (OS_ERR *)&err);
//
// OSStart(&err);
/* Infinite loop */
while (1)
{
}
}
8.着重要注意的是,我们需要测试单独外设功能的时候,需要先初始化ucos,在创建任务之前加入原来的while循环函数即可,不然原来的函数会无法运行的。
int main(void)
{
OS_ERR err;
BSP_Init();
CPU_Init();
OSInit(&err);
while (1)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);
// USART1_SendByte(0xAA);
delay_ms(1000);
// printf("** Test finished successfully. ** \r\n");
// Key_Out(0x00);
}
// OSTaskCreate((OS_TCB *)&MyTaskTCB,
// (CPU_CHAR *)"MyTask",
// (OS_TASK_PTR)&MyTask,
// (void *)0,
// (OS_PRIO) APP_TASK_START_PRIO,
// (CPU_STK *)&MyTaskStk[0],
// (CPU_STK_SIZE)APP_TASK_START_STK_SIZE / 10,
// (CPU_STK_SIZE)APP_TASK_START_STK_SIZE,
// (OS_MSG_QTY)0,
// (OS_TICK)0,
// (void *)0,
// (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
// (OS_ERR *)&err);
//
// OSStart(&err);
/* Infinite loop */
while (1)
{
}
}
(0 )
(0 )
回复
举报
- 0000000000000000
-
1888 发帖7917 回复34980 积分
- 私信他 +关注
回复于 2020-02-18 3#
感谢分享,欢迎关注我,资料持续更新中。有需要机械臂,电源,硬件电路设计,软件编程,开发板等各种定制的可以私聊我哦,相互学习,共同进步。
(0 )
发表回复
块
导
航
举报
请选择举报类别
- 广告垃圾
- 违规内容
- 恶意灌水
- 重复发帖