(转)基于STM32F303VC四个ADC模块同时转换之应用示例

admin 发表了文章 • 0 个评论 • 297 次浏览 • 2020-05-28 18:48 • 来自相关话题

本文转自: https://mp.weixin.qq.com/s/_iR_yVWwJOlTglfcOK3M2g 感谢:Miler 茶话MCU 分享欢迎大家去关注此公众号,里面干货不少.有人使用STM32F303VC开发电源方面的产品,想使用4个ADC模块进行同时采样转换,感觉不知怎么实现。这里简单介绍下实现过程,以供参考。现在希望四个ADC模块同时进行AD转换。我们使用双ADC主从模式,ADC1与ADC2成为一组,构成主从模式。同样,ADC3与ADC4也成为一组构成主从模式。其中,ADC1和ADC3分别为各组中的主,并让两组都工作在同时转换模式,对规则通道进行ADC转换。它们的转换使用同一定时器事件来触发,这里选择TIM4的更新事件来触发所有ADC的转换。如下图所示,主ADC的CH1与从ADC的CH16同时进行转换,主ADC的CH2与从ADC的CH14同时进行转换,就这样依次按照红色箭头方向进行。对于工作在主从模式的双ADC的转换结果,可以合并成一个字放在一个公共数据寄存器里ADCx_CDR( x=12 or 34),能被CPU或DMA读取访问。其中高半字存放从ADC的转换结果,低半字存放主ADC的转换结果。【这里各ADC的分辨率选用12位,转换结果采用右对齐方式。】大致原理就介绍到这里,更多细节还得看STM32参考手册。现在将4个ADC模块用起来,同时进行ADC转换,通过DMA传输ADC结果。这里只用到规则转换,其中,ADC1使用它的CH1/CH2,ADC2使用它的CH3/CH4, ADC3使用它的CH5/CH6, ADC4使用CH7/CH8。各ADC模块的采样通道连接如下图所示,ADC经定时器事件触发转换。现在基于STM32CubeMx进行初始化配置。先看TIM4的配置,它的更新事件作为所有ADC的转换触发事件。然后根据上面的规划,对4个ADC模块进行配置。4个ADC的配置除了各自选择的通道不一样外,在上面页面里的配置都相同。定时器触发,工作在双模式同时转换。 因为要对ADC结果实行DMA传输,根据当前所选择的工作模式,这里只需对ADC1和ADC3两个主ADC的转换事件进行DMA配置,如下图所示:我这里将DMA传输配置成循环模式,基于ADC3事件的DMA传输配置跟上面一样,只是DMA通道不同而已。将时钟等必要的配置完成后即可生成初始化代码。在初始化代码的基础上添加用户代码。我定义了2个数组pData12[4]、pData34[4]分别存放ADC1/2 与ADC3/4合并后的转换结果。基于STM32Cube HAL库组织代码,相关参考代码如下:代码直观明了,无须过多解释。提醒一点,使用双ADC模式时,从ADC要先于主ADC启动使能。 基于上面的规划与代码,测试结果如下:结果跟实际硬件连接情况完全吻合。上面只是基于双ADC模块规则通道的同时转换模式做了简单应用介绍。其实对于双ADC模式,还有其它更多转换模式,在STM32开发应用中可以灵活选择使用。 查看全部

本文转自: https://mp.weixin.qq.com/s/_iR_yVWwJOlTglfcOK3M2g

感谢:Miler 茶话MCU 分享

欢迎大家去关注此公众号,里面干货不少.


有人使用STM32F303VC开发电源方面的产品,想使用4ADC模块进行同时采样转换,感觉不知怎么实现。这里简单介绍下实现过程,以供参考。

image.png

现在希望ADC模块同时进行AD转换。我们使用双ADC主从模式,ADC1ADC2成为一组,构成主从模式。同样,ADC3ADC4也成为一组构成主从模式。其中,ADC1ADC3分别为各组中的主,并让两组都工作在同时转换模式,对规则通道进行ADC转换

image.png

它们的转换使用同一定时器事件来触发,这里选择TIM4的更新事件来触发所有ADC的转换。如下图所示,ADCCH1ADCCH16同时进行转换,主ADCCH2与从ADCCH14同时进行转换,就这样依次按照红色箭头方向进行。

image.png

对于工作在主从模式的双ADC的转换结果,可以合并成一个字放在一个公共数据寄存器里ADCx_CDR( x=12 or 34),能被CPUDMA读取访问其中高半字存放ADC的转换结果,低半字存放ADC的转换结果。【这里各ADC的分辨率选用12位,转换结果采用右对齐方式。】


