高血压专题网,内容丰富有趣,生活中的好帮手!
高血压专题网 > stm32ccu6基于HAl库的开发

stm32ccu6基于HAl库的开发

时间:2020-06-23 00:48:13

相关推荐

stm32ccu6基于HAl库的开发

目录

硬件情况:

pwm:

代码使用方式:

模式一:

模式二:

感谢声明:

硬件情况:

淘宝上面20几块绿色盗版开发板(支持正版),st_linkV2烧录器

然后是导师的要求:

我们已经买了这个板,准备用它做一个直流电机控制的电路

我们用1个光电门检测旋转的起始点,另外1个光电门检测旋转位置。

基本要求有:

1、检测到起始点后输出另一个光电门的脉冲,用1个门电路控制脉冲是否输出;

2、检测到起始点后按规定的时序输出脉冲;

3、能和上位机通信,工作模式由上位机定。也可以通过引脚的电平组合定工作模式。

目标方案:

采用F401CCU6系统板,控制输出。PWM脉冲输出速度,工作模式上位机通信确定。

具体方案:按键a(KEY2B0)确定模式1,2:串口输出 "模式X" ,

按下按键b(KEY3B1):串口输出(模式一)“请输入设定个数和设定输出PWM组(为了方便连续实验)”OR(模式二)“请输入设定t/T,输入循环次数”

在按一次按键a:

(模式一)开始检测光电门PWM,当稳定时,串口输出“开始工作”,检测脉冲单片机计脉冲数至设定个数,输出设定PWM(控制光电门输入脉冲,是个数组,最多可存储10个)

(模式二)开始检测光电门PWM,当稳定时,串口输出“开始工作,当前T:XXX”,检测到宽脉冲,计1,输出1.单片机计数至设定个数。输出0;

前前后后反正中途变方案了好多;

下面是干货,各种模块

用stm32ccu6开发板的人知道,像这种,资料很少,不向正点原子那种官方例程搞好,然后ctrl+c+v,so easy.它只有一个虚拟串口+定时灯+GPIO口的例程,一些F4库他还会删删减减,更为要命的是,有些同学(比如我)只会keil,不会说stmcubex(是真的强,狗头狗头),移植程序就很难。

但是主要在于三个程序:

pwm串口捕获,输出指定pwm,虚拟串口收发指令并控制(上位机还没有做好QAQ)

pwm输出:

开始输出。正点原子官方HAl例程直接整。

pwm串口捕获:

检测最终版:鬼才知道我修了几版。个式bug。

主要是主要就是声明一个接口,声明一个timer定时器,声明一个中断,clock切换,开始输出。,然后在main.c,设定数值,设定检测流程。

/* USER CODE BEGIN Header *//********************************************************************************* @file : main.c* @brief: Main program body******************************************************************************** This notice applies to any and all portions of this file* that are not between comment pairs USER CODE BEGIN and* USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools* are owned by their respective copyright owners.** COPYRIGHT(c) STMicroelectronics** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:* 1. Redistributions of source code must retain the above copyright notice,*this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright notice,*this list of conditions and the following disclaimer in the documentation*and/or other materials provided with the distribution.* 3. Neither the name of STMicroelectronics nor the names of its contributors*may be used to endorse or promote products derived from this software*without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.********************************************************************************//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include "main.h"#include "adc.h"#include "dma.h"#include "rtc.h"#include "tim.h"#include "usb_device.h"#include "gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include "usbd_cdc_if.h"#include <stdio.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 *//* Buffers used for displaying Time and Date */uint8_t aShowTime[50] = {0};uint8_t aShowDate[50] = {0};uint32_t capture_Buf[3] = {0}; //存放计数值uint8_t capture_Cnt = 0; //状态标志位uint32_t high_time; //高电平时间/* 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 Display the current time and date.* @param showtime : pointer to buffer* @param showdate : pointer to buffer* @retval None*//* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/int main(void){/* USER CODE BEGIN 1 */uint32_t tick,tick1,tick2;uint16_t uhAdc[2];uint8_t sendAdct[50];//float Vrefint,TempSensor;uint16_t Gpio = GPIO_PIN_All,GpioA = GPIO_PIN_All,GpioB = GPIO_PIN_All;CLEAR_BIT(GpioA,GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_8);///* 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_RTC_Init();MX_USB_DEVICE_Init();MX_ADC1_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */HAL_ADC_Start_DMA(&hadc1,(uint32_t *)uhAdc,sizeof(uhAdc));tick2 = tick1 = tick = HAL_GetTick();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){switch (capture_Cnt){case 0:capture_Cnt++;__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//启动输入捕获 或者: __HAL_TIM_ENABLE(&htim5);break;case 3:high_time = capture_Buf[1]- capture_Buf[0]; //高电平时间//HAL_UART_Transmit(&htim2, (uint8_t *)high_time, 1, 0xffff); //发送高电平时间CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"high_time: %ld \r\n",high_time));//HAL_Delay(1000); //延时1Scapture_Cnt = 0; //清空标志位break;}/* D1 闪烁测试 *//*if((HAL_GetTick() - tick >= 500 )){tick = HAL_GetTick();HAL_GPIO_TogglePin(LED_C13_GPIO_Port,LED_C13_Pin);}*//* 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};RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};/**Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);/**Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.LSEState = RCC_LSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 336;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;RCC_OscInitStruct.PLL.PLLQ = 7;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();}PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){Error_Handler();}HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_5);}/* USER CODE BEGIN 4 */void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if(TIM2 == htim->Instance){switch(capture_Cnt){case 1:capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获capture_Cnt++;break;case 2:capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获 或者: __HAL_TIM_DISABLE(&htim5);capture_Cnt++; }}}/* 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****/

