cubeIDE配置正点原子f103精英板配置红外遥控实验(无LCD版)

发布时间:2026/7/11 10:52:17

cubeIDE配置正点原子f103精英板配置红外遥控实验(无LCD版) 默认时钟和电源已经配置好建议配个串口用于调试可去搜索配置教程一、前期准备1.查看开发板手册找到红外遥控的输入端口由图一可知精英开发板的红外输入端口是PB9图一2.在芯片上找到PB9端口查看对应的定时器及相应通道由图二可知红外遥控输入端口对应的是定时器4的通道4图二二、cubeIDE的配置1.配置定时器4模式1时钟源配置为内部时钟2PB9引脚配置为定时器4通道43定时器4通道4设置为输入捕获模式注意配置定时器4通道4时cubeIDE默认设置的引脚可能不是PB9所以建议先查手册查看红外遥控对应的引脚然后把定时器4的时钟源配置为内部时钟然后再去芯片上点PB9的时候才会出现TIM4_CH4选项2.GPIO的配置PB9配置为pull up3.定时器参数配置见下图4.使能定时器中断然后就可以生成代码了三、导入功能代码导入正点原子红外实验的remote.c和remote.h文件因为cubeIDE已经生成了定时器4的配置函数所以定时器4的相关初始化函数直接注释即可void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数我注释是因为我在配置系统时钟时cubeIDE自动生成了这个函数所以我将remote.c中的void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数里的内容直接复制到cubeIDE自动生成的void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)里面了remote.h里面的一些宏定义是可以删掉的但是我懒得改了remote.h#ifndef __REMOTE_H #define __REMOTE_H #include stdint.h /******************************************************************************************/ /* 红外输入引脚及定时器 定义 */ #define REMOTE_IN_GPIO_PORT GPIOB #define REMOTE_IN_GPIO_PIN GPIO_PIN_9 #define REMOTE_IN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */ #define REMOTE_IN_TIMX TIM4 #define REMOTE_IN_TIMX_IRQn TIM4_IRQn #define REMOTE_IN_TIMX_IRQHandler TIM4_IRQHandler #define REMOTE_IN_TIMX_CHY TIM_CHANNEL_4 /* 通道Y, 1 Y 2*/ #define REMOTE_IN_TIMX_CCRY REMOTE_IN_TIMX-CCR4 #define REMOTE_IN_TIMX_CHY_CLK_ENABLE() do{ __HAL_RCC_TIM4_CLK_ENABLE(); }while(0) /* TIMX 时钟使能 */ /******************************************************************************************/ #define RDATA HAL_GPIO_ReadPin(REMOTE_IN_GPIO_PORT, REMOTE_IN_GPIO_PIN) /* 红外数据输入脚 */ /* 红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的. * 我们选用的遥控器识别码为0 */ #define REMOTE_ID 0 extern uint8_t g_remote_cnt; /* 按键按下的次数 */ extern uint8_t g_remote_sta; void remote_init(void); /* 红外传感器接收头引脚初始化 */ uint8_t remote_scan(void); #endifremote.c#include stdint.h #include remote.h #include tim.h #include stm32f1xx_it.h extern TIM_HandleTypeDef htim4; //TIM_HandleTypeDef g_tim4_handle; /* 定时器4句柄 */ /** * brief 红外遥控初始化 * note 设置IO以及定时器的输入捕获 * param 无 * retval 无 */ //void remote_init(void) //{ // TIM_IC_InitTypeDef tim_ic_init_handle; // // g_tim4_handle.Instance REMOTE_IN_TIMX; /* 通用定时器4 */ // g_tim4_handle.Init.Prescaler (72-1); /* 预分频器,1M的计数频率,1us加1 */ // g_tim4_handle.Init.CounterMode TIM_COUNTERMODE_UP; /* 向上计数器 */ // g_tim4_handle.Init.Period 10000; /* 自动装载值 */ // g_tim4_handle.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; // HAL_TIM_IC_Init(g_tim4_handle); // // /* 初始化TIM4输入捕获参数 */ // tim_ic_init_handle.ICPolarity TIM_ICPOLARITY_RISING; /* 上升沿捕获 */ // tim_ic_init_handle.ICSelection TIM_ICSELECTION_DIRECTTI; /* 映射到TI4上 */ // tim_ic_init_handle.ICPrescaler TIM_ICPSC_DIV1; /* 配置输入分频不分频 */ // tim_ic_init_handle.ICFilter 0x03; /* IC1F0003 8个定时器时钟周期滤波 */ // HAL_TIM_IC_ConfigChannel(g_tim4_handle, tim_ic_init_handle, REMOTE_IN_TIMX_CHY);/* 配置TIM4通道4 */ // HAL_TIM_IC_Start_IT(g_tim4_handle, REMOTE_IN_TIMX_CHY); /* 开始捕获TIM的通道值 */ // __HAL_TIM_ENABLE_IT(g_tim4_handle, TIM_IT_UPDATE); /* 使能更新中断 */ //} // ///** // * brief 定时器4底层驱动时钟使能引脚配置 // * param htim:定时器句柄 // * note 此函数会被HAL_TIM_IC_Init()调用 // * retval 无 // */ //void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) //{ // if(htim-Instance REMOTE_IN_TIMX) // { // GPIO_InitTypeDef gpio_init_struct; // // REMOTE_IN_GPIO_CLK_ENABLE(); /* 红外接入引脚GPIO时钟使能 */ // REMOTE_IN_TIMX_CHY_CLK_ENABLE(); /* 定时器时钟使能 */ // __HAL_AFIO_REMAP_TIM4_DISABLE(); /* 这里用的是PB9/TIM4_CH4参考AFIO_MAPR寄存器的设置 */ // // gpio_init_struct.Pin REMOTE_IN_GPIO_PIN; // gpio_init_struct.Mode GPIO_MODE_AF_INPUT; /* 复用输入 */ // gpio_init_struct.Pull GPIO_PULLUP; /* 上拉 */ // gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH; /* 高速 */ // HAL_GPIO_Init(REMOTE_IN_GPIO_PORT, gpio_init_struct); /* 初始化定时器通道引脚 */ // // HAL_NVIC_SetPriority(REMOTE_IN_TIMX_IRQn, 1, 3); /* 设置中断优先级抢占优先级1子优先级3 */ // HAL_NVIC_EnableIRQ(REMOTE_IN_TIMX_IRQn); /* 开启ITM4中断 */ // } // //} /* 遥控器接收状态 * [7] : 收到了引导码标志 * [6] : 得到了一个按键的所有信息 * [5] : 保留 * [4] : 标记上升沿是否已经被捕获 * [3:0]: 溢出计时器 */ uint8_t g_remote_sta 0; uint32_t g_remote_data 0; /* 红外接收到的数据 */ uint8_t g_remote_cnt 0; /* 按键按下的次数 */ /** * brief 定时器中断服务函数 * param 无 * retval 无 */ //void REMOTE_IN_TIMX_IRQHandler(void) //{ // HAL_TIM_IRQHandler(htim4); /* 定时器共用处理函数 */ //} /** * brief 定时器更新中断回调函数 * param htim:定时器句柄 * retval 无 */ //void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //{ // if (htim-Instance REMOTE_IN_TIMX) // { // if (g_remote_sta 0x80) /* 上次有数据被接收到了 */ // { // g_remote_sta ~0X10; /* 取消上升沿已经被捕获标记 */ // // if ((g_remote_sta 0X0F) 0X00) // { // g_remote_sta | 1 6; /* 标记已经完成一次按键的键值信息采集 */ // } // // if ((g_remote_sta 0X0F) 14) // { // g_remote_sta; // } // else // { // g_remote_sta ~(1 7); /* 清空引导标识 */ // g_remote_sta 0XF0; /* 清空计数器 */ // } // } // } //} /** * brief 定时器输入捕获中断回调函数 * param htim:定时器句柄 * retval 无 */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim-Instance REMOTE_IN_TIMX) { uint16_t dval; /* 下降沿时计数器的值 */ if (RDATA) /* 上升沿捕获 */ { __HAL_TIM_SET_CAPTUREPOLARITY(htim4,REMOTE_IN_TIMX_CHY,TIM_INPUTCHANNELPOLARITY_FALLING);//CC4P1 设置为下降沿捕获 __HAL_TIM_SET_COUNTER(htim4, 0); /* 清空定时器值 */ g_remote_sta | 0X10; /* 标记上升沿已经被捕获 */ } else /* 下降沿捕获 */ { dvalHAL_TIM_ReadCapturedValue(htim4, REMOTE_IN_TIMX_CHY); /* 读取CCR4也可以清CC4IF标志位 */ __HAL_TIM_SET_CAPTUREPOLARITY(htim4, REMOTE_IN_TIMX_CHY, TIM_INPUTCHANNELPOLARITY_RISING);/* 配置TIM4通道4上升沿捕获 */ if (g_remote_sta 0X10) /* 完成一次高电平捕获 */ { if (g_remote_sta 0X80) /* 接收到了引导码 */ { if (dval 300 dval 800) /* 560为标准值,560us */ { g_remote_data 1; /* 右移一位 */ g_remote_data ~(0x80000000); /* 接收到0 */ } else if (dval 1400 dval 1800) /* 1680为标准值,1680us */ { g_remote_data 1; /* 右移一位 */ g_remote_data | 0x80000000; /* 接收到1 */ } else if (dval 2000 dval 3000) /* 得到按键键值增加的信息 2500为标准值2.5ms */ { g_remote_cnt; /* 按键次数增加1次 */ g_remote_sta 0XF0; /* 清空计时器 */ } } else if (dval 4200 dval 4700) /* 4500为标准值4.5ms */ { g_remote_sta | 1 7; /* 标记成功接收到了引导码 */ g_remote_cnt 0; /* 清除按键次数计数器 */ } } g_remote_sta~(14); } } } /** * brief 处理红外按键(类似按键扫描) * param 无 * retval 0 , 没有任何按键按下 * 其他, 按下的按键键值 */ uint8_t remote_scan(void) { uint8_t sta 0; uint8_t t1, t2; if (g_remote_sta (1 6)) /* 得到一个按键的所有信息了 */ { t1 g_remote_data; /* 得到地址码 */ t2 (g_remote_data 8) 0xff; /* 得到地址反码 */ if ((t1 (uint8_t)~t2) t1 REMOTE_ID) /* 检验遥控识别码(ID)及地址 */ { t1 (g_remote_data 16) 0xff; t2 (g_remote_data 24) 0xff; if (t1 (uint8_t)~t2) { sta t1; /* 键值正确 */ } } if ((sta 0) || ((g_remote_sta 0X80) 0)) /* 按键数据错误/遥控已经没有按下了 */ { g_remote_sta ~(1 6); /* 清除接收到有效按键标识 */ g_remote_cnt 0; /* 清除按键次数计数器 */ } } // printf(sta : %d\n,sta); return sta; }因为我用的是freertos的多任务所以红外遥控的实现我放在了freertos的任务函数里面如果不用freertos的话可以直接放main函数里面main.c#include main.h #include cmsis_os.h #include can.h #include dma.h #include tim.h #include usart.h #include gpio.h /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include remote.h /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); void MX_FREERTOS_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * brief The application entry point. * retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_CAN_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_TIM4_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Init scheduler */ osKernelInitialize(); /* Call init function for freertos objects (in cmsis_os2.c) */ MX_FREERTOS_Init(); /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken by the scheduler */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * brief System Clock Configuration * retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ 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 buses 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 BEGIN 4 */ /* USER CODE END 4 */ /** * brief Period elapsed callback in non blocking mode * note This function is called when TIM7 interrupt took place, inside * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment * a global variable uwTick used as application time base. * param htim : TIM handle * retval None */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { /* USER CODE BEGIN Callback 0 */ /* USER CODE END Callback 0 */ if (htim-Instance TIM7) { HAL_IncTick(); } /* USER CODE BEGIN Callback 1 */ if (htim-Instance REMOTE_IN_TIMX) { if (g_remote_sta 0x80) /* 上次有数据被接收到了 */ { g_remote_sta ~0X10; /* 取消上升沿已经被捕获标记 */ if ((g_remote_sta 0X0F) 0X00) { g_remote_sta | 1 6; /* 标记已经完成?次按键的键?信息采? */ } if ((g_remote_sta 0X0F) 14) { g_remote_sta; } else { g_remote_sta ~(1 7); /* 清空引导标识 */ g_remote_sta 0XF0; /* 清空计数? */ } } } /* USER CODE END Callback 1 */ } /** * 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 */ __disable_irq(); while (1) { } /* 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, ex: printf(Wrong parameters value: file %s on line %d\r\n, file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */freertos.c任务代码我按自己的需要改动了一下/* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ Usart2_Init_Function(); HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); Zlmotor_Init(); uint8_t key; uint8_t flag 0; char *str 0; waypoint_cur.v 0; waypoint_cur.w 0; float n_left,n_right; float d0.4; float wheel_l0.42; /* Infinite loop */ for(;;) { Zlmotor_Data_Process(); // printf(22222222222\n); key remote_scan(); if(key 69) { flag 1; } if(flag) { Path_Data_Process(waypoint_path); WayPoint_Data_Process(waypoint_path,waypoint_cur); } if (key flag) { switch (key) { case 69: str START; break; case 70: str UP; waypoint_cur.v 0.2; printf(key waypoint_cur.v : %.2f\n,waypoint_cur.v); break; case 21: str DOWN; waypoint_cur.v -0.2; break; case 68: str LEFT; waypoint_cur.w 0.5; break; case 67: str RIGHT; waypoint_cur.w -0.5; break; // case 7: // str -; // waypoint_cur.v waypoint_cur.v - 0.05; // if(waypoint_cur.v 0)waypoint_cur.v 0; // // break; // case 9: // str ; // waypoint_cur.v waypoint_cur.v 0.05; // if(waypoint_cur.v 0.42)waypoint_cur.v 0.42; // break; case 64: str STOP; flag0; waypoint_cur.v 0; waypoint_cur.w 0; break; default: printf(key error\n); break; } } printf(key_end waypoint_cur.v : %.2f\n,waypoint_cur.v); // printf(waypoint_cur.v: %d\n,waypoint_cur.v); n_leftwaypoint_cur.v*60/(3.14159*d)-0.5*waypoint_cur.w*60*wheel_l/(3.14159*d); n_rightwaypoint_cur.v*60/(3.14159*d)0.5*waypoint_cur.w*60*wheel_l/(3.14159*d); Zlmotor_Set_Spdmode_Spd(zlmotor_left,n_left); Zlmotor_Set_Spdmode_Spd(zlmotor_right,n_right); osDelay(10); } // printf(v: w: %.2f %.2f\n,waypoint_cur.v,waypoint_cur.w); /* USER CODE END StartDefaultTask */ }

相关新闻