1, Get source code
It's faster to get the source code directly from Baidu online disk. Extraction code: 1234
Link: https://pan.baidu.com/s/10RqsDRecbmVteWmDv2oUNQ.
2, Build project
Open stm32subemx to create a new project and select STM32F103C8T6 chip
Configure the chip
Set PC13 to GPIO_Output is used to light the LED lamp to judge whether the transplantation is successful
Continue configuring the chip
Select the name and path of the generated file
In this way, the project file is generated
3, Preparation before transplantation
1. Create bsp.c and bsp.h files for UC BSP folder
2. Add the following files to the folder UC config
3. Copy the uCOS related files to the MDK-ARM folder of the HAL project just generated
4, Start migration
Open the project file and click Manage Project Items
Create a new file for the project and add the previous uc files in turn
The following folders are also added with files in turn as above
Import file path
5, Add code
bsp.h file
#ifndef __BSP_H__ #define __BSP_H__ #include "stm32f1xx_hal.h" void BSP_Init(void); #endif
bsp.c file
#include "includes.h" #define DWT_CR *(CPU_REG32 *)0xE0001000 #define DWT_CYCCNT *(CPU_REG32 *)0xE0001004 #define DEM_CR *(CPU_REG32 *)0xE000EDFC #define DBGMCU_CR *(CPU_REG32 *)0xE0042004 #define DEM_CR_TRCENA (1 << 24) #define DWT_CR_CYCCNTENA (1 << 0) CPU_INT32U BSP_CPU_ClkFreq (void) { return HAL_RCC_GetHCLKFreq(); } void BSP_Tick_Init(void) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; cpu_clk_freq = BSP_CPU_ClkFreq(); #if(OS_VERSION>=3000u) cnts = cpu_clk_freq/(CPU_INT32U)OSCfg_TickRate_Hz; #else cnts = cpu_clk_freq/(CPU_INT32U)OS_TICKS_PER_SEC; #endif OS_CPU_SysTickInit(cnts); } void BSP_Init(void) { BSP_Tick_Init(); MX_GPIO_Init(); } #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) void CPU_TS_TmrInit (void) { CPU_INT32U cpu_clk_freq_hz; DEM_CR |= (CPU_INT32U)DEM_CR_TRCENA; /* Enable Cortex-M3's DWT CYCCNT reg. */ DWT_CYCCNT = (CPU_INT32U)0u; DWT_CR |= (CPU_INT32U)DWT_CR_CYCCNTENA; cpu_clk_freq_hz = BSP_CPU_ClkFreq(); CPU_TS_TmrFreqSet(cpu_clk_freq_hz); } #endif #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) CPU_TS_TMR CPU_TS_TmrRd (void) { return ((CPU_TS_TMR)DWT_CYCCNT); } #endif #if (CPU_CFG_TS_32_EN == DEF_ENABLED) CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts) { CPU_INT64U ts_us; CPU_INT64U fclk_freq; fclk_freq = BSP_CPU_ClkFreq(); ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC); return (ts_us); } #endif #if (CPU_CFG_TS_64_EN == DEF_ENABLED) CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts) { CPU_INT64U ts_us; CPU_INT64U fclk_freq; fclk_freq = BSP_CPU_ClkFreq(); ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC); return (ts_us); } #endif
main function
/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "gpio.h" #include "usart.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <includes.h> /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* Task priority */ #define START_TASK_PRIO 3 #define LED0_TASK_PRIO 4 #define LED1_TASK_PRIO 5 #define FLOAT_TASK_PRIO 6 /* Task stack size */ #define START_STK_SIZE 256 #define LED0_STK_SIZE 128 #define LED1_STK_SIZE 128 #define FLOAT_STK_SIZE 128 /* Task stack */ CPU_STK START_TASK_STK[START_STK_SIZE]; CPU_STK LED0_TASK_STK[LED0_STK_SIZE]; CPU_STK LED1_TASK_STK[LED1_STK_SIZE]; /* Task control block */ OS_TCB StartTaskTCB; OS_TCB Led0TaskTCB; OS_TCB Led1TaskTCB; OS_TCB FloatTaskTCB; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Task function definition */ void start_task(void *p_arg); static void AppTaskCreate(void); static void AppObjCreate(void); static void led_pc13(void *p_arg); static void send_msg(void *p_arg); /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /** * @brief System Clock Configuration * @retval None */ 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.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(); } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { OS_ERR err; OSInit(&err); HAL_Init(); SystemClock_Config(); //MX_GPIO_Init(); This will also be initialized in BSP initialization MX_USART1_UART_Init(); /* Create task */ OSTaskCreate((OS_TCB *)&StartTaskTCB, /* Create the start task */ (CPU_CHAR *)"start task", (OS_TASK_PTR ) start_task, (void *) 0, (OS_PRIO ) START_TASK_PRIO, (CPU_STK *)&START_TASK_STK[0], (CPU_STK_SIZE) START_STK_SIZE/10, (CPU_STK_SIZE) 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); /* Start the multitasking system and give control to uC/OS-III */ OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ } void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; /* YangJie add 2021.05.20*/ BSP_Init(); /* Initialize BSP functions */ //CPU_Init(); //Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //Statistical tasks #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN // If enabled, measure the interrupt off time CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN // When using time slice rotation //Enable the time slice rotation scheduling function. The time slice length is 1 system clock beat, i.e. 1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //Enter critical zone /* Create LED0 task */ OSTaskCreate((OS_TCB * )&Led0TaskTCB, (CPU_CHAR * )"led_pc13", (OS_TASK_PTR )led_pc13, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )&LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_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); /* Create LED1 task */ OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led1 task", (OS_TASK_PTR )send_msg, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_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); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //Suspend start task OS_CRITICAL_EXIT(); //Enter critical zone } /** * Function function: start the task function body. * Input parameter: p_arg is the formal parameter passed when the task was created * Return value: None * Description: None */ static void led_pc13 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 0, 500,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 0, 500,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void send_msg (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); AppTaskCreate(); /* Create Application Tasks */ AppObjCreate(); /* Create Application Objects */ while (DEF_TRUE) { printf("hello world \r\n"); OSTimeDlyHMSM(0, 0, 0, 500,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /* USER CODE BEGIN 4 */ /** * Function function: create application task * Input parameter: p_arg is the formal parameter passed when the task was created * Return value: None * Description: None */ static void AppTaskCreate (void) { } /** * Function function: uCOSIII kernel object creation * Input parameters: None * Return value: None * Description: None */ static void AppObjCreate (void) { } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Add printf redirection function
startup_ Modification of stm32f103xb. S file
app_ Modification of CFG. H file
Modification of the includes.h file
lib_ Modification of CFG. H file
Set engineering data
Compilation succeeded
Experimental results:
6, Waveform observation
Create a. txt file in the MDK-ARM folder of the project, add the following contents, and modify the file suffix to ini
map 0x40000000, 0x40007FFF read write // APB1 map 0x40010000, 0x400157FF read write // APB2 map 0x40020000, 0x4007FFFF read write // AHB1 map 0x50000000, 0x50060BFF read write // AHB2 map 0x60000000, 0x60000FFF read write // AHB3 map 0xE0000000, 0xE00FFFFF read write // CORTEX-M4 internal peripherals
Add the uc.ini file to the projectClick on the pattern of the magnifying glass
Click setup to add the waveform to be observed (PORTC.13, PORTA.3, USART1_SR), change the Display Type of the three observation signals to Bit display, and configure the color for them. Finally, click Close
Simulation results:
Observe the waveform using the real logic instrument SaleaeLogic16
Baidu online disk download link, extraction code: bstv
Link: https://pan.baidu.com/s/1Zpg5V44uO_Ly907CdCtm5A.
After entering the start page, click the upper left corner to select Logic16
Set the channel and modify the trigger mode
LED signal waveform of PC13 pin
LED signal waveform of PA3 pin
The specific data output by USART1 serial port is shown in the figure below
Serial port setting diagram
During data transmission of serial communication protocol, each character is 10 bits (1 start bit, 7 data bits, 1 check bit and 1 end bit): Start bit - first send a logical "0" signal to indicate the beginning of the transmitted character; Data bits - can be 5~8 Bit logic "0" or "1"; Check bit - this bit is added to the data bit so that the number of bits of "1" should be even(Parity check)Or odd(Odd check); Stop bit - it is the end flag of a character data. Can be 1 bit, 1 bit.5 Bit, 2-bit high level; Idle bit - in logic "1" state, indicating that there is no data transmission on the current line. It can be seen from the waveform of the logic analyzer that each character is 10 bits, with a start bit of logic "0", 7 data bits, 1 parity bit, 1 high-level stop bit and 1 idle bit in logic "1". Data bits: 1101000, i.e. hexadecimal number 0 x68. The serial port waveform conforms to the data transmission format of serial port communication
summary
Through this experiment, I learned the embedded real-time operating system, successfully transplanted the uC/OS-III system to stm32F103, constructed and completed three experimental task s, deeply mastered keil's simulation and debugging code function, and also learned to use the real logic instrument to troubleshoot and test the code operation. Observe the pin waveform through keil simulation oscilloscope and logic analyzer. The waveform is basically consistent with the requirements set in the actual code. When adding files, be careful and pay attention to the path of the file.