操作全在

可以下载stmcubex,也可以学到其他操作,实心推荐

Z小旋【STM32】HAL库 STM32CubeMX系列学习教程

虚拟串口收发指令并控制:

有一说一这部分有点久远了,先对借鉴的作者说一声感谢!!

主要是stmccu6这例程,本身就有CDC_XXX,这样的输出

另外为了进行控制

if(my_RxLength!=0){for(i=0;i<my_RxLength;i++){//HAL_Delay(500u);//设定个数设定if(my_RxBuf[i]==97)//当输入串口a时+1{shedinggeshu=shedinggeshu+1;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",shedinggeshu));}if(my_RxBuf[i]==98)//当输入串口b时-1{shedinggeshu=shedinggeshu-1;if(shedinggeshu==-1){shedinggeshu=0;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number Error%d\r\n"));}CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",shedinggeshu));}//设定输出PWM组if(my_RxBuf[i]==99)//当输入串口c时确定输入一个PWM{pwmnum=pwmnum+1;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set pwmnum: %d ge\r\n",pwmnum));pwmflag=1;}if(pwmflag==1){if(my_RxBuf[i]==97)//当输入串口a时+10{pwmcount=pwmcount+10;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",pwmcount));}if(my_RxBuf[i]==98)//当输入串口b时-10{pwmcount=pwmcount-10;if(pwmcount<0){pwmcount=0;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number Error%d\r\n"));}CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",pwmcount));}if(my_RxBuf[i]==101)//当输入串口e时+1{pwmcount=pwmcount+1;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",pwmcount));}if(my_RxBuf[i]==102)//当输入串口f时-1{pwmcount=pwmcount-1;if(pwmcount<0){pwmcount=0;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number Error%d\r\n"));}CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",pwmcount));}if(my_RxBuf[i]==100)//当输入串口d时停止修改PWM,pwmcount放置pwm100倍{pwmflag=0;//pwmzu[pwmnum-1]=pwmcount;CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the end set pwmnum: %d ge\r\n",pwmnum));CDC_Transmit_FS(sendAdct,sprintf((char *)sendAdct,"\r\n the set number: %d\r\n",pwmcount));}}}for(i=0;i<my_RxLength;i++){my_RxBuf[i]=0;}}

就是把串口读取到的存储在一个数组,要用时挨个取出,为了之后不出错,还要即时清空。

cdc串口输出就有一点迷,会警告,总程序共有十个警告,但不影响使用。

代码分享:链接: /s/1p1gYMzV5YHxDJ5X8HghZhg?pwd=qhif 提取码: qhif 复制这段内容后打开百度网盘手机App,操作更方便哦

--来自百度网盘超级会员v4的分享

希望能进行探讨在代码过程中发现什么问题。也希望能发表一下自身见解。

代码使用方式:

用flagmode来区分工作,

先进入flagmode==1:判断进入哪种工作模式,模式一串口输入“q”,模式二串口输入“p”,

模式一:

进入flagmode==5:输入工作数据,workliza,worklizb来判断模式几,然后我们是模式一,需要检测到特定脉冲,而我们则是用高电平时长检测,检测至设定个数,输出设定PWM波,所以一个整数,一个数组。输入一次“a”,设定个数+1;输入一次“b”,设定个数-1;输入一次“c”,设定数组值+1;且输入一次“g”,设定个数+10;输入一次“h”,设定个数-10;输入一次“e”,设定个数+1;输入一次“f”,设定个数-1;输入串口“d“时停止修改PWM,pwmcount放置pwm100倍。设定好一切之后,按一次”r“;

进入flagmode==2:按下”p“,输出当前高电平时间,再按下”s“,进入工作。

进入flagmode==4:串口输出“开始工作,当前T:XXX”,检测到宽脉冲,计1,输出1.单片机计数至设定个数。输出0;

会有一个回退程序:按下”r“,进行回退到flagmode==1;

模式二:

进入flagmode==5:输入工作数据,workliza,worklizb来判断模式几,然后我们是模式二,就是检测到一个指定信号脉冲,开始启动,知道当前高脉冲时间,然后不断输出一个时间比值上为1+t/T的脉冲,和检测次数。所以一个数组,一个整数。;输入一次“c”,设定数组值+1;且输入一次“g”,设定个数+10;输入一次“h”,设定个数-10;输入一次“e”,设定个数+1;输入一次“f”,设定个数-1;当输入串口d时停止修改zhouqibizhicount,zhouqibizhicount放置t/T倍。输入一次“a”,设定个数+1;输入一次“b”,设定个数-1设定好一切之后,按一次”r“;

进入flagmode==2:按下”q“,进入工作。

进入flagmode==4:然后会输出当前周期”T,按下”y,会自动输出当前高电平时间,输出pWM。检测到设定个数,停止

会有一个回退程序:按下”r“,进行回退到flagmode==1;

感谢声明:

感谢csdn作者:strongerhuang,(f4教程很棒,给了我极多的启发)

感谢正点原子官方(例程提供非常全面)

感谢csdn作者:Z小旋(输入捕获借鉴)

感谢csdn作者:21世纪不靠谱艺术表演家(虚拟串口教程非常完善)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。