当前位置: 首页 > article >正文

51c嵌入式~电路~合集25

我自己的原文哦~   https://blog.51cto.com/whaosoft/13241709

一、“开关电源”和“普通电源”的区别

什么叫开关电源

    随着电力电子技术的发展和创新,使得开关电源技术也在不断地创新。目前,开关电源以小型、轻量和高效率的特点被广泛应用几乎所有的电子设备,是当今电子信息产业飞速发展不可缺少的一种电源方式。

    开关电源是利用现代电力电子技术,控制开关管开通和关断的时间比率,维持稳定输出电压的一种电源,开关电源一般由脉冲宽度调制(PWM)控制IC和MOSFET构成。

    开关电源是相对线性电源说的,其输入端直接将交流电整流变成直流电,再在高频震荡电路的作用下,用开关管控制电流的通断,形成高频脉冲电流。在电感(高频变压器)的帮助下,输出稳定的低压直流电。

    由于变压器的磁芯大小与开关电源工作频率的平方成反比,频率越高铁心越小。这样就可以大大减小变压器,使电源减轻重量和体积。而且由于它直接控制直流,使这种电源的效率比线性电源高很多。这样就节省了能源,因此它受到人们的青睐。但它也有缺点,就是电路复杂、维修困难、对电路的污染严重;电源噪声大,不适合用于某些低噪声电路。

开关电源的特点

    开关电源一般由脉冲宽度调制(PWM)控制IC和MOSFET构成。随着随着电力电子技术的发展和创新,目前开关电源主要以小型、轻量和高效率的特点被广泛应用到几乎所有的电子设备,其重要性可见一斑。

开关电源的分类

    根据开关器件在电路中连接的方式,开关电源总的来说可分为串联式开关电源、并联式开关电源、变压器式开关电源等三大类。

    其中,变压器式开关电源还可以进一步分成:推挽式、半桥式、全桥式等多种。根据变压器的激励和输出电压的相位,又可以分成:正激式、反激式、单激式和双激式等多种。

开关电源和普通电源的区别

    普通的电源一般是线性电源,线性电源,是指调整管工作在线性状态下的电源。而在开关电源中则不一样,开关管(在开关电源中,我们一般把调整管叫做开关管)是工作在开、关两种状态下的:开 —— 电阻很小,关 —— 电阻很大。

    开关电源是一种比较新型的电源。它具有效率高,重量轻,可升、降压、输出功率大等优点。但是由于电路工作在开关状态,所以噪声比较大。

■ 举例说明:降压型开关电源

    我们来简单的说说降压型开关电源的工作原理:电路由开关(实际电路中为三极管或者场效应管),续流二极管、储能电感、滤波电容等构成。

    当开关闭合时,电源通过开关、电感给负载供电,并将部分电能储存在电感以及电容中。由于电感的自感,在开关接通后,电流增大得比较缓慢,即输出不能立刻达到电源电压值。

    一定时间后,开关断开,由于电感的自感作用(可以比较形象地认为电感中的电流有惯性作用),将保持电路中的电流不变,即从左往右继续流。这电流流过负载,从地线返回,流到续流二极管的正极,经过二极管,返回电感的左端,从而形成了一个回路。

    通过控制开关闭合跟断开的时间(即PWM——脉冲宽度调制),就可以控制输出电压。如果通过检测输出电压来控制开、关的时间,以保持输出电压不变,这就实现了稳压的目的。

    普通电源和开关电源相同的是都有电压调整管,利用反馈原理来进行稳压的,不同的是开关电源利用开关管进行调整,普通电源一般利用三极管的线性放大区进行调整。比较而言,开关电源的能耗低,对交流电压适用范围要宽,输出直流的波纹系数要好,缺点是开关脉冲干扰。

    普通半桥开关电源的主要工作原理就是上桥和下桥的开关管(频率高时开关管为VMOS)轮流导通,首先电流通过上桥开关管流入,利用电感线圈的存储功能,将电能集聚在线圈中,最后关闭上桥开关管,打开下桥的开关管,电感线圈和电容持续给外部供电。然后又关闭下桥开关管,再打开上桥让电流进入,就这样重复进行,因为要轮流开关两开关管,所以称为开关电源。

    而线性电源就不一样了,由于没有开关介入,使得上水管一直在放水,如果有多的,就会漏出来,这就是我们经常看到的某些线性电源的调整管发热量很大,用不完的电能,全部转换成了热能。从这个角度来看,线性电源的转换效率就非常低了,而且热量高的时候,元件的寿命势必要下降,影响最终的使用效果。

■ 主要区别:工作方式

    线性电源的功率调整管总是工作在放大区,流过的电流是连续的。由于调整管上损耗较大的功率,所以需要较大功率调整管并装有体积很大的散热器,发热严重,效率很低,一般在40%~60%(还得说是很好的线性电源)。

    线性电源的工作方式,使从高压变低压必须有降压装置,一般的都是变压器,也有别的像KX电源,再经过整流输出直流电压。这样一来体积也就很大,比较笨重,效率低、发热量也大;但也有优点:纹波小、调整率好、对外干扰小、适合用于模拟电路/各类放大器等。

    开关电源它的功率器件工作在开关状态,在电压调整时能量是通过电感线圈来临时贮存,这样他的损耗就小,效率也就高,对散热的要求低,但它对变压器和贮能电感也有了更高的要求,要用低损耗高磁导率的材料来做。它的变压器就是一个字小。总效率在80%~98%,开关电源的效率高但体积小,但是和线性电源比它的纹波,电压电流调整率就有一定的折扣了。

二、获取STM32代码运行时间

测试代码的运行时间的两种方法:

  • 使用单片机内部定时器,在待测程序段的开始启动定时器,在待测程序段的结尾关闭定时器。为了测量的准确性,要进行多次测量,并进行平均取值。
  • 借助示波器的方法是:在待测程序段的开始阶段使单片机的一个GPIO输出高电平,在待测程序段的结尾阶段再令这个GPIO输出低电平。用示波器通过检查高电平的时间长度,就知道了这段代码的运行时间。显然,借助于示波器的方法更为简便。

借助示波器方法的实例

    Delay_us函数使用STM32系统滴答定时器实现:

#include "systick.h"


/* SystemFrequency / 1000    1ms中断一次
 * SystemFrequency / 100000     10us中断一次
 * SystemFrequency / 1000000 1us中断一次
 */


#define SYSTICKPERIOD                    0.000001
#define SYSTICKFREQUENCY            (1/SYSTICKPERIOD)


/**
  * @brief  读取SysTick的状态位COUNTFLAG
  * @param  无
  * @retval The new state of USART_FLAG (SET or RESET).
  */
static FlagStatus SysTick_GetFlagStatus(void) 
{
if(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk) 
    {
return SET;
    }
else
    {
return RESET;
    }
}


/**
  * @brief  配置系统滴答定时器 SysTick
  * @param  无
  * @retval 1 = failed, 0 = successful
  */
uint32_t SysTick_Init(void)
{
/* 设置定时周期为1us  */
if (SysTick_Config(SystemCoreClock / SYSTICKFREQUENCY)) 
    { 
/* Capture error */
return (1);
    }


/* 关闭滴答定时器且禁止中断  */
    SysTick->CTRL &= ~ (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);                                                  
return (0);
}


/**
  * @brief   us延时程序,10us为一个单位
  * @param
  *        @arg nTime: Delay_us( 10 ) 则实现的延时为 10 * 1us = 10us
  * @retval  无
  */
void Delay_us(__IO uint32_t nTime)
{     
/* 清零计数器并使能滴答定时器 */
    SysTick->VAL   = 0;  
    SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;     


for( ; nTime > 0 ; nTime--)
    {
/* 等待一个延时单位的结束 */
while(SysTick_GetFlagStatus() != SET);
    }


/* 关闭滴答定时器 */
    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

    检验Delay_us执行时间中用到的GPIO(gpio.h、gpio.c)的配置:

#ifndef __GPIO_H
#define    __GPIO_H


#include "stm32f10x.h"


#define     LOW          0
#define     HIGH         1


/* 带参宏,可以像内联函数一样使用 */
#define TX(a)                if (a)    \
                                            GPIO_SetBits(GPIOB,GPIO_Pin_0);\
else        \
                                            GPIO_ResetBits(GPIOB,GPIO_Pin_0)
void GPIO_Config(void);


#endif


#include "gpio.h"


/**
  * @brief  初始化GPIO
  * @param  无
  * @retval 无
  */
void GPIO_Config(void)
{        
/*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;


/*开启LED的外设时钟*/
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); 


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;    
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
        GPIO_Init(GPIOB, &GPIO_InitStructure);    
}

    在main函数中检验Delay_us的执行时间:

    示波器的观察结果:

    可见Delay_us(100),执行了大概102us,而Delay_us(1)执行了2.2us。

    更改一下main函数的延时参数:

    示波器的观察结果:

    可见Delay_us(100),执行了大概101us,而Delay_us(10)执行了11.4us。

    结论:此延时函数基本上还是可靠的。​

使用定时器方法的实例

    Delay_us函数使用STM32定时器2实现:

#include "timer.h"


/* SystemFrequency / 1000            1ms中断一次
 * SystemFrequency / 100000     10us中断一次
 * SystemFrequency / 1000000         1us中断一次
 */


#define SYSTICKPERIOD                    0.000001
#define SYSTICKFREQUENCY            (1/SYSTICKPERIOD)


/**
  * @brief  定时器2的初始化,,定时周期1uS
  * @param  无
  * @retval 无
  */
void TIM2_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;


/*AHB = 72MHz,RCC_CFGR的PPRE1 = 2,所以APB1 = 36MHz,TIM2CLK = APB1*2 = 72MHz */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


/* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/SYSTICKFREQUENCY -1;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


    TIM_ARRPreloadConfig(TIM2, ENABLE);


/* 设置更新请求源只在计数器上溢或下溢时产生中断 */
    TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Global); 
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
}


/**
  * @brief   us延时程序,10us为一个单位
  * @param  
  *        @arg nTime: Delay_us( 10 ) 则实现的延时为 10 * 1us = 10us
  * @retval  无
  */
void Delay_us(__IO uint32_t nTime)
{     
/* 清零计数器并使能滴答定时器 */
    TIM2->CNT   = 0;  
    TIM_Cmd(TIM2, ENABLE);     


for( ; nTime > 0 ; nTime--)
    {
/* 等待一个延时单位的结束 */
while(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != SET);
     TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    }


    TIM_Cmd(TIM2, DISABLE);
}

    在main函数中检验Delay_us的执行时间:

#include "stm32f10x.h"
#include "Timer_Drive.h"
#include "gpio.h"
#include "systick.h"


TimingVarTypeDef Time;


int main(void)
{    
    TIM2_Init();    
    SysTick_Init();
    SysTick_Time_Init(&Time);


for(;;)
    {
        SysTick_Time_Start(); 
        Delay_us(1000);
        SysTick_Time_Stop();
    }     
}

    怎么去看检测结果呢?用调试的办法,打开调试界面后,将Time变量添加到Watch一栏中。然后全速运行程序,既可以看到Time中保存变量的变化情况,其中TimeWidthAvrage就是最终的结果。

    可以看到TimeWidthAvrage的值等于0x119B8,十进制数对应72120,滴答定时器的一个滴答为1/72M(s),所以Delay_us(1000)的执行时间就是72120*1/72M (s) = 0.001001s,也就是1ms。验证成功。

    备注:定时器方法输出检测结果有待改善,你可以把得到的TimeWidthAvrage转换成时间(以us、ms、s)为单位,然后通过串口打印出来,不过这部分工作对于经常使用调试的人员来说也可有可无。相关推荐:学习STM32单片机,绕不开的串口。​

两种方法对比

软件测试方法

    操作起来复杂,由于在原代码基础上增加了测试代码,可能会影响到原代码的工作,测试可靠性相对较低。由于使用32位的变量保存systick的计数次数,计时的最大长度可以达到2^32/72M = 59.65 s。

示波器方法

    操作简单,在原代码基础上几乎没有增加代码,测试可靠性很高。由于示波器的显示能力有限,超过1s以上的程序段,计时效果不是很理想。但是,通常的单片机程序实时性要求很高,一般不会出现程序段时间超过秒级的情况。

三、xxx

http://www.kler.cn/a/531210.html

相关文章:

  • 【DeepSeek背后的技术】系列一:混合专家模型(MoE)
  • Jenkins 触发构建的几种常见方式
  • STM32_SD卡的SDIO通信_DMA读写
  • deepseek 本地化部署和小模型微调
  • 17.3.4 颜色矩阵
  • 从零开始部署Dify:后端与前端服务完整指南
  • GRE阅读双线阅读 --青山学堂GRE全程班 包括 阅读、数学、写作、填空、背单词
  • Math数字类
  • CH340G上传程序到ESP8266-01(S)模块
  • 大模型领域的Scaling Law的含义及作用
  • 7-4 西安距离
  • SAP HCM 回溯分析
  • 民法学学习笔记(个人向) Part.2
  • 元音字母(模拟)
  • 网络工程师 (16)侵权判断
  • DeepSeek- R1 原理介绍
  • Java中的泛型及其用途是什么?
  • windows linux常用基础命令
  • C++类定义中的关键字public 、protected 、private的详细介绍【定义类成员的访问权限属性和基类的成员的访问权限属性】
  • python:求解爱因斯坦场方程
  • Nginx 变量集合
  • 从零开始部署Dify:后端与前端服务完整指南
  • CSS Module 常用笔记
  • ubuntuCUDA安装
  • 第28节课:前端项目实战—从需求分析到开发流程的全方位指南
  • Vue3学习笔记-事件-4