由于自己设计要用,所以从网上找了一套相对比较完整的资料,现在分享给大家,内容十分详细包括说明书、软件、代码、原理图一应俱全,需要的小伙伴自行下载吧!
电路原理图如下:
管脚序号 | | | 0 | | | 1 | | | 2 | | | 3 | |
| 4 | |
| 5 | |
| 6 | | | 7 | | | 8 | | | 9 | | | 10 | | | 11 |
| | 12 |
| | 13 |
| | 14 |
| | 15 |
| |
stm32单片机源程序如下:
- /* 包含头文件 ----------------------------------------------------------------*/
- #include "stm32f1xx_hal.h"
- #include "usart/usart.h"
- #include "string.h"
- #include "pwm/pwm.h"
- #include "gpio/gpio.h"
- #include "adc/adc.h"
- #include "tim4capture/tim4capture.h"
- #include "tim2capture/tim2capture.h"
- #include "delayus/delayus.h"
- #include "ultrasonic/ultrasonic.h"
- #include "public/public.h"
- #include "speed/speed.h"
- #include "voltage/voltage.h"
- #include "usartjudge/usartjudge.h"
- #include "direction/direction.h"
- #include "time1/time1.h"
- /* 类型定义 ------------------------------------------------------------------*/
- /*************************timecapture***********************************/
- STRUCT_CAPTURE strCapture1 = { 0, 0, 0, 0 };
- STRUCT_CAPTURE strCapture2 = { 0, 0, 0, 0 };
- STRUCT_CAPTURE strCapture3 = { 0, 0, 0, 0 };
- extern uint8_t ultrasonic_overtime;//超声波超时标志位
- extern uint8_t usart_switch;//串口接完成标志位
- extern uint8_t usart_data[4];//串口接收数据
- uint8_t aRxBuffer;//串口接收缓存
- uint8_t aTxBuffer;//串口发送缓存
- __IO uint16_t ADC_ConvertedValue;// AD转换结果值
- uint32_t sleep_time=0;//睡眠时间,60000=1分钟
- uint8_t sleep_switch=0;//睡眠开关标志位
- uint16_t speed_time=0;//检测没有速度周期
- uint16_t ultrasonic_time=0;
- uint8_t ultrasonic_switch=0;//超声波开关标志位
-
- uint16_t missile1_time=0;//玩具特效1导通时间
- uint8_t missile1_switch=0;//玩具特效1开关标志位
- uint16_t missile2_time=0;//玩具特效2导通时间
- uint8_t missile2_switch=0;//玩具特效2开关标志位
- uint16_t missile3_time=0;//玩具特效3导通时间
- uint8_t missile3_switch=0;//玩具特效3开关标志位
- uint16_t missile4_time=0;//玩具特效4导通时间
- uint8_t missile4_switch=0;//玩具特效4开关标志位
- uint16_t voltage_time=0;///电压数据发送周期时间
- /* 扩展变量 ------------------------------------------------------------------*/
- /* 私有函数原形 --------------------------------------------------------------*/
- /* 函数体 --------------------------------------------------------------------*/
- /**
- * 函数功能: 系统时钟配置
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 无
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 外部晶振,8MHz
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 9倍频,得到72MHz主时钟
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟:72MHz
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB时钟:72MHz
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1时钟:36MHz
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2时钟:72MHz
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
- // HAL_RCC_GetHCLKFreq()/1000 1ms中断一次
- // HAL_RCC_GetHCLKFreq()/100000 10us中断一次
- // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); // 配置并启动系统滴答定时器
- /* 系统滴答定时器时钟源 */
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
- /* 系统滴答定时器中断优先级配置 */
- HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
- }
- /**
- * 函数功能: 主函数.
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 无
- */
- int main(void)
- {
- uint32_t ulTmrClk; //timecapture
- /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
- HAL_Init();
- /* 配置系统时钟 */
- SystemClock_Config();
-
- /**************GPIO******************************************************************/
- GPIOC13_Init();
- GPIOA2_Init();
-
- GPIOA_Init();
- GPIOB_Init();
- /***************串口******************************************************************/
- /* 初始化串口并配置串口中断优先级 */
- USART1_Init();
- /* 使能接收,进入中断回调函数 */
- HAL_UART_Receive_IT(&husart1,&aRxBuffer,1);
- /***************PWM******************************************************************/
- /* 通用定时器初始化并配置PWM输出功能 */
- GENERAL_TIMx_Init();
-
- /* 启动通道PWM输出 */
- HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_2);
- HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_3);
- HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_4);
- /**************ADC****************************************************************/
- /* ADC 初始化 */
- MX_ADCx_Init();
- HAL_ADCEx_Calibration_Start(&hadcx);
- /* 启动AD转换并使能AD中断 */
- HAL_ADC_Start_IT(&hadcx);
- /* ************************time4capture**********************************/
- /*定时器4初始化并配置输入捕获功能 */
- TIM4_Init();
- /* 获取定时器时钟周期 */
- ulTmrClk = HAL_RCC_GetHCLKFreq()/72;
- /* 启动定时器 */
- HAL_TIM_Base_Start_IT(&htim4);
- /* 启动定时器通道输入捕获并开启中断 */
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_2);
- /* ************************time2capture**********************************/
- /*定时器2初始化并配置输入捕获功能 */
- TIM2_Init();
- /* 启动定时器 */
- HAL_TIM_Base_Start_IT(&htim2);
- /* 启动定时器通道输入捕获并开启中断 */
- HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
-
- /****************************time1************************************/
- /* 基本定时器初始化:1ms中断一次 */
- TIM1_Init();
- /* 在中断模式下启动定时器 */
- HAL_TIM_Base_Start_IT(&htim1);
-
- /*舵机归位*/
- TIM3->CCR4 =170;
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);//扫描ON
- HAL_Delay(2000);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);//扫描OFF
- /* 无限循环 */
- while (1)
- {
-
- /*-----------------------------------------------*/
- if(usart_switch)
- {
- switch(usart_data[1])
- {
- case 0x00:
- switch(usart_data[2])
- {
- case 0x00:stop();//停止
- break;
- case 0x01:forward();//前进
- break;
- case 0x02:back();//后退
- break;
- case 0x03:left();//向左
- break;
- case 0x04:right();//向右
- break;
- default:break;
- }break;
-
- case 0x01:
- switch(usart_data[2])
- {
- case 0x00:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);//探照灯OFF
- break;
- case 0x01:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);//探照灯ON
- break;
- default:break;
- }break;
-
- case 0x02:
- switch(usart_data[2])
- {
- case 0x00:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);//激光OFF
- break;
- case 0x01:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);//激光ON
- break;
- default:break;
- }break;
-
- case 0x03:
- switch(usart_data[2])
- {
- case 0x01://玩具特效1启动
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
- missile1_switch=1;
- break;
- case 0x02://玩具特效2启动
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
- missile2_switch=1;
- break;
- case 0x03://玩具特效3启动
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
- missile3_switch=1;
- break;
- case 0x04://玩具特效4启动
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);
- missile4_switch=1;
- break;
- default:break;
- }break;
- case 0x04:
- switch(usart_data[2])
- {
- case 0x00:
- ultrasonic_switch=0;
- TIM3->CCR4 =170;
- ultrasonic_time=2000;
- break;
- case 0x01:
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);//扫描ON
- ultrasonic_switch=1;
- break;
- default:break;
- }break;
- case 0x05:
- {
- TIM3->CCR1=TIM3->CCR2=(usart_data[2]*256)+usart_data[3];
- }break;
- case 0x06:
- {
- sleep_time=((usart_data[2]*256)+usart_data[3])*60000;
- if(sleep_time) sleep_switch=1;
- }break;
- case 0x07:
- {
- TIM3->CCR3 = usart_data[3];//玩具特效舵机PWM占空比(150-230)
- }break;
- default:break;
- }
- usart_switch=0;
- }
- /*超声波*/
- if(ultrasonic_switch)
- {
- ultrasonic();
- }else if(!ultrasonic_time) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
- /*测转速*/
- speed();
- if(speed_time>100)//100ms
- {
- /* 打印速度speed1 */
- aTxBuffer=0xFE;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0xEF;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x03;//3位有效数据位
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x02;//测速功能标志位
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x00;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x00;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- /* 打印速度speed2*/
- aTxBuffer=0xFE;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0xEF;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x03;//3位有效数据位
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x03;//测速功能标志位
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x00;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- aTxBuffer=0x00;
- HAL_UART_Transmit(&husart1, &aTxBuffer, 1, 0xFFFF);
- speed_time=0;
- }
- /*测电压*/
- if(voltage_time>500)
- {
- voltage();
- voltage_time=0;
- }
- /*玩具特效启动*/
- if(missile1_switch && missile1_time>2000)//2s
- {
- missile1_time=0;
- missile1_switch=0;
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
- }
-
- if(missile2_switch && missile2_time>2000)//2s
- {
- missile2_time=0;
- missile2_switch=0;
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
- }
-
- if(missile3_switch && missile3_time>2000)//2s
- {
- missile3_time=0;
- missile3_switch=0;
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
- }
-
- if(missile4_switch && missile4_time>2000)//2s
- {
- missile4_time=0;
- missile4_switch=0;
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
- }
-
- if(sleep_switch)
- {
- /*舵机归位*/
- ultrasonic_switch=0;
- TIM3->CCR4 =170;
- HAL_Delay(2000);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);//扫描OFF
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);//激光OFF
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);//探照灯OFF
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);//路由器OFF
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
- while(sleep_time) delay_us(1);//延时函数不能删除,否者程序卡死
- HAL_Delay(1000);//此处延时不能删,否者可能会出现程序时序错误
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);//路由器ON
- }
- }
- }
- /**
- * 函数功能: 串口接收完成回调函数
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
- {
- if(UartHandle->Instance==USART1)
- {
- usartjudge();
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
- while(HAL_OK!=HAL_UART_Receive_IT(&husart1,&aRxBuffer,1));
- }
- }
- /**
- * 函数功能: AD转换结束回调函数
- * 输入参数: hadc:AD设备类型句柄
- * 返 回 值: 无
- * 说 明: 无
- */
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
- {
- ADC_ConvertedValue=HAL_ADC_GetValue(&hadcx);
- }
- /**
- * 函数功能: 非阻塞模式下定时器的回调函数
- * 输入参数: htim:定时器句柄
- * 返 回 值: 无
- * 说 明: 无
- */
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance==TIM4)
- {
- strCapture2 .usPeriod ++;
- strCapture3 .usPeriod ++;
- }
- if(htim->Instance==TIM2)
- {
- ultrasonic_overtime=1;
- }
-
- if(htim->Instance==TIM1)
- {
- speed_time++;
- voltage_time++;
- if(ultrasonic_time) ultrasonic_time--;
- if(missile1_switch) missile1_time++;
- if(missile2_switch) missile2_time++;
- if(missile3_switch) missile3_time++;
- if(missile4_switch) missile4_time++;
- if(sleep_switch && sleep_time) sleep_time--;
- else sleep_switch=0;
- }
- }
- /**
- * 函数功能: 定时器捕获中断
- * 输入参数: htim:定时器句柄
- * 返 回 值: 无
- * 说 明: 无
- */
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance==TIM4)
- {
- TIM_IC_InitTypeDef sConfigIC;
- if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)//TIM_CHANNEL_1
- {
- if ( strCapture2 .ucStartFlag == 0 )
- {
- strCapture2 .usPeriod = 0;
- // 获取定时器计数值
- strCapture2 .usCtr = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1);
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_CC1);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);
- strCapture2 .ucStartFlag = 1;
- }
-
- else
- {
- // 获取定时器计数值
- strCapture2 .usCtr2 = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1);
-
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_CC1);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);
- strCapture2 .ucStartFlag = 0;
- strCapture2 .ucFinishFlag = 1;
- }
- }
-
- else//TIM_CHANNEL_2
- {
- if ( strCapture3 .ucStartFlag == 0 )
- {
- strCapture3 .usPeriod = 0;
- // 获取定时器计数值
- strCapture3 .usCtr = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_2);
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2);
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_CC2);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_2);
- strCapture3 .ucStartFlag = 1;
- }
-
- else
- {
- // 获取定时器计数值
- strCapture3 .usCtr2 = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_2);
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2);
-
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_CC2);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_2);
- strCapture3 .ucStartFlag = 0;
- strCapture3 .ucFinishFlag = 1;
- }
- }
- }
- if(htim->Instance==TIM2)
- {
- TIM_IC_InitTypeDef sConfigIC;
- if ( strCapture1 .ucStartFlag == 0 )
- {
- htim2.Instance->CNT=0; // 清零定时器计数
- ultrasonic_overtime=0;
- strCapture1 .usCtr = 0;
-
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2);
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_CC2);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
- strCapture1 .ucStartFlag = 1;
- }
-
- else
- {
- // 获取定时器计数值
- strCapture1 .usCtr = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
- // 配置输入捕获参数,主要是修改触发电平
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2);
-
- // 清除中断标志位
- __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_CC2);
- // 启动输入捕获并开启中断
- HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
- strCapture1 .ucStartFlag = 0;
- strCapture1 .ucFinishFlag = 1;
-
- }
- }
- }
复制代码
压缩包内包含STM32代码与app(不含代码)
STM32代码下载:
STM32代码.7z
(15.06 MB, 下载次数: 638)
|