image.png

大致原理就介绍到这里,更多细节还得看STM32参考手册。

现在将4ADC模块用起来,同时进行ADC转换,通过DMA传输ADC结果。这里只用到规则转换,其中,ADC1使用它的CH1/CH2,ADC2使用它的CH3/CH4, ADC3使用它的CH5/CH6, ADC4使用CH7/CH8

image.png

ADC模块的采样通道连接如下图所示,ADC经定时器事件触发转换。

image.png

现在基于STM32CubeMx进行初始化配置。


先看TIM4的配置,它的更新事件作为所有ADC的转换触发事件。

image.png

然后根据上面的规划,对4ADC模块进行配置。


image.png

4ADC的配置除了各自选择的通道不一样外,在上面页面里的配置都相同。定时器触发,工作在双模式同时转换。

 

因为要对ADC结果实行DMA传输,根据当前所选择的工作模式,这里只需对ADC1ADC3两个主ADC的转换事件进行DMA配置,如下图所示:

image.png



我这里将DMA传输配置成循环模式,基于ADC3事件的DMA传输配置跟上面一样,只是DMA通道不同而已。

将时钟等必要的配置完成后即可生成初始化代码。在初始化代码的基础上添加用户代码。

我定义了2个数组pData12[4]pData34[4]分别存放ADC1/2 ADC3/4合并后的转换结果。

image.png

基于STM32Cube HAL组织代码,相关参考代码如下:

image.png


代码直观明了,无须过多解释。提醒一点,使用双ADC模式时,ADC要先于ADC启动使能。

 

基于上面的规划与代码,测试结果如下:

image.png


结果跟实际硬件连接情况完全吻合。


上面只是基于双ADC模块规则通道的同时转换模式做了简单应用介绍。其实对于双ADC模式,还有其它更多转换模式,在STM32开发应用中可以灵活选择使用。


(转)基于STM32Cube库的Timer捕获应用

admin 发表了文章 • 0 个评论 • 2235 次浏览 • 2018-06-14 09:19 • 来自相关话题

当使用Timer做捕获输入时,有时候需要将捕获得到的数据通过DMA方式写到定义好的数据或数组中,本文将详细介绍使用CubeMX配置PWM捕获功能,用户可以直接得到输入的PWM信号的频率以及占空比,Cube库可以很方便配置。实验过程中,当配置超过两个以上的Timer通道DMA时会遇到一些问题,本文也对其进行了说明并给出了解决方案。Timer2的PWM信号捕获功能√使用Timer的IC1,IC2两个捕获输入通道,两个通道的外部管脚输入配置为相同TI1通道;√两个通道的捕获输入极性,一个为Active,另外一个为Inactive;√其中一个TI1FP1作为触发输入,从模式配置为复位模式;√这样CCR1为PWM输入的频率值,CCR2为占空比值(正/负)。使用STM32CubeMX对外设进行初始化配置:Step1: TIM1的输出PWM波作为捕获输入的被测信号,输出管脚为PA8Step2: TIM2的输入管脚为PA5(CH1)Step3: 配置TIM2的输入捕获参数Step4: 捕获数据直接通过DMA方式保存到RAM变量Update_Value1和Update_Value2。Step5: 测试读取到的CCR1、CCR2的数据与Update_Value1、Update_Value2对应,PWM波的频率和占空比都可以捕获得到。实验过程要点提示在stm32f3xx_hal_tim.c库文件中的HAL_TIM_IC_Start_DMA函数中会将状态置忙。但在函数结尾配置完毕后没有将该状态位复位,如果客户在其用户程序中使用了这个函数,这会导致该状态位始终为忙,后续任何对该状态的判断配置都将无法执行:因此需要在函数的最后将状态复位:本文小结本文重点介绍利用STM32CubeMX初始化配置工具和STM32Cube库如何通过TIMER的捕获功能完成对频率、占空比的测试,同时我们对如何解决实验过程中遇到的一些问题,做了特别提示。我们知道STM32Cube库非常庞大,虽难尽善尽美,但一定会越来越强大、越来越完善。本文转自:https://mp.weixin.qq.com/s/e2M22gpqFmOKee36MFe9oQ感谢ST人的分享和付出! 查看全部

当使用Timer做捕获输入时,有时候需要将捕获得到的数据通过DMA方式写到定义好的数据或数组中,本文将详细介绍使用CubeMX配置PWM捕获功能,用户可以直接得到输入的PWM信号的频率以及占空比,Cube库可以很方便配置。

实验过程中,当配置超过两个以上的Timer通道DMA时会遇到一些问题,本文也对其进行了说明并给出了解决方案。

Timer2的PWM信号捕获功能


使用Timer的IC1,IC2两个捕获输入通道,两个通道的外部管脚输入配置为相同TI1通道;

两个通道的捕获输入极性,一个为Active,另外一个为Inactive;

其中一个TI1FP1作为触发输入,从模式配置为复位模式;

这样CCR1为PWM输入的频率值,CCR2为占空比值(正/负)。

webwxgetmsgimg.jpg


使用STM32CubeMX对外设进行初始化配置:


Step1: TIM1的输出PWM波作为捕获输入的被测信号,输出管脚为PA8

Step2: TIM2的输入管脚为PA5(CH1)

webwxgetmsgimg (1).jpg

Step3: 配置TIM2的输入捕获参数

webwxgetmsgimg (2).jpg

Step4: 捕获数据直接通过DMA方式保存到RAM变量Update_Value1和Update_Value2。

webwxgetmsgimg (3).jpg

Step5: 测试读取到的CCR1、CCR2的数据与Update_Value1、Update_Value2对应,PWM波的频率和占空比都可以捕获得到。


webwxgetmsgimg (4).jpg


实验过程要点提示


在stm32f3xx_hal_tim.c

库文件中的HAL_TIM_IC_Start_DMA函数中会将状态置忙。

webwxgetmsgimg (5).jpg

但在函数结尾配置完毕后没有将该状态位复位,如果客户在其用户程序中使用了这个函数,这会导致该状态位始终为忙,后续任何对该状态的判断配置都将无法执行:

webwxgetmsgimg (6).jpg

因此需要在函数的最后将状态复位:

webwxgetmsgimg (7).jpg

本文小结

本文重点介绍利用STM32CubeMX初始化配置工具和STM32Cube库如何通过TIMER的捕获功能完成对频率、占空比的测试,同时我们对如何解决实验过程中遇到的一些问题,做了特别提示。我们知道STM32Cube库非常庞大,虽难尽善尽美,但一定会越来越强大、越来越完善。



本文转自:https://mp.weixin.qq.com/s/e2M22gpqFmOKee36MFe9oQ


感谢ST人的分享和付出!

读取F4芯片ID和flash的大小

回复

admin 发起了问题 • 1 人关注 • 0 个回复 • 2385 次浏览 • 2015-12-11 10:54 • 来自相关话题

关于FreeRTOS的设置分析和官方例程实验

回复

admin 发起了问题 • 6 人关注 • 0 个回复 • 4652 次浏览 • 2014-12-31 17:17 • 来自相关话题

stm32cube中文教程:TIM3定时,TIM1双通道计数器的实现

admin 发表了文章 • 0 个评论 • 6686 次浏览 • 2014-10-14 00:16 • 来自相关话题

本次利用了,stm32cubemx生成代码,稍微在main中添加得到
打开cubemx,先设置pinout选项卡。
rcc选择crystal。外部时钟
TIM1中选择Channel1的Input Capture direct mode
TIM1中选择Channel2的Input Capture direct mode

TIM3中Clock Source选择Internal Clock
Usart1中MOde选择Asynchronous

其他所有的默认即可。
TIM1用于计数,两个通道同时计数。
TIM3用于定时,并且生成一个脉冲信号
usart用于输出计数结果

Clock configuration选项卡中
时钟我用的25M晶振,系统时钟设为168MHz
APB1 Prescaler 选4,APB2 Prescaler选2

Configuration选项卡中,
usart设置不再讲述,可以去看网站里面的帖子
NVIC按钮打开后,TIM1 Capture Compare interrupt 设为0,2
TIM3 gloable interrupt 设置 0,1
并且以上开启使能
TIM1设置页打开后 counter period (autoreload register-16bits value) 设为65535,up,其他不变,tim1的gpio都设为Pull-up,high
Tim3设置页 prescaler (psc-16 bits value) 为8399
紧接着up,继续9999
最后update event。

好了,设置结束,生成代码,
main.c中的代码:其他的文件没变啊,自己对比添加了哪些吧,懒得一个个写


/[i] Includes ------------------------------------------------------------------[/i]/
#include "stm32f4xx_hal.h"

/[i] Private variables ---------------------------------------------------------[/i]/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart1;

/[i] USER CODE BEGIN 0 [/i]/
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
uint32_t cont_value1 = 0;
uint32_t cont_value2 = 0;
uint32_t v_value1 = 0;
uint32_t v_value2 = 0;
static void Error_Handler(void);
/[i] USER CODE END 0 [/i]/

/[i] Private function prototypes -----------------------------------------------[/i]/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM3_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{

/[i] USER CODE BEGIN 1 [/i]/

/[i] USER CODE END 1 [/i]/

/[i] MCU Configuration----------------------------------------------------------[/i]/

/[i] Reset of all peripherals, Initializes the Flash interface and the Systick. [/i]/
HAL_Init();

/[i] Configure the system clock [/i]/
SystemClock_Config();

/[i] System interrupt init[/i]/
/[i] Sets the priority grouping field [/i]/
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/[i] Initialize all configured peripherals [/i]/
MX_GPIO_Init();
MX_TIM1_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();

/[i] USER CODE BEGIN 2 [/i]/
HAL_TIM_Base_Start_IT (&htim3 );
if(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2) != HAL_OK)
{
/[i] Starting Error [/i]/
Error_Handler();
}
if(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK)
{
/[i] Starting Error [/i]/
Error_Handler();
}
/[i] USER CODE END 2 [/i]/

/[i] USER CODE BEGIN 3 [/i]/
/[i] Infinite loop [/i]/
while (1)
{
// HAL_Delay(1000);

// printf ("hello ,my world!");
HAL_Delay(1000);
printf ("%d , %d \r\n",v_value1, v_value2);
cont_value1= 0;cont_value2= 0;

}
/[i] USER CODE END 3 [/i]/

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

__PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_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_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

RCC_ClkInitStruct.ClockType = 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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/[i] TIM1 init function [/i]/
void MX_TIM1_Init(void)
{

TIM_IC_InitTypeDef sConfigIC;
TIM_MasterConfigTypeDef sMasterConfig;

htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_IC_Init(&htim1);

sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);

HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

}

/[i] TIM3 init function [/i]/
void MX_TIM3_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 8399;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 99;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);

}

/[i] USART1 init function [/i]/
void MX_USART1_UART_Init(void)
{

huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);

}

/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOF_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOE_CLK_ENABLE();
__GPIOB_CLK_ENABLE();

/[i]Configure GPIO pin : PF6 [/i]/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

}

/[i] USER CODE BEGIN 4 [/i]/
static void Error_Handler(void)
{
/[i] Turn LED3 on [/i]/
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
while(1)
{
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
v_value1 = cont_value1;v_value2 = cont_value2;
// cont_value = 0;
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6);

}
/**
* @brief Conversion complete callback in non blocking mode
* @param htim : hadc handle
* @retval None
*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{

/[i] Get the 1st Input Capture value [/i]/
cont_value1 ++;

}
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{

/[i] Get the 1st Input Capture value [/i]/
cont_value2 ++;

}
}
/[i] USER CODE END 4 [/i]/

#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)
{
/[i] USER CODE BEGIN 6 [/i]/
/* 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) */
/[i] USER CODE END 6 [/i]/

}

#endif 查看全部
本次利用了,stm32cubemx生成代码,稍微在main中添加得到
打开cubemx,先设置pinout选项卡。
rcc选择crystal。外部时钟
TIM1中选择Channel1的Input Capture direct mode
TIM1中选择Channel2的Input Capture direct mode

TIM3中Clock Source选择Internal Clock
Usart1中MOde选择Asynchronous

其他所有的默认即可。
TIM1用于计数,两个通道同时计数。
TIM3用于定时,并且生成一个脉冲信号
usart用于输出计数结果

Clock configuration选项卡中
时钟我用的25M晶振,系统时钟设为168MHz
APB1 Prescaler 选4,APB2 Prescaler选2

Configuration选项卡中,
usart设置不再讲述,可以去看网站里面的帖子
NVIC按钮打开后,TIM1 Capture Compare interrupt 设为0,2
TIM3 gloable interrupt 设置 0,1
并且以上开启使能
TIM1设置页打开后 counter period (autoreload register-16bits value) 设为65535,up,其他不变,tim1的gpio都设为Pull-up,high
Tim3设置页 prescaler (psc-16 bits value) 为8399
紧接着up,继续9999
最后update event。

好了,设置结束,生成代码,
main.c中的代码:其他的文件没变啊,自己对比添加了哪些吧,懒得一个个写


/[i] Includes ------------------------------------------------------------------[/i]/
#include "stm32f4xx_hal.h"

/[i] Private variables ---------------------------------------------------------[/i]/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart1;

/[i] USER CODE BEGIN 0 [/i]/
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
uint32_t cont_value1 = 0;
uint32_t cont_value2 = 0;
uint32_t v_value1 = 0;
uint32_t v_value2 = 0;
static void Error_Handler(void);
/[i] USER CODE END 0 [/i]/

/[i] Private function prototypes -----------------------------------------------[/i]/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM3_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{

/[i] USER CODE BEGIN 1 [/i]/

/[i] USER CODE END 1 [/i]/

/[i] MCU Configuration----------------------------------------------------------[/i]/

/[i] Reset of all peripherals, Initializes the Flash interface and the Systick. [/i]/
HAL_Init();

/[i] Configure the system clock [/i]/
SystemClock_Config();

/[i] System interrupt init[/i]/
/[i] Sets the priority grouping field [/i]/
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/[i] Initialize all configured peripherals [/i]/
MX_GPIO_Init();
MX_TIM1_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();

/[i] USER CODE BEGIN 2 [/i]/
HAL_TIM_Base_Start_IT (&htim3 );
if(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2) != HAL_OK)
{
/[i] Starting Error [/i]/
Error_Handler();
}
if(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK)
{
/[i] Starting Error [/i]/
Error_Handler();
}
/[i] USER CODE END 2 [/i]/

/[i] USER CODE BEGIN 3 [/i]/
/[i] Infinite loop [/i]/
while (1)
{
// HAL_Delay(1000);

// printf ("hello ,my world!");
HAL_Delay(1000);
printf ("%d , %d \r\n",v_value1, v_value2);
cont_value1= 0;cont_value2= 0;

}
/[i] USER CODE END 3 [/i]/

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

__PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_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_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

RCC_ClkInitStruct.ClockType = 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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/[i] TIM1 init function [/i]/
void MX_TIM1_Init(void)
{

TIM_IC_InitTypeDef sConfigIC;
TIM_MasterConfigTypeDef sMasterConfig;

htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_IC_Init(&htim1);

sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);

HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

}

/[i] TIM3 init function [/i]/
void MX_TIM3_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 8399;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 99;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);

}

/[i] USART1 init function [/i]/
void MX_USART1_UART_Init(void)
{

huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);

}

/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOF_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOE_CLK_ENABLE();
__GPIOB_CLK_ENABLE();

/[i]Configure GPIO pin : PF6 [/i]/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

}

/[i] USER CODE BEGIN 4 [/i]/
static void Error_Handler(void)
{
/[i] Turn LED3 on [/i]/
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
while(1)
{
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
v_value1 = cont_value1;v_value2 = cont_value2;
// cont_value = 0;
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6);

}
/**
* @brief Conversion complete callback in non blocking mode
* @param htim : hadc handle
* @retval None
*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{

/[i] Get the 1st Input Capture value [/i]/
cont_value1 ++;

}
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{

/[i] Get the 1st Input Capture value [/i]/
cont_value2 ++;

}
}
/[i] USER CODE END 4 [/i]/

#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)
{
/[i] USER CODE BEGIN 6 [/i]/
/* 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) */
/[i] USER CODE END 6 [/i]/

}

#endif

stm32cube中文教程:运行中修改TIM定时时间的例子将1s定时运行中改成200ms定时

admin 发表了文章 • 0 个评论 • 4422 次浏览 • 2014-10-14 00:14 • 来自相关话题

本实验用stm32cubemx生成定时器4的1s定时,然后准备在运行过程中更改定时时间
考虑程序中初始化后定时修改时再次init初始化,应该就可以了。
关于用stm32cube生成定时的方法,请找本论坛文章。
本程序只在原来定时中断中增加了再次初始化代码。
运行正常,测试通过。
代码如下:

其他代码不给出了,只贴出修改了的代码:
在main文件中的定时中断函数中增加:


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
flag++;
HAL_GPIO_TogglePin (GPIOD,GPIO_PIN_14);
if(flag==20)
{
htim4.Init.Period = 1999;
HAL_TIM_Base_Init(&htim4);
}
}

其中flag是计数标示,用来记进入了几次中断,程序中断20次后,修改Period ,然后固化,
之后程序开始以200ms开始闪烁。灯是PD14. 查看全部
本实验用stm32cubemx生成定时器4的1s定时,然后准备在运行过程中更改定时时间
考虑程序中初始化后定时修改时再次init初始化,应该就可以了。
关于用stm32cube生成定时的方法,请找本论坛文章。
本程序只在原来定时中断中增加了再次初始化代码。
运行正常,测试通过。
代码如下:

其他代码不给出了,只贴出修改了的代码:
在main文件中的定时中断函数中增加:


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
flag++;
HAL_GPIO_TogglePin (GPIOD,GPIO_PIN_14);
if(flag==20)
{
htim4.Init.Period = 1999;
HAL_TIM_Base_Init(&htim4);
}
}

其中flag是计数标示,用来记进入了几次中断,程序中断20次后,修改Period ,然后固化,
之后程序开始以200ms开始闪烁。灯是PD14.

stm32cube中文教程:DAC输出模拟电压,用12位精度DA最大3.3v,学习笔记

admin 发表了文章 • 0 个评论 • 7606 次浏览 • 2014-10-14 00:11 • 来自相关话题

用stm32cubemx生成DA输出真对stm32f407的模拟输出电压,很简单
首先,配置时钟,168M,我用的stm32f407discovery板。
这些配置操作我以前提到过,不懂的可以在这个论坛里找找,有图文注释的。
直接点取DAC的通道1,然后去configariton里面配置DAC,其实无需配置,不用改任何东西
生成代码。
打开main文件,找到main函数中初始化后添加:
这个是我自己的例子,你可以适当修改


/[i][size=16]-4- Enable DAC Channel1 [/size]#########################[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[/i]/ [/size][/size][/size][/size][/size][/size][/size]
if(HAL_DAC_Start(&hdac, DAC_CHANNEL_1) != HAL_OK)
{
/[i] Start Error [/i]/
Error_Handler();
}

/[i] USER CODE END 2 [/i]/

/[i] USER CODE BEGIN 3 [/i]/
/[i] Infinite loop [/i]/
while (1)
{


HAL_Delay (1);
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6 );
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value );
if(!flag)
{ value ++; if(value==0xfff){ flag=1; }} else { value--;if(!value) flag=0; }
}

代码注释:第一个意思是开启dac的通道1.
while中的意思是:设置DA的值,我用的12位精度,右对齐,值是value,通道DAC_CHANNEL_1
值value从0增加到4095即0xfff,然后从0xfff减小到0,无限循环,哦,上面还有个指示灯,不过
这么高的频率是指示不出来的。是i我调试其他的时候加的,可以无视它。

用示波器 测量PA4管脚(这个就是DA的输出口1),会看到波形类似三角波,电压是从0升到3.3然后再降到0v,ok,结束实验 查看全部
用stm32cubemx生成DA输出真对stm32f407的模拟输出电压,很简单
首先,配置时钟,168M,我用的stm32f407discovery板。
这些配置操作我以前提到过,不懂的可以在这个论坛里找找,有图文注释的。
直接点取DAC的通道1,然后去configariton里面配置DAC,其实无需配置,不用改任何东西
生成代码。
打开main文件,找到main函数中初始化后添加:
这个是我自己的例子,你可以适当修改


/[i][size=16]-4- Enable DAC Channel1 [/size]#########################[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[size=16]#[/i]/ [/size][/size][/size][/size][/size][/size][/size]
if(HAL_DAC_Start(&hdac, DAC_CHANNEL_1) != HAL_OK)
{
/[i] Start Error [/i]/
Error_Handler();
}

/[i] USER CODE END 2 [/i]/

/[i] USER CODE BEGIN 3 [/i]/
/[i] Infinite loop [/i]/
while (1)
{


HAL_Delay (1);
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6 );
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value );
if(!flag)
{ value ++; if(value==0xfff){ flag=1; }} else { value--;if(!value) flag=0; }
}

代码注释:第一个意思是开启dac的通道1.
while中的意思是:设置DA的值,我用的12位精度,右对齐,值是value,通道DAC_CHANNEL_1
值value从0增加到4095即0xfff,然后从0xfff减小到0,无限循环,哦,上面还有个指示灯,不过
这么高的频率是指示不出来的。是i我调试其他的时候加的,可以无视它。

用示波器 测量PA4管脚(这个就是DA的输出口1),会看到波形类似三角波,电压是从0升到3.3然后再降到0v,ok,结束实验