充电函数如下所示:
Input voltage =VDD(1- exp(- t /T))
其中:
● VDD 为正电源电压
● t 为时间
● T 为 RC 常数
根据上述公式可以推算:
C = -t / ( R x In( 1-threshold /(VDD) ))
比较器配置程序:
void Comp_Config(uint32_t COMP_Selection_COMPx)
{
COMP_InitTypeDef COMP_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_COMP, ENABLE);//开比较器时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//开GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_7);// 复用AF7,比较器输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
//内部参考电压1.2v(可以内部基准设置0.4v、0.6v、0.9v和1.2v)
COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_VREFINT;
//PA5为正相输入引脚
COMP_InitStructure.COMP_NonInvertingInput = COMP_NonInvertingInput_IO6;
//输出重印射到TIM1的输入捕获通道4
COMP_InitStructure.COMP_Output = COMP_Output_TIM1IC1;
//比较器不上锁
COMP_InitStructure.COMP_BlankingSrce = COMP_BlankingSrce_None;
//比较器输出极性:同相输出
COMP_InitStructure.COMP_OutputPol = COMP_OutputPol_NonInverted;
//比较器迟滞电压:0mV(可设置迟滞电压0-27mV)
COMP_InitStructure.COMP_Hysteresis = COMP_Hysteresis_No;
//比较器模式:中等速率(可设置极低速率、低速率、中等速率、高速率)
COMP_InitStructure.COMP_Mode = COMP_Mode_MediumSpeed;COMP_Init(COMP_Selection_COMPx, &COMP_InitStructure);
//使能比较器
COMP_Cmd(COMP_Selection_COMPx, ENABLE);
}
定时器TIM1配置程序:
void TIM1_PWMINPUT_INIT(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM1_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//TIM1时钟使能
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);GPIOA时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;// TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_IRQn; //配置中断优先级
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM1_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1映射到TI1 上
TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕获
TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上
TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频
TIM1_ICInitStructure.TIM_ICFilter = 0x0; //不滤波
TIM_PWMIConfig(TIM1, &TIM1_ICInitStructure);
TIM_ITConfig(TIM1, TIM_IT_CC1|TIM_IT_Update, ENABLE); //使能捕获和更新中断
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1|TIM_IT_Update); //清中断
TIM_Cmd(TIM1, ENABLE); //定时器使能
}
定时器TIM1中断服务函数:
void TIM1_CC_IRQHandler (void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
{
period = TIM_GetCapture1(TIM1);
duty = TIM_GetCapture2(TIM1);
CollectFlag = 1;
}
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1|TIM_IT_Update);
}
小结:
1、为保证恶劣环境下比较器设置不能被无效寄存器访问或者程序计数器破坏所改变,比较器控制和状态寄存器可以设为写保护(只读),一旦设置完成, LOCK 位必须设为 1,这导致整个 COMPx_CSR 寄存器变成只读,包括 LOCK 位在内。写保护只能被 MCU 复位所清除。
2、在某些用电池供电的应用中,MCU需要在环境明亮时上电;其它情况下,微控制器必须保持断电状态。对于此类应用,可以使用电阻随光强度变化的光敏电阻 (LDR) 来控制MCU的状态。使用 LDR 传感器时,MCU可根据 LDR 电阻提供的电压切换到低功耗模式或退出低功耗模式。MM32L0系列MCU 的比较器COMP1和COMP2的可在内部将该输出分别连接到 EXTI 线19和20。
0