百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

隔离电源拓扑,MCUXpresso,OTFAD以及反激拓扑技术文章分享

lipiwang 2024-10-16 13:09 11 浏览 0 评论

隔离和非隔离电源拓扑,看这篇文章就够了!

1)非隔离DC-DC拓扑介绍

Buck型拓扑变换器

Buck型变换器的拓扑结构如图所示,Buck型变换器也称降压型电源拓扑。在开关管S导通时,二极管VD负极电压高于正极反偏截止,此时电流经过电感L向电容和负载供电,同时电感L中储存了能量。在开关管S关断时,电感L中储存的能量不能立即释放,产生的感应电流通过负载、二极管VD形成续流通路,继续给负载供电。该二极管也因此称为续流二极管。在降压型电源拓扑中,当驱动开关管的PWM占空比为D时,输出与输入满足的关系为:

Boost型拓扑变换器

Boost变换器基本拓扑结构如图所示。Boost变换器也称为升压型电源拓扑。当开关管S导通时,二极管正极电压低于负极电压反偏关断,电源和电感形成通路,电感L流过电流储存能量,此时负载由电容提供能量。当开关管S断开时,此时二极管正向导通,电源和电感L储存的能量同时向电容、负载供电。在升压型变换器中,当驱动开关管的控制信号占空比为D时,输出与输入满足关系为:

Buck-Boost型拓扑变换器

Buck-Boost变换器基本拓扑结构如图所示,Buck-Boost变换器也称为升降压型开关电源拓扑,。在开关管S导通时,二极管负极电压高于正极电压反偏截止,电源和电感形成通路,电感L储存能量。当开关管S关断时,二极管正向导通,电感电流不会立即释放与负载、二极管形成续流通路。但是,此时负载电压与输入电压极性相反。在Buck-Boost变换器中,当驱动开关管的控制信号的占空比为D时,输出与输入满足的关系为:

2)隔离式DC-DC拓扑介绍

正激式拓扑变换器

正激式变换器基本拓扑结构如图所示。将变压器放在降压型变换器的开关管和二极管之间就可以得到正激式的拓扑结构,变压器的原边和副边的隔离就使输入和输出隔离。正激时变换器因电路设计简单、经济便捷,在50W~400W的场合应用很广。但是由于变压器上所有线圈电流在开关管关断的时候,全部断开,为了保证变压器的磁芯不发生磁饱和现象,附加绕组W3的加入起到磁芯复位的功能。

当开关管S导通时,电源电压加到初级绕组W1上,根据N1、N2同名端的关系,此时初级绕组能量传递到次级绕组W2,VD1导通,电感L,电容C共同获得初级输入的能量。当开关管S关断时,W1中剩余能量通过辅助绕组W3返回到电源的输入,VD1截止,次级的电感L、 二极管VD2、负载形成续流通路。

在正激式变换器中特别注意开关S关断到下个周期开关S导通的时间内要使磁芯剩余的能量得到释放,否则在后续的时间内,该剩余的能量值不断的增加,最后达到磁芯所能承受的极限值而饱和。

反激式拓扑变换器

反激式变换器基本拓扑结构如图所示。在Buck-Boost型变换器中将高频变压器放在电感的位置就有了反激式的电路。反激式变换器设计非常容易,价格低廉,常常用在多路输出的小功率开关电源场合。

当开关管S导通时,电源电压加在初级绕组W1两端,根据N1、N2同名端的关系,绕组W2的高电位在下端,二极管VD1此时不导通。当开关S关断时, 绕组W2的高电位在上端,二极管VD1正向导通,负载获得能量。

推挽式拓扑变换器

推挽式变换器其拓扑结构如图所示。原边开关管S1、S2交替导通,变压器磁芯中的能量能够正常的储存和释放,从而将能量从原边向副边传递。

当开关S1导通,S2关断时,副边绕组二极管VD1导通,负载获得能量。当S2导通,S1关断时,副边二级管VD2导通,负载仍能获得能量。当开关管S1,S2都关断时,电感L通过二极管VD1、VD2和负载形成通路,根据并联分流,负载电流只有一半通过每个二极管,但此时开关管承受的电压均为。,所以为了保证开关管的电压应力不会过大,推挽式变换器用在低压大电流的场合具有一定的优势。

半桥拓扑变换器

半桥变换器其拓扑结构如图所示。一条桥臂由两个电容组成,另一条桥臂由两个功率开关管组成。在电路正常工作时,原边绕组在控制信号整个周期均有电流,磁芯的利用率得到提高。所以半桥变换器用在高电压、大功率的情况下比较有优势。

电容C1和C2容值、型号一致,则每个电容上的电压为。当开关S1导通S2关断时,二极管VD1导通,VD2截止,此时N21绕组向负载传递能量。当开关S1关断,S2导通时,二极管VD2导通,VD截止,此时N22绕组能向负载传递能量,即副边绕组N21和N22交替释放能量。

全桥拓扑变换器

全桥变换器其拓扑结构如图所示。四个开关管组成H桥电路,变压器原变绕组接在桥式电路的负载位置。当开关S1和S4导通,S2和S3关断时,初级绕组的高电位在上端。当开关S2和S3导通,S1和S4关断时,初级绕组的高电位在下端。因此,在一个周期内初绕组流过的电流方向相反,变压器不存在磁芯饱和问题,这也使得全桥变换器的效率和功率密度可以做的很高。全桥变换器的次级绕组带有一个中心抽头,输出采用全波整流的方式,因此适合应用在大功率的条件下。

各类型拓扑比较如下表所示:

隔离式DC-DC拓扑电路的比较

查看原文:https://www.dianyuan.com/eestar/article-8316.html


MCUXpresso IDE下添加新路径下源文件进工程编译的方法

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是MCUXpresso IDE下添加新路径下源文件进工程编译的方法

接着上篇文章 《MCUXpresso IDE下SDK工程导入与workspace管理机制》 接着聊,痞子衡说过不建议从零开始创建新工程项目,最好就是导入一个SDK里的现成项目(尽量跟你最终需求相近,主要是需要的SDK基础驱动都要包含),然后在这个项目基础上修改成自己想要的最终工程。

如果你是一个习惯于IAR或者MDK这种非Eclipse式集成开发环境的用户,你可能会对MCUXpresso IDE下管理工程(主要是在工程里增加源文件)的方式感到不适应。本文痞子衡将为你指明MCUXpresso IDE下增加源文件让你不适应的地方。

一、准备测试环境

上篇文章 《MCUXpresso IDE下SDK工程导入与workspace管理机制》 里我们导入了RT500的一个hello world项目进workspace空间,让我们将这个项目拷贝到如下自定义的路径,然后在MCUXpresso IDE下使用 Import project(s) from file system 方式并且不勾选 Copy projects into workspace 选项去打开自定义路径下的hello world工程。

为简单起见,我们再创建三组源文件:sw_delay1.c/h、sw_delay2.c/.h、sw_delay3.c/.h,我们会用这三组源文件来测试三种不同路径类型下添加源文件进工程的情况。

////////////////sw_delayx.c////////////////
#include "sw_delayx.h"
void sw_delayx(uint32_t n)
{
    while (n != 0U)
    {
        n--;
    }
}

////////////////sw_delayx.h////////////////
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
void sw_delayx(uint32_t n);
#if defined(__cplusplus)
}
#endif

二、已有路径下添加源文件进工程

第一种测试情况最简单,我们直接把sw_delay1.c/h文件放到\mcux_test\evkmimxrt595_hello_world\source\路径下,跟主函数源文件hello_world.c放在一起。当我们将新源文件放到已有路径下时,在MCUXpresso IDE工程里新文件就立刻显示在了界面左上角的workspace里(可以理解为直接被添加进工程了),根本不用你手动添加(这是跟IAR/MDK相比第一个不同的地方,也是你可能不适应的地方),这时候我们可以在主函数文件里直接引用和调用sw_delay1.c/h里的内容,不需要再额外做任何工程设置。

自动刷新工程路径下源文件进工程是Eclipse型IDE的特色,这个特色其实挺好,只有一种情况下不太方便,那就是多个不同源文件中均有相同函数定义(可能是测试目的,或者刻意保留不同版本函数实现),这种情况下在工程编译时会报错,需要在IDE里主动右击你不想添加进工程的源文件,在Properties框里勾选上 Exclude resource from build

三、新路径下添加源文件进工程

3.1 在工程文件所在路径下

现在我们换一种情况,还是在当前工程路径\mcux_test\evkmimxrt595_hello_world下,但是新建一个名为sw_delay2的文件夹,并且将sw_delay2.c/h文件放到\mcux_test\evkmimxrt595_hello_world\sw_delay2\路径下。因为有了新路径,此时还需要在工程Properties选项的MCU C Compiler / Includes里(最好在MCU Assembler / General 里也同样设置)将该新路径添加进去。

此时新文件夹sw_delay2及其中源文件好像同样被自动更新到了工程workspace中,我们试试在主函数源文件中调用sw_delay2(),并编译工程。很遗憾,工程编译报错,提示undefined reference to `sw_delay2',就是找不到sw_delay2()函数,这是为什么?

这里要介绍第二个让你不适应的地方,那就是工程文件所在路径下的新建文件夹看起来被自动更新显示到工程workspace中了,但其实其中源文件并没有真正被添加进工程,还需要你手动做一次路径添加,在工程Properties选项的C/C++ General的Paths and Symbols下做如下操作。做完之后,你可以在workspace里看到此时sw_delay2文件夹被提到了Debug上面显示(在SDK工程里,Debug和doc文件夹一般显示在最下面,这两个并没有被真正添加进工程源文件路径,凡是显示在它们后面的文件夹都是没有被真正加入工程的),现在工程可以正常编译了。

3.2 非工程文件所在路径下

最后介绍一种最复杂的情况,这次不在工程路径\mcux_test\evkmimxrt595_hello_world下做文章,我们在\mcux_test\路径下新建一个名为sw_delay3的文件夹,并且将sw_delay3.c/h文件放到\mcux_test\sw_delay3\路径下。因为这个新路径跟工程路径不相关,因此工程workspace没有自动显示它,此时当然需要我们手动来添加这个文件夹进工程。右击工程选择 New / Folder,使用Folder选项里Advanced下面的 Link to alternate location 功能将sw_delay3文件夹及其源文件添加进工程。

此时工程workspace中已经显示了sw_delay3文件夹,但是显示在最下面(Debug和doc之后),这时候我们可以当sw_delay3文件夹刚刚被放到\mcux_test\evkmimxrt595_hello_world\下面一样,按3.1节里的方法走一遍,MCU C Compiler / Includes和C/C++ General - Paths and Symbols下都分别再设置一下。

这里有第三个让你不适应的地方,非工程文件所在路径下的源文件夹在被强制链到工程里时,其Include路径直接转变成了当前工程路径/${ProjName}/下,并不需要像IAR/MDK那样使用 ../ 去回退寻找具体的相对路径。

至此,MCUXpresso IDE下添加新路径下源文件进工程编译的方法痞子衡便介绍完毕了,掌声在哪里~~~

查看原文:https://www.dianyuan.com/eestar/article-8340.html


OTFAD加密启动失败?先去检查系统时钟配置

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败问题

我们知道,i.MXRT1xxx家族早期型号(RT1050/RT0160/RT1020)的硬件解密外设名字叫BEE,这个外设主要是配合FlexSPI外设去实现外接串行NOR Flash在线解密XIP执行用的。而到了最近的i.MXRT1xxx新型号(RT1010/RT1170)上,BEE外设被替换成了OTFAD外设,功能不变,解密效率得到了很大提升,但客户在使能OTFAD加密启动时常常遇到App无法正常运行问题,这其实跟OTFAD自身的一个时钟小限制有关(这个限制在BEE上不存在),今天痞子衡就来好好聊一聊OTFAD的这个小限制:

一、问题描述

我们以i.MXRT1010为例,从恩智浦官网下载一个SDK包(痞子衡下的是v2.9.1),随便选择其中一个例程,就以最简单的 \SDK\boards\evkmimxrt1010\demo_apps\led_blinky 为例吧。编译这个 led_blinky 工程(选择 flexspi_nor_debug build,即XIP工程),得到可执行文件(实际bin文件大小为10KB左右),使用 NXP-MCUBootUtility 工具将可执行文件(led_blinky.out)下载进MIMXRT1010-EVK开发板中(下载时启动模式为2'b01,启动时切换到2'b10),可以看到板载绿色LED小灯(D25)会闪,例程是可以正常工作的。

现在让我们尝试使能OTFAD加密,回到芯片下载模式依然借助 NXP-MCUBootUtility 工具,将工具 Secure boot type 选项切换为 OTFAD Encrypted Image Boot,其他设置均默认(此时加密范围是 0x60001000 - 0x60001fff,仅加密IVT等启动头,不含app),再次下载可执行文件(led_blinky.out),换到芯片启动模式复位板子,例程依旧是正常工作的,看起来OTFAD加密启动似乎没有问题。

让我们再进一步,将加密范围设置为0x60002000 - 0x60004fff,这时加密区域覆盖到了整个app,重新按上述流程操作一遍,发现例程没能正常工作,这时候OTFAD加密启动出了问题,难道app区域不能被加密?那OTFAD加密还有啥意义?

app区域当然可以被加密,跟着痞子衡再做一次实验,在 led_blinky.c 文件的 main() 函数中,我们将时钟配置函数 BOARD_BootClockRUN() 直接注释掉或者在链接文件里将其全部搞成 __ramfunc(即在芯片内部RAM里执行这部分时钟配置代码),这个例程仅是利用SysTick定时翻转GPIO,因此时钟配置代码去掉不影响正常运行,重新编译工程再按上面流程操作一遍,这时候例程又能正常工作了,说明加密后的app是能被OTFAD正常解密执行的。

现在的问题变成了为何OTFAD加密启动时,BOARD_BootClockRUN() 函数不能在Flash里执行,这就是问题所在。

二、原因分析

关于上述问题的原因,痞子衡先直接给答案,这是OTFAD外设本身的时钟小限制,当OTFAD被使能时,如果被加密的app代码是XIP执行,app里做系统时钟配置时要始终保证Core时钟高于FlexSPI外设时钟。如果Core时钟低于FlexSPI时钟,此时Core去访问加密Flash区域,OTFAD无法正常解密,会导致指令错乱,发生系统故障。

我们配合上面的i.MXRT1010系统时钟树来认真分析下OTFAD这个时钟限制问题。芯片上电总是从BootROM执行,BootROM会先将Core配置到396MHz,将FlexSPI时钟根据用户放置在Flash偏移0x400处的FDCB里的设定配到30MHz - 200MHz不等,再读取Flash偏移0地址处OTFAD DEK KeyBlob数据使能OTFAD,然后读取IVT等头信息去跳转到App。很显然只加密IVT部分根本不受OTFAD限制的影响,这部分解析是在BootROM里完成的,BootROM里时钟配置符合OTFAD时钟限制要求。

// BootROM里对Core时钟配置
CCM_ANALOG->PFD_528[PFD3_FRAC] = 24,   PLL2 PFD3输出 (528MHz * 18) / 24 = 396MHz
CCM->CBCMR[PRE_PERIPH_CLK_SEL] = 2,    时钟来自PLL2 PFD3
CCM->CBCDR[PERIPH_CLK_SEL]     = 0,   内核时钟来自CCM->CBCMR[PRE_PERIPH_CLK_SEL]
CCM->CBCDR[AHB_PODF]           = 0,   内核时钟不分频

// BootROM里对FlexSPI时钟配置
CCM_ANALOG->PFD_480[PFD0_FRAC] = x,    PLL3 PFD0输出 (480MHz * 18) / x
CCM->CSCMR1[FLEXSPI_CLK_SEL]   = 3,    时钟来自PLL3 PFD0
CCM->CSCMR1[FLEXSPI_CLK_SRC]   = 0,   FlexSPI时钟来自CCM->CSCMR1[FLEXSPI_CLK_SEL]
CCM->CSCMR1[FLEXSPI_PODF]      = y,   FlexSPI时钟做(y+1)分频

当BootROM跳转到了App之后,我们再来看看App里对时钟是怎么配置的,就是BOARD_BootClockRUN()函数,可以看到这个函数里将内核频率从BootROM设置的396MHz切换到外部OSC 24MHz。无论此时用户FDCB里对FlexSPI时钟是多少配置,至少也会大于30MHz,那么此时24MHz内核频率一定会低于FlexSPI时钟频率,此时只要发生内核对Flash加密区域的访问(时钟配置代码就在Flash里执行),就触发了OTFAD时钟限制问题,App就会跑飞。

三、解决方案

知道了原因,解决方案就简单了,在App时钟配置里,不要按照寻常套路去先将内核时钟源切换到外部OSC再切到PLL,而是直接切到PLL上。比如i.MXRT1010内部有个PLL6(也叫Audio PLL),固定500MHz,正好是App要的最终内核频率,我们在BOARD_BootClockRUN()里将Audio(Enet) PLL初始化设置代码提到前面,删掉原来的切换OSC设置代码即可。

void BOARD_BootClockRUN(void)
{
    // 此处略去...
    /* Set Oscillator ready counter value. */
    CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127);
-    /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */
-    CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */
-    CLOCK_SetMux(kCLOCK_PeriphMux, 1);     /* Set PERIPH_CLK MUX to PERIPH_CLK2 */

    // 此处略去...
    /* Set IPG_PODF. */
    CLOCK_SetDiv(kCLOCK_IpgDiv, 3);
+     /* Init Enet PLL. */
+    CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN);
+    /* Set preperiph clock source. */
+    CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);

    // 此处略去...
    /* Enable Audio PLL output. */
    CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
-    /* Init Enet PLL. */
-    CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN);
-    /* Set preperiph clock source. */
-    CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);

    // 此处略去...
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
}

最后再提一下,这个OTFAD时钟限制问题在i.MXRT1170上同样存在,解决思路与上面类似,痞子衡就不再赘述了。

至此,系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败问题痞子衡便介绍完毕了,掌声在哪里~~~

查看原文:https://www.dianyuan.com/eestar/article-8335.html


反激拓扑3—CCM模式与DCM模式的边界条件

上期推送对反激电路的工作模式和简单原理计算进行了介绍反激拓扑2—反激电路工作原理分析,文中提到反激电路工作模式分为CCM、CRM和DCM,那么CCM和DCM模式的边界条件是什么?很明显,就是上文中说的CRM即临界模式,我们在同一个图中绘制出三个模式下的励磁电流波形进行分析。

从图中,可知:

①CCM模式下,励磁电流的平均电流存在一个直流分量,其平均电流Im>Im_peak/2,t1+t2+t3=T,t1=ton,t2+t3=toff;

②DCM模式下,励磁电感在每个周期内都可以被完全去磁,其平均电流Im<Im_peak/2,t1+t2+t3=T,t1=ton,t2=toff,t3时间段内,反激变压器的原副边均无电流;

③CRM边界模式下,励磁电感充磁和去磁能量正好相等,其平均电流Im=Im_peak/2,t1+t2+t3=T,t1=ton,t2+t3=toff;

反激变压器初级侧的电流波形如图所示

变压器次级电流波形如图所示


根据电感伏秒平衡定律:

带入上式简化得:

这个就是CCM和DCM的边界条件,其中f为反激电源的开关频率,D为占空比,N为原副边的匝数比,Lm为励磁电感,R为等效负载电阻。有如下结论:CCM模式下:

DCM模式下:

查看原文:https://www.dianyuan.com/eestar/article-8437.html


更多精彩内容,尽在电子星球 APP(https://www.eestar.com/)

六篇技术文章,让你秒懂电容的脾气秉性

七篇DIY技术文章献给你,让你脑洞全开

五篇文章帮你开启DSP的学习思路

汇总篇:关于PID知识,重点在此

相关推荐

前端入门——css 网格轨道详细介绍

上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...

Islands Architecture(孤岛架构)在携程新版首页的实践

一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...

HTML中script标签中的那些属性

HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...

CSS 中各种居中你真的玩明白了么

页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...

CSS样式更改——列表、表格和轮廓

上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...

一文吃透 CSS Flex 布局

原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...

css实现多行文本的展开收起

背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...

css 垂直居中的几种实现方式

前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...

WordPress固定链接设置

WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...

面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿

前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...

3种CSS清除浮动的方法

今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...

2025 年 CSS 终于要支持强大的自定义函数了?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...

css3属性(transform)的一个css3动画小应用

闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...

CSS基础知识(七)CSS背景

一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...

CSS 水平居中方式二

<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...

取消回复欢迎 发表评论: