【电机控制器】FM33LF015芯片——ADC温度传感器
@TOC
前言
使用工具:
1.FM33LF015开发板
2.J-OBV2仿真烧录器
3.USB-TTL
4.上位机串口助手
提示:以下是本篇文章正文内容,下面案例可供参考
一、概述
亮点:
1.有两个运算放大器,对于电机控制来说是不错的
2.支持DMA
二、温度传感器计算公式
三、代码
main.c
float GetT;
int main(void)
{
/* Configure the system clock */
MF_Clock_Init();
/* Initialize FL Driver Library */
FL_Init();
/* Initialize all configured peripherals */
MF_Config_Init();
/* 串口0初始化 */
MF_UART0_Init();
/* 高级定时器PWM PB7输出 */
//MF_ATIM_PWM_Config_Init();
/* 基础定时器1ms */
MF_BSTIM16_Config_Init();
/* 看门狗初始化 */
WDG_Init();
LED1_OFF();
/* Initial ADC */
MF_ADC_Common_Init(); /*ADC基础配置*/
MF_ADC_Init();
while(1)
{
GetT = GetTS_POLL();
printf("温度 = %3f\n",GetT);
WDG_Reset();
Run_Systimer();
Function_Deal();
}
}
mf_adc.c
/* Includes ------------------------------------------------------------------*/
#include "mf_config.h"
/**
* @brief ADC_Common Initialization function
* @param void
* @retval None
*/
void MF_ADC_Common_Init(void)
{
FL_ADC_CommonInitTypeDef Common_InitStruct;
Common_InitStruct.clockSource = FL_CMU_ADC_CLK_SOURCE_RCHF; /*配置ADC工作时钟源*/
Common_InitStruct.clockPrescaler = FL_ADC_CLK_PSC_DIV8; /*配置ADC工作时钟分配*/
Common_InitStruct.referenceSource = FL_ADC_REF_SOURCE_VDDA; /*配置ADC参考源*/
Common_InitStruct.bitWidth = FL_ADC_BIT_WIDTH_12B; /*配置ADC输出位宽*/
(void)FL_ADC_CommonInit(&Common_InitStruct);
}
/**
* @brief ADC Initialization function
* @param void
* @retval None
*/
void MF_ADC_Init(void)
{
FL_ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.conversionMode = FL_ADC_CONV_MODE_SINGLE; /*配置ADC转换模式*/
ADC_InitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO; /*配置ADC转换流程,仅对单次转换有效*/
ADC_InitStruct.waitMode = FL_ENABLE; /*配置ADC等待模式*/
ADC_InitStruct.overrunMode = FL_ENABLE; /*配置ADC_Overrun模式*/
ADC_InitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_FORWARD; /*配置ADC扫描顺序*/
ADC_InitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_NONE; /*配置非软件触发使能及极性*/
ADC_InitStruct.triggerSource = FL_DISABLE; /*配置ADC非软件触发源*/
ADC_InitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_2_ADCCLK; /*配置ADC快速通道采样时间*/
ADC_InitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_512_ADCCLK; /*配置ADC慢速通道采样时间*/
ADC_InitStruct.oversamplingMode = FL_DISABLE; /*配置ADC过采样模式*/
ADC_InitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_16X; /*配置ADC过采样率*/
ADC_InitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_4B; /*配置ADC过采样结果移位*/
(void)FL_ADC_Init(ADC, &ADC_InitStruct);
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_TS); /*通道选择*/
}
static uint8_t GetVREF1P2Sample_POLL(uint32_t *ADCRdresult)
{
uint32_t counter = 0;
uint32_t EOC_Flag;
uint8_t State;
FL_CMU_SetADCPrescaler(FL_CMU_ADC_PSC_DIV8); //配置ADC工作时钟分频
FL_VREF_EnableVREFBuffer(VREF); //使能VREF BUFFER,
//为了考虑功耗BUFFER可关闭,从使能到ADC可以正常采样需要100us的建立时间,本例程配置慢速通道较长的采样时间,来保证建立时间满足。
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_ALL_CHANNEL); //清空打开的通道
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2); //通道选择
FL_ADC_ClearFlag_EndOfConversion(ADC); //清标志
FL_ADC_Enable(ADC); //启动ADC
FL_ADC_EnableSWConversion(ADC); //开始转换
do
{
EOC_Flag = FL_ADC_IsActiveFlag_EndOfConversion(ADC);
counter++;
} while((counter != 0xFFFFFFFFU) && (EOC_Flag == 0U)); //等待转换完成
if(EOC_Flag == 0x01U)
{
FL_ADC_ClearFlag_EndOfConversion(ADC); //清标志
*ADCRdresult = FL_ADC_ReadConversionData(ADC); //获取采样值
FL_ADC_Disable(ADC); //关闭ADC
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2); //通道关闭
FL_VREF_DisableVREFBuffer(VREF); //关闭VREF BUFFER
State = 0;
}
else
{
State = 1 ;
}
return State;
}
static uint8_t GetTSSample_POLL(uint32_t *ADCRdresult)
{
uint32_t counter = 0;
uint32_t EOC_Flag;
uint8_t State;
FL_CMU_SetADCPrescaler(FL_CMU_ADC_PSC_DIV8); //配置ADC工作时钟分频
FL_VREF_EnableVPTATBuffer(VREF); //使能PTATBUFFER
//为了考虑功耗BUFFER可关闭,从使能到ADC可以正常采样需要100us的建立时间,本例程配置慢速通道较长的采样时间,来保证建立时间满足。
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_ALL_CHANNEL); //清空打开的通道
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_TS); //通道选择
FL_ADC_ClearFlag_EndOfConversion(ADC); //清标志
FL_ADC_Enable(ADC); //启动ADC
FL_ADC_EnableSWConversion(ADC); //开始转换
do
{
EOC_Flag = FL_ADC_IsActiveFlag_EndOfConversion(ADC);
counter++;
} while((counter != 0xFFFFFFFFU) && (EOC_Flag == 0U)); //等待转换完成
if(EOC_Flag == 0x01U)
{
FL_ADC_ClearFlag_EndOfConversion(ADC); //清标志
*ADCRdresult = FL_ADC_ReadConversionData(ADC); //获取采样值
FL_ADC_Disable(ADC); //关闭ADC
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_INTERNAL_TS); //通道关闭
State = 0;
}
else
{
State = 1 ;
}
return State;
}
float GetTS_POLL(void)
{
uint32_t VPTAT = 0, VPTAT_30 = 0, GetTSSample = 0, GetVREF1P2Sample = 0;
uint8_t Get122VSample_State, GetTSample_State;
float GetTS = 0.00f;
Get122VSample_State = GetVREF1P2Sample_POLL(&GetVREF1P2Sample);
GetTSample_State = GetTSSample_POLL(&GetTSSample);
if((GetVREF1P2Sample != 0) && (Get122VSample_State == 0) && (GetTSample_State == 0))
{
VPTAT = (uint32_t)(((uint64_t)GetTSSample * 3000 * (ADC_VREF)) / ((uint64_t)GetVREF1P2Sample * 4095));
VPTAT_30 = ((uint32_t)ADC_TS * 3000) / (4095);
GetTS = ((float)VPTAT - (float)VPTAT_30) / (2.6f) + (30.0f);
}
// 转换结果
return GetTS;
}
四、实验
五、参考资料
keil 下如何使用printf
【STM32学习】定时器寄存器配置、功能工作过程详解
stm32f103定时器配置与时间计算公式
STM32 TIM(一)定时中断+时钟源选择
总结
本文仅仅简单介绍了【电机控制器】FM33LF015芯片——定时器,评论区欢迎讨论。