精华内容
下载资源
问答
  • LED 驱动 电路原理

    2011-09-04 20:50:57
    LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED驱动电路原理LED...
  • 开发环境: 开发板:STM32PZ6806L 芯片:ARM_STM32F103_ZE 软件开发环境:KEIL5开发所需资料:STM32F1XX芯片电路原理图 STM32F1XX系列芯片手册XX...第一步,分析电路原理图首先第一步打开STM32F1XX芯片的电路原理...

    开发环境:

         开发板:STM32PZ6806L
           芯片:ARM_STM32F103_ZE
    软件开发环境:KEIL5

    开发所需资料:

    STM32F1XX芯片电路原理图
    STM32F1XX系列芯片手册

    XX代表系列版本号,ARM公司开发的芯片大多数都是一样的,除非增加了新功能才会更正芯片手册,XX就代表该文档支持系列版本!

     

    更新 2020.12.17

    如没有这些文档则可以在这里下载:https://jrhar.blog.csdn.net/article/details/111310182

    在上面的链接里找到你开发板的型号,

    本系列使用的是这个架构:

    百度网盘链接:https://pan.baidu.com/s/1rXwt7W3MX3GzF3F4Z0OB8Q 提取码:2ykk

     

    更新 2020.12.23

    stm32f10x系列启动汇编文件:https://download.csdn.net/download/bjbz_cxy/13763212

     

    第一步,分析电路原理图

    首先第一步打开STM32F1XX芯片的电路原理图:

    (图1.0)

    找到LED模块电路的原理图,其次也是看一下这个板子上有没有设计LED电路模块:

    (图1.1)

    找到之后代表该板子已经设计了LED电路模块,那么放大来看一下:

    (图1.2)

    从LED模块电路原理图中可以看到,每个LED(LED1-LED8)都有一个二极管(D1-D8)连接着

    二极管的两个引脚具有正负极区分,从原理图中可以得知该二极管的正极对应着LED,而负极对应着输入源

    (图1.3)

    所以如果我们想要让LED灯亮起,首先要经过连接在LED上的二极管,所以我们要让该二极管工作,从输入源里输入一个低电平,即可让二极管的负极一端引脚工作,相反输入高电平则二极管的负极一端不会产生任何作用!

    (二极管极性连接识别方法)

    (图1.4)

     

    并且输入源中设有两个排阻,每个排阻中有四个电阻,用于简化PCB板设计

     

    (图1.5)

    但内部电阻作用原理图并没有明确给出,博主推断应该是上拉下拉电阻用于限流作用

    (图1.6)

    除此之外同时又得知该电路模块最大承受电平值为+3.3v(0-3.3v)

    LED模块的电路原理图看懂了,那么就要知道LED模块连接在处理器的哪个总线上!

    为什么需要知道在哪个总线上?

    这里就拿找人打个比喻吧:

    就像找人一样,你知道他是谁,是干什么的,但是你现在想要找到他,是不是要去他家里?

    那么去他家里之前你要知道他家在哪儿,房子编号是多少,有个具体的路线和编号就可以轻而易举的找到他家,并找到他!

    那么接下里我们看一下电路原理图中,CPU这一块的连接电路原理图:

    (图1.7)

    放大一点儿:

    (图1.8)

    (图1.9)

    由此可以看到,每个LED模块(1-8)分别对应着PC特殊功能寄存器(0-7bit位)

    知道LED对应的特殊功能寄存器,那么就要知道该特殊功能寄存器挂设在哪个总线上,映射地址是多少!

    开始查找之前给大家补充一点儿知识:

    什么是特殊功能寄存器?什么是映射地址?

    答:特殊功能寄存器本质上也是一个存储单元和内存里的存储单元没有什么区别,只是内存里的存储单元用于存储单字节数据的,而微型处理器内部的存储单元往往都是4字节或8字节作为一个单元,用于做特殊计算/操作时用到的,比如DS段寄存器用于存储地址,它的大小决定了CPU的寻址能力!CPU会根据DS寄存器里的地址来寻址,再则地址总线位宽也要和DS寄存器一致,假如说地址总线位宽小于DS寄存器那么地址总线将没有能力表示出大于自身的地址!

    什么叫映射地址?

    答:这里做个比喻,假如说你家住某某小区xx栋楼xx号室,那么这个地址就是你房间的地址,每次点外卖或者快递我们一般都会填写这个地址,那么快递员有了这个地址就可以轻而易举的找到我们的房间并把货物递送给我们,这个地址就是你房间的映射,而对特殊功能寄存器的映射如上所说,就是把开发板上的一个物理地址分配给它,就叫做地址映射!

    相关文章:深度理解“CPU内部寻址方式” 详解:物理地址,虚拟地址,内存管理,逻辑地址之间的关系

    言归正传,知道LED模块对应的特殊功能寄存器,我们就可以到STEM32的芯片手册里查看芯片各个寄存器以及地址映射和总线之间的介绍

    打开STM32的芯片手册

    (图2)

    在2.3.30页找到待有对PC特殊功能寄存器总线挂接介绍的原理图:

    (图2.1)

    找到PC特殊功能寄存器:

    (图2.2)

    如上图可以看到PC特殊功能寄存器是由GPIO端口为C的GPIO管脚所连接的,而GPIO端口C挂设到APB2总线上,而APB2挂设在AHB2系统总线上!

    注意这个挂设怎么区分的,首先GPIO端口C实则上是一组GPIO管脚组成的,只不过该管脚负责PC特殊功能寄存器的I/操作,其他GPIO管脚负责其它的特殊功能寄存器,列如PE,PB等,ARM为了加以区分,让开发人员更易读,所以为其进行了区分,也就是成了端口C,端口E,端口G等,分别对应不同的特殊功能寄存器,上面的总结和系统总线的区分打比喻就是一组里有小组的情况一样,每个小组对应不同的功能,但用管理一个组的方式管理所有的小组,而这个组的名字叫做系统总线。

    地址总线,数据总线和控制总线均属于系统总线

    就像人一样,你想要让某个人过来帮你忙,你是不是首先要叫他的名字,他才知道你是在叫他,如果在很多人的情况下,谁也不知道你在叫谁!

    言归正传,那么有了名字要工作是不是要分组?让某一组去做或管理某个事情,形成一个项目体系,所以ARM为其进行了分组,方便于管理,GPIO端口C和其他端口被规划到了APB2总线上,也就是这一组的名字称为APB2,而APB2呢又被规划到了AHB2总线上,所以对应情况是:GPIO端口C和其他端口=APB2而APB2同时也等于AHB2,方便于区分和管理,且形成一个项目体系!

    (图2.3)

    这里从上图中可以知道,PC特殊功能寄存器所使用的总线连接引脚是GPIO,那么我们要查一下关于ARM是如何设计开发板的GPIO引脚的!

    可以通过:STM32 Reference Manual这本开发文档里找到对GPIO引脚的设计,该开发文档对应所有芯片的GPIO引脚设计,除了一些特定的需要重新设计的开发板,因为ARM的系列STM开发板引脚设计所使用的方法都是基于此开发文档的,不会变更,由于文档较大,篇章较多建议下载中文版的:

    可以在8.1里找到对GPIO引脚的设计图:

    (图2.4)

     

    从上图可以看到,STM32所使用的GPIO引脚内部带有保护二极管,用于防止过高过低的不正常电压进入芯片如果电压过高的话保护二极管会被烧掉,因为二极管会首先吸收电压判断电压值是否正确在让其进去芯片,倘若电压过高可能会直接烧掉二极管。

    (图2.5)

    接了两个是因为一个对应输入一个对应输出,GPIO是属于I/O引脚!

    其次还有上拉下拉电阻,用于矫正电平!

    (图2.6)

    为什么有了保护二极管还需要上拉下拉电阻?

    答:不同的模块所使用的电压不同,因为这些模块并非开发板自带的,而是后面焊接上去的,这些模块都是不同的硬件工程师开发的,所以接上上拉下拉电阻,可以把一个不确定的电压矫正成与模块所使用的正常电压!

    其余的我们暂时不看,因为通过这些信息即可得知,我们这发送电压时无需考虑电脑所使用的电压是否与开发板子一直,当然要确定你的电脑电压不能太高!一般来说家用电脑都在3.xv左右,所以这种电压保护二极管是可以完全承受的!

    其次STM32 Reference Manual开发文档中还有对存储器与总线之间的架构图:

    (图2.7)

    从上可以明了的看出总线与存储之间的分组架构:

    (图2.8)

    知道了挂设总线,就像上面打的比喻,知道了名字想要找到他让他帮忙是不是需要知道他家在哪?就算打电话是不是也要知道电话号码?

    那么我们在芯片手册里找一下特殊功能寄存器的映射:

    可以在芯片手册的第4章找到总线映射地址,注意特殊功能寄存器是连接在总线上的,所以也就是总线映射地址:

    (图2.9)

    下面来说一下上面的地址映射介绍

    (图3)

    从该图中可以得出,ARM将地址空间划分为了八块,每块大小为512-Mbyte(MB),名称叫做bloc x以及作用

    从上可以的值,ARM将地址空间划分为了八块,每块大小是512MB,4*512=4G空间,也就是说ARM将4G空间划分为了4块,每块512MB,其作用我们看下图:

    (图3.1)

    从上图的内存映射来看,每块内存大致用途如下:

    (图3.2)

    讲解这些只是为了让大家对ARM的区域划分有个认识,最重要的地方还是地址映射:

    (图3.3)

    右侧ARM将划分四块地址,每块地址的总线名都给写出来了,那么就可以在地址映射表里找到与我们所需要操作的总线名和地址,便可以通过C语言指针方式来操控它,下面是四块内存的地址映射表:

    (图3.4)

    (图3.5)

    根据对图1.9,2.2和2.3,3.1,3.2的分析得出,用于控制LED状态的特殊功能寄存器名字叫做:PC寄存器,而用于连接PC寄存器的GPIO端口为C,且该GPIO挂接在APB2片上外设总线上(外部总线),而APB2挂接在AHB2外设总线上,所以我们要操控PC寄存器就要找到GPIO端口为C的引脚:

    (图3.6)

    放大一点:

    (图3.7)

    从上图中可以得出该组引脚属于:bloc2内存块,且内存偏移地址为:0x40011000-0x400113FF(1024字节也就是1MB的大小)

    (图3.8)

    从电路图以及存储器映射表中已经的值我们需要的操控的LED模块属于哪个特殊功能寄存器控制以及偏移地址是多少,并且知道了连接该特殊功能寄存器挂设在哪个总线上:

    LED模块对应的特殊功能寄存器:PC寄存器
    
    PC寄存器对应的GPIO:GPIO_C
    
    GPIO_C挂设在:APB2外设总线上,且偏移起始地址为:0x40011000-0x400113FF
    
    APB2外设总线挂接在:AHB2系统总线上
    
    AHB2地址空间划分在:bloc2空间中

     

    注意从图2.8中可以看出,AHB总线是由RCC时钟电路控制的:

     

    (图3.9)

    从上图可以看到,凡是挂接在AHB系统总线上的任何总线都由RCC时钟电路控制其状态,下面来详细的解释一下ARM为什么这样做,以及时钟电路的工作原理:

    ARM在总线上架设一个时钟电路的原因主要是为了降低开发板的功耗,起到节能省电的作用,但是同时也给开发人员带来了研究电路原理图和代码量的增长问题,其他的开发板一般都是找到物理地址,发送电平值使其芯片工作,也就写成了一个简单的硬件驱动!

    但ARM对这些地址进行了分组,每组上都有一个时钟电路,包括GPIO每个端口都对应着一个时钟电路,这些时钟电路是根据对应的特殊功能寄存器状态来工作的!

    就比如有一个总线,总线名叫:CBV1,那么这个总线是由一堆GPIO管脚组成的,且这些管脚被分组了,分成GPIO端口C,用于控制LED,GPIO端口为D的用于控制蜂鸣器等。

    (图4.0)

    那么在不工作的情况GPIO端口会不停的向这些芯片发送低电平(取决于二极管极性),就出现了即使这个模块不用但还是一直通电,浪费功耗的情况。

    所以ARM就在每个端口前设置了一个时钟,用于限制电流经过,这些时钟的工作状态取决于对应的特殊功能寄存器,且这个特殊功能寄存器被架设在CBV1的总线上,这些时钟会根据CBV1总线上的特殊功能寄存器状态来工作,架设在CBV1总线上了所以偏移地址也从CBV1的基地址开始算,CBV1的基地址就是所有GPIO端口中地址最低的那个GPIO端口地址!

    那么一个疑问来了,限流也就不让电平通过但是这些电平还是会被发送到时钟电路上啊!

    答:PC寄存器有8个bit位,有GPIO端口C的I/P管脚来控制,那么GPIO端口C总共有8个管脚对应着,GPIO端口向PC寄存器写入某个电平值都会改变LED芯片工作。

    LED芯片会根据特殊功能寄存器来工作,每写入一次寄存器,寄存器里的存储单元就要发生一次变化,那么这样的话所做的操作就需要更多的电流值来变换,相反这样的重复操作每次都无用的,所以ARM想直接给限制掉不写入任何值,这样的话存储单元就无需将新的电平值写入到存储单元当中去了!

    所以我们要想要让LED灯亮起就必须将控制AHB系统总线的RCC时钟电路设置成推送状态,那么我们可以在STM32 Reference Manual开发文档中找到对RCC时钟电路的介绍:

    (图4.1)

    从上图文章栏中可以看到对外设时钟有很多方的介绍,这里我们只查找关于对APB2外设时钟使能寄存器的介绍,也就是6.3.7。

    为什么不看AHB的?

    答:上面说过APB2是挂设在AHB系统总线上的,但ARM在设计时并没有让其和AHB共用同一时钟电路,相反单独为其设置了时钟电路,所以APB2虽然说是挂设在AHB上的,但有自己的时钟电路,无论AHB系统总线的时钟电路开与关都与APB2无关,ARM这样画图只是为了表明APB2挂设在AHB系统总线上的用于分组,当然AHB的时钟电路也有自己的作用:

    下面给大家看一下AHB的时钟电路介绍:

    (图4.2)

    可以看到大多数都是用于控制核心模块工作的,上面的时钟电路对应的特殊功能寄存器位介绍里没有针对GPI/O端口的控制位!

    下面我们来看一下7.3.7对APB2的时钟电路介绍:

    基本介绍:

    (图4.3)

    与电路时钟对应的状态寄存器每个bit位的读写权限介绍:

    (图4.4)

    与电路时钟对应的状态寄存器每个bit位状态介绍:

    (图4.5)

    从上图可以看到与APB2时钟电路对应的特殊功能寄存器的第4个bit位,就是对IO端口C(GPIO_C)时钟电路的控制:

    (图4.6)

    通过上面所知道APB2的地址总线上的时钟电路偏移地址为:0x18,那么就要知道位于APB2总线上的RCC时钟基址是多少!

    通过对图2.2的分析可以得出,GPIO端口C位于APB2总线上的,又通过对图3.6的分析得出,GPIO端口C管脚挂接的地址总线空间被划分到block2上,所以我们可以直接在block2上找到时钟电路的基址:

    (图4.7)

    放大一点儿:

    (图4.8)

    通过基址可以得出APB2的时钟电路物理地址=0x4002100+0x18=0X4002118

    到这步基本上所有的地址都已经分析完毕了,除此之外在实际开发之前还要知道关于对GPIO端口功能的介绍:

    (图4.9)

    并且通过对图2.4的分析:

    (图5.0)

    (图5.1)

    从上图可以得出,该GPIO输入口处可以看到上拉和下拉电阻都接了VDD三极管和VSS三极管用于限制电流经过,所以我们如果要想让电流顺利通过上拉和下拉电阻写入到寄存器里,就必须让VDD开启推挽输出(推挽输出:推挽放大器电路中,一只三极管工作在导通、放大状态时,另一只三极管处于截止状态,当输入信号变化到另一个半周后,原先导通、放大的三极管进入截止,而原先截止的三极管进入导通、放大状态,两只三极管在不断地交替导通放大和截止变化,所以称为推挽放大器,一般用于低功耗输出大功率电路中。),否则就会变成如下情况:

    (图5.2)

    也就是变成了不导通状况,不让电流经过,如果想要让电流经过的话这时候就需要去查看关于对GPIO端口的特殊功能寄存器介绍了:

    在8.2章节可以找到对GPIO端口寄存器的介绍:

     

    ,ARM为每个端口设置了7个寄存器用于控制端口状态!

    可以在8.2文章看到:

    对GPIOX端口寄存器的各个介绍(X为端口号)

    下面我们来看一下:

    (图5.3)

    在8.2中可以找到对GPIO端口I/O介绍,我们找到对应的状态寄存器你并开启推挽输出,让其某一个三极管变成放大状态,这样的话我们就可以顺利让电流经过VDD了!

    注意STM32中的推挽输出只需要设置一个bit位即可,上面介绍也说了。推挽输出时的三极管一个工作则另外一个就会不导通,另外一个不导通则另一个就会工作!

    下面我们来看一下下GPIO的工作方法:

    (图5.4)

    GPIOX表示任意端口号,而后面的

    X表示端口多少到端口多少,上面的为X=A..E说明GPIOA-GPIOE的端口均设有该寄存器!

    CBFy其中的y代表相应的管脚号,也就是我们要操控的端口上的引脚号

    (图5.5)

    并且也详细介绍了寄存器上每个位的功能:

    (图5.6)

    大家通过上方的位介绍可以看出,每个位是以4bit做分割的:

    (图5.7)

    这里解释一下:

    3:2这里想表达的是0,1,2,3这组bit位,而7:6实则上表达的是:4,5,6,7这组bit位,所以算出来每组相差为4个bit位,ARM编写开发文档时只是将高位标了出来,低位并没有写出来,这是一个容易令人迷惑的区域!

    并且通过介绍可以看到:

    (图5.8)

    设置寄存器的第1:0个bit位来确定GPIO的输入输出状态!

    并且下面也有不同的bit位设置不同的状态,一般来说虽然说有四个bit位做一组,但实则上我们一般只用到低位!

    (图5.9)

    继续分析下一个寄存器

    (图6.0)

    对BSRR寄存器分析一下

    (图6.1)

    其意思是低0-15位设置1则向对应的寄存器发送一个高电平(ODRy)(y为对应位,ODR为寄存器),16-31位设置1则向对应寄存器发送一个低电平(ODRy)(y为对应位,ODR为寄存器)!

    在说明白点:假如:ODR是PC寄存器,而GPIOC对应着,我们向GPIOC端口的BSRR寄存器的高16位写入一个高电平(1)那么GPIOC就会向PC寄存器发送一个低电平,低位发送一个高电平(1),则向PC寄存器发送一个高电平,对应位分别是BSRR16+偏移量!

    比如向PC0发送一个低电平(根据贴片二极管极性),让第一个LED灯点亮,那么就是向BSRR寄存器的高第16位+0写入一个高电平(1)即可

    如果让其熄灭即向BSRR的低位0位写入一个高电平(1)即可

    按上面所说的,如果想让第二个LED灯点亮,那么就是向BSRR寄存器的高16+1位写入一个高电平即可

    如果想让其熄灭即向低位的0+1位写一个高电平即可

    其他寄存器我们就暂时不分析,因为暂时用不到!

    有了这些信息就可以开始实践动手开发了!

     

    首先编写代码之前,我们打开kile5创建一个新的工程文件:

    (图6.2)

    (图6.3)

    这里我保存到c盘test_led目录下,工程文件也叫led

    (图6.4)

    然后在弹出的CPU型号选择框里,选择与开发板对应的CPU型号

    (图6.5)

    (图6.6)

    (图6.7)

    选择完之后会弹出说明手册,直接跳过

    (图6.8)

    增加新的工程文件

    (图6.9)

    (图7.0)

    添加新的工程文件完成之后我们配置一下kile5的魔术棒选项,让其生成二进制文件(hex),以便于烧录到开发板中,注意:我们使用的开发板是裸板,里面没有任何操作系统,所以必须生成纯二进制文件,才能让其CPU正确解析里面的二进制指令,像EXE这样的可执行文件格式中分为:头信息区和数据区,其中当我们运行EXE文件时操作系统会自动将头信息区的数据分离开,只留下数据区给CPU这样才避免了无法执行的指令问题!

    (图7.1)

    (图7.2)

    除此之外也别忘记将stm官方提供的启动汇编文件添加进来一并编译,否则无法正常编译和运行:

    (图7.3)

    启动汇编文件中其他代码无需关系,这里我们看一下第149行开始中有非常关键的代码:

    (图7.4)

     

     

     

    学过汇编的应该很容易看出来,下面来解释一下:

     

    第 149 行是定义了一个子程序: Reset_Handler。 PROC 是子程序定义伪指

    令。这里就相当于 C 语言里定义了一个函数,函数名为 Reset_Handler。
    第 150 行 EXPORT 表示 Reset_Handler 这个子程序可供其他模块调用。 相当于 C 语言的函数声明。关键字[WEAK] 表示弱定义,如果编译器发现在别处定

    义了同名的函数,则在链接时用别处的地址进行链接,如果其它地方没有定义,编译器也不报错,以此处地址进行链接,如果不理解 WEAK,那就忽略它好了。第 151 行和第 152 行 IMPORT 说明 __main 和 SystemInit 这两个标号在其

    他文件,在链接的时候需要到其他文件去寻找。相当于 C 语言中,从其它文件引入函数声明。以便下面对外部函数进行调用。

    SystemInit 需要由我们自己实现,即我们要编写一个具有该名称的函数,用来初始化 STM32 芯片的时钟,一般包括初始化 AHB、 APB 等各总线的时钟,需要经过一系列的配置 STM32 才能达到稳定运行的状态。__main 其实不是我们定义的(不要与 C 语言中的 main 函数混淆),当编译器编译时,只要遇到这个标号就会定义这个函数,该函数的主要功能是:负责初始化栈、堆,配置系统环境,准备好 C 语言并在最后跳转到用户自定义的 main 函数,从此来到 C 的世界。

    第 153 行把 SystemInit 的地址加载到寄存器 R0。

    第 154 行程序跳转到 R0 中的地址执行程序,即执行 SystemInit 函数的内容。

    第 155 行把__main 的地址加载到寄存器 R0。

    第 156 行程序跳转到 R0 中的地址执行程序,即执行__main 函数,执行完毕之后即可进入 main 函数。

    第 157 行表示子程序的结束。

    总之,看完这段代码后,了解到如下内容即可:我们需要在外部定义一个SystemInit 函数设置 STM32 的时钟; STM32 上电后,会执行 SystemInit 函数,最后执行我们 C 语言中的 main 函数。

    创建好工程文件之后就可以开始编写代码了:

    首先第一步根据已经得知的地址信息来定义地址:

    首先通过对图3.3的分析得知,GPIOC被划分到block_2的地址空间里去了,所以我们要先将基址定义出来:

    (图7.5)

    存储空间中地址为最小的那个就是存储空间的首地址/基址:

    (图7.6)

    即0x40000000,那么我们将其定义出来,后面定义地址只要在block2空间上的直接用基址加上偏移地址即可,方便于后期管理!

    这里是以无符号整形的方式定义它,明确告诉编译器这个值不是负数,只能是整数!

    //定义电路地址
    #define BLOCK_2 (unsigned int)0x40000000		//BLOCK_2基址
    

    那么在继续定义我们所需要的APB2的基址,通过对图1.8和图2.2的分析

    (图7.7)

    (图7.8)

    可以得知LED模块对应在PC寄存器上的,而PC寄存器对应在GPIO端口C上的,GPIO_C这组引脚属于APB2总线,所以我们在这里定义一个GPIO_C的总线地址:

    (图7.9)

    所以定义如下地址:

    #define BLOCK_2_APB2_GPIO_C	(BLOCK_2+0x11000)	//APB2总线上GPIO_C引脚基址

    除此根据对图5.3的分析知道CRL寄存器是控制GPIO端口的推送状态

    (图8.0)

    偏移地址为0x00所以我们定义出来

     

    //定义GPIOC寄存器的偏移地址
    #define BLOCK_2_GPIOC_CRL 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x00)

    注意这里一定要用*(usigned int*)指针的方式来定义,否则编译器会把这个宏看成常量,常量是不能作为左值运算的,所以我们以指针的方式修饰它,并在前面加上解引用,显示的告诉编译器这个常量为一个地址,如果不在前面加上*解引用的话编译器还是会把这个值看成一个常量地址,所以对其解引用就是访问这个地址空间!

    这里我要讲一下啊,为什么第一行定义block2空间的基址不用以指针的方式定义它而是以整形的方式?

    答:如果你把基址以指针的方式修饰它的话,那么当我们根据基址+偏移量时编译器就会这样做:

    将基址空间里的值取出来然后加上偏移地址,而非让基址+偏移地址,所以这里不要搞混淆了!

     

    上面也说了,如果想要控制GPIO端口发送高低电平就需要设置BSRR寄存器,我们根据偏移地址将其定义出来:

    (图8.1)

    #define BLOCK_2_GPIOC_BSRR 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x10)//GPIO_BSRR寄存器

     

    除此之外,还要开启APB2时钟电路,通过对图4.3,和图4.7的分析得知时钟电路的基址是:0x40021000

     

    (图8.2)

    偏移地址是:

    (图8.3)

    所以我们定义一下基址:

    #define BLOCK_2_RCC_BASE 		 (BLOCK_2 + 0x21000)	//bloc时钟电路基址

    在定义一下APB2时钟基址:

    #define BLOCK_2_RCC_APB2 		 *(unsigned int*)(BLOCK_2_RCC_BASE+0x18)	//APB2时钟电路基址

    完整代码:

    //定义电路地址
    #define BLOCK_2 (unsigned int)0x40000000		//BLOCK_2基址
    #define BLOCK_2_APB2_GPIO_C	(BLOCK_2+0x11000)	//APB2总线上GPIOC_引脚端口
    #define BLOCK_2_GPIOC_CRL 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x00)	//GPIO_CRL寄存器
    #define BLOCK_2_GPIOC_BSRR 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x10)//GPIO_BSRR寄存器
    #define BLOCK_2_RCC_BASE 		 (BLOCK_2 + 0x21000)	//APB2时钟电路基址
    #define BLOCK_2_RCC_APB2 		 *(unsigned int*)(BLOCK_2_RCC_BASE+0x18)	//APB2时钟电路基址

    地址定义好了,那么就可以开始编写实际代码了:

    第一步先开启时钟:

    通过对图4.6的分析

    (图8.4)

    可以得出对位4发送一个高电平(1)即可让时钟开启:

    BLOCK_2_RCC_APB2 |= 1 << 4;	//开启时钟电路

     

    这里一定要用|运算,如果你不知道的话可以查看这篇文章:按位运算操作符底层实现原理

     

    位移就是将1从低位开始移动四个位,并将第四位的值|运算上这个1!

    然后在设置GPIO_C管脚为推送状态:

    (图8.5)

    BLOCK_2_GPIOC_CRL |= (2 << 4 * 0);	//设置GPIO_C端口为推送状态

    这里2转化为二进制就是10,左移4*0个上面也说了bit位的分组是按4个bit位为一组管理一个引脚,写入时都按低位开始写入,所以公式得出:4*0 = 0也就是从第一组的低0位开始写入,如果你要写入第二个的话4*1即可从第二组的低位开始写入!

    这里要说一些为什么设置成复用功能推挽输出模式而不是通用推挽输出模式:

    GPIO端口复用电路:用以提高主控芯片的GPIO端口的利用率,使得能够利用有限的GPIO端口实现更多的功能,节省GPIO端口资源。

    GPIO端口通用电路:常规输入输出

    那么如果想要让灯亮起来的话需要向LED模块发送一个低电平(根据极性),所以我们只需要向BSRR寄存器的高位+PC偏移量写入一个高电平,那么GPIO端口就会向LED模块的对应位发送一个低电平!

    BLOCK_2_GPIOC_BSRR= (1 << (16 + 0));	//发送一个低电平

    这里我们要第一个LED灯亮起来,所以就是16+0第0个,如果想要让第二个亮起那么就是16+1!

    并且在main函数之前声明定义SystemInit函数,用于STM32启动文件的初始化:

    void SystemInit()
    {
    	
    }

    完整代码:

    //定义电路地址
    #define BLOCK_2 (unsigned int)0x40000000		//BLOCK_2基址
    #define BLOCK_2_APB2_GPIO_C	(BLOCK_2+0x11000)	//APB2总线上GPIOC_引脚端口
    #define BLOCK_2_GPIOC_CRL 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x00)	//GPIO_CRL寄存器
    #define BLOCK_2_GPIOC_BSRR 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x10)//GPIO_BSRR寄存器
    #define BLOCK_2_RCC_BASE 		 (BLOCK_2 + 0x21000)	//APB2时钟电路基址
    #define BLOCK_2_RCC_APB2 		 *(unsigned int*)(BLOCK_2_RCC_BASE+0x18)	//APB2时钟电路基址
    //stm32初始化函数
    void SystemInit()
    {
    
    }
    int main(){
    	BLOCK_2_RCC_APB2 |= 1 << 4;	//开启时钟电路
    	BLOCK_2_GPIOC_CRL |= (2 << 4 * 0);	//设置GPIO_C端口为推送状态
    	BLOCK_2_GPIOC_BSRR = (1 << (16 + 0));	//向PC0发送一个低电平
    }

    我们点击编译生成来看一下是否有问题:

    (图8.6)

    编译结果:

    (图8.7)

    正常编译通过,到编译目录下看一下是否生成了hex文件:

    最后在通过stm官方提供的烧录软件,将其hex程序烧录进去:

    选择好我们开发板的通讯串口:

    (图8.8)

    在点程序下载:

    (图8.9)

    这里我们无需管程序会被下载到哪儿,因为在上面也说过:

     

    0x0800 0000-0x0807 FFFF:片内 FLASH,这一块内存会存放我们烧录的程序,而CPU通电就会执行这块内存的指令,其烧录软件已经帮我们指定好了无需手动指定!

    运行结果:

    (图9.0)

    成功让其亮起来了,那么在动动手让其闪烁

    首先我们声明一个函数并实现它:

    函数名为:

    void sleep(int time);

    无返回值,用于循环延时:

    实现代码:

    //延迟函数
    void sleep(int time){
    	while (time--);	//递减,while循环不为0循环继续,当time为0时循环结束
    }

    在修改main函数代码:

    BLOCK_2_RCC_APB2 |= 1 << 4;	//开启时钟电路
    	BLOCK_2_GPIOC_CRL |= (2 << 4 * 0);	//设置GPIO_C端口为推送状态
    	BLOCK_2_GPIOC_BSRR = (1 << (16 + 0));	//设置高位16+0,即向pc0输出一个高电平
    	while (1){	//死循环闪烁
    		BLOCK_2_GPIOC_BSRR = (1 << (16 + 0));	//亮
    		sleep(0xFFFF);
    		BLOCK_2_GPIOC_BSRR = (1 << (0));	//灭
    	}

    在运行时可以看下板子有没有在闪烁:

    (图9.1)

    完整代码:

    //定义电路地址
    #define BLOCK_2 (unsigned int)0x40000000		//BLOCK_2基址
    #define BLOCK_2_APB2_GPIO_C	(BLOCK_2+0x11000)	//APB2总线上GPIOC_引脚端口
    #define BLOCK_2_GPIOC_CRL 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x00)	//GPIO_CRL寄存器
    #define BLOCK_2_GPIOC_BSRR 	 	 *(unsigned int*)(BLOCK_2_APB2_GPIO_C+0x10)//GPIO_BSRR寄存器
    #define BLOCK_2_RCC_BASE 		 (BLOCK_2 + 0x21000)	//APB2时钟电路基址
    #define BLOCK_2_RCC_APB2 		 *(unsigned int*)(BLOCK_2_RCC_BASE+0x18)	//APB2时钟电路基址
    //stm32初始化函数
    void SystemInit()
    {
    
    }
    //延迟函数
    void sleep(int time){
    	while (time--);	//递减,while循环不为0循环继续,当time为0时循环结束
    }
    int main(){
    	BLOCK_2_RCC_APB2 |= 1 << 4;	//开启时钟电路
    	BLOCK_2_GPIOC_CRL |= (2 << 4 * 0);	//设置GPIO_C端口为推送状态
    	BLOCK_2_GPIOC_BSRR = (1 << (16 + 0));	//设置高位16+0,即向pc0输出一个高电平
    	while (1){	//死循环闪烁
    		BLOCK_2_GPIOC_BSRR = (1 << (16 + 0));	//亮
    		sleep(0xFFFF);
    		BLOCK_2_GPIOC_BSRR = (1 << (0));	//灭
    	}
    }

    如果上面有没有说到位,或者电路图分析不到位或者对代码有不理解的地方可以在下面评论区提问出来。

    展开全文
  • 电路原理 的 一些基础知识

    千次阅读 2017-11-15 20:24:26
    电路原理

    电容 与 电感 的 伏安特性

    电感的伏安特性公式:
    这里写图片描述

    电容的伏安特性公式:
    这里写图片描述

    电感 和 电容 元件的串并联

    电感串联:
    这里写图片描述

    电感并联:
    这里写图片描述

    电容串联:
    这里写图片描述

    电容并联:
    这里写图片描述

    RC电路 的 零输入响应 和 零状态响应

    零输入响应:
    这里写图片描述
    这里写图片描述

    零状态响应:
    这里写图片描述
    这里写图片描述

    RLC串联谐振电路

    这里写图片描述

    变压器等效电路

    变压器的初级和次级等效电路:
    这里写图片描述

    展开全文
  • 音频电路原理

    千次阅读 2018-10-25 20:06:12
    音频电路原理 典型音频电路: 双运放  TDA1308 NXP 甲乙类CD专用耳机功放集成电路 低电压、低失真、高速率、强输出等优异的性能芯片内采用MOS管输出, 可以直接推动32Ω耳机。   此类电路在直接采用STM32DAC...

    音频电路原理

    典型音频电路:        双运放 

    TDA1308 NXP 甲乙类CD专用耳机功放集成电路

    低电压、低失真、高速率、强输出等优异的性能芯片内采用MOS管输出, 可以直接推动32Ω耳机。

     

    此类电路在直接采用STM32DAC接TDA1308 缺乏带负载能力,驱动能力偏低。

    可采用独立的DA或者采用74HC4052扩流。

    74HC4052带有公共使能输入控制的2路 4选1模拟开关电路。 2路输入选择输出端口

     

    CF的作用:相位补偿,防止振荡,抑制高频噪声。

    Why? 一般来说,因为布线的寄生电容,使得运放的输入端都会有一个10~20pF的寄生电容,如图CIN(我们暂且将它称为输入电容)。正是这个输入电容,会使得运放的高频噪声增益很大,从而有可能使系统不稳定。

    我们的输入信号一般为直流信号或低频信号,这个电容此时不会起作用,因而此时的增益为-R2/R1。 引发系统不稳定的是高频噪声,所以我们可以暂且抛开信号增益,只讨论电路的噪声增益。该网络的反馈系数是R1/(R1+R2),因而噪声增益为(R1+R2)/R1 (这里我也不是很明白,欢迎大伙补充说明)。 当噪声的频率比较高的时候,则需要考虑输入电容CIN对噪声增益的贡献,对于高频噪声来说,R1与CIN为并联关系,因而此时的噪声增益为:[R2+(R1//1/ωCIN)]/(R1//1/ωCIN)。 

    从这个噪声公式可以看出,当噪声频率越高,噪声增益公式的分母越小,噪声增益的值就越大(是不是感觉像是伯德图中零点的作用?),系统就越不容易稳定。 

    How? 引入CF滞后,噪声增益公式变为:[(R2//1/ωCF)+(R1//1/ωCIN)]/(R1//1/ωCIN),当频率ω增大,噪声增益公式中分母减小的同时,分子也在减小,因而噪声增益公式整体就不会随着1/ω的增大而增大。如果从伯德图看来,这里是引入了一个极点。 

    一般要求是R1 X CIN 大于等于 R2 X CF。 

    以上,就是本人对反相输入电路的反馈电阻上并联电容作用的理解,欢迎大伙进行补充。

    MP3

    MP3播放器是利用数字信号处理器DSP来完成处理传输和解码MP3文件的任务的。 DSP掌管播放器的数据传输,设备接口控制,文件解码回放等活动 

    MP3播放器要分几个部分:中央处理器,解码器,存储设备,主机通迅端口,音频解码D/A转换和功放,显示界面和控制键,其中中央处理器和解码器是整个系统的核心,这里的中央处理器我们通常称为主控,它运行MP3的整个控制程序,也称为固件程序,控制MP3各个部件的工作:从存储设备读取数据送到解码器解码,与电脑连接时完成与主机的数据交换,接收控制按键的操作,显示系统运行状态等任务。

    解码器是芯片中的一个硬件模块,它可以直接完成各种格式MP3数据流的解码操作,并输出PCM或IZS格式的数字音频信号。

    主机USB接口是MP3播放机与电脑交换数据的途径。电脑通过该端口操作MP3播放器存储设备中的数据,拷贝、删除、复制文件等操作。   目前最广泛使用的是USB总线,并且遵循微软定义的大容量移动存储协议,将MP3播放机作为主机的一个移动存储设备。

    音频D/A转换是将数字音频信号转换成模拟音频信号,以推动耳机,功放等模拟音响设备。数字音频信号与模拟音频信号的区别在于,数字音频信号是相对模拟音频信号来说的,我们知道声音的本质是波,人所能听到的声音频率在20HZ到20KHZ之间,称为声波,模拟信号对波的表示是连续的函数特性,基本的原理是不同频率和振幅的波叠加在一起。数字音频信号是对模拟信号的一种量化,典型的方法是对时间坐标,按相等的时间间隔做采样,对振幅做量化。单位时间内的采样次数称为采样频率。这样一段声波就可以被数字化后变成一串数值,每个数值对应相应帛样点的振幅值,按顺序将这些数字排列起来就是数字音频信号了。这是A/D转换过程。(模拟 —— 数字) 

    D/A转换过程相反,将连续的数字接采样的时候的频率顺序转换成对应的电压,MP3解码器解码后的信息属于数字音频信号,需要通过D/A转换器变成模拟信号后才能推动功放,被人耳所识别。 

     一般用每秒种音乐所占的比特数据来表示,这个数字越小,压缩程序度就越高,对播放质量的主观感觉因人而异,但大多数人所能接受的数字大约为128Kbps。当然,同一首MP3歌曲,压缩成160Kbps比压缩成96Kbps要好听,但160Kbps却将会占用更多的空间。   

    当我们播放歌曲时,数据被传送到DSP处理,DSP对文件进行解压。下一步,DSP将数据传送到数字----模拟解码器,将二进制数字信息转换成模拟音频信号,然后模拟音频信号控制耳机或扬声器形成音乐。  

     有的播放器还带有小型的前置功放集成电路,在音频信号到达耳机前加强声音效果 。

    音频压缩

    音乐信号中有许多冗余成分,其中包括间隔和一些人耳分辨不出的信息(如混杂在较强背景中的弱信号)。CD声音不经压缩,采用44.1kHz的固定速率采样,可以保证最大动态音乐的良好再现,当然,信息量较少处的数据量也是相同的,因而存在压缩的可能性。音响频宽为20~20kHz(顶级CDPlayer可向下延伸至2Hz)已成为目前的音乐标准。MP3为降低声音失真采取了名为"感官编码技术"的编码算法:编码时先对音频文件进行频谱分析然,然后用过滤器率掉噪音电平,接着通过量化的方式将剩下的每一位打散排列,最后形成具有较高压缩比的MP3文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。虽然他是一种有损压缩,但是它的最大优势是一极小的声音失真换来了较高的压缩比。且现在的MP3采用与杜比AC-3相似的变压缩比率(VBR)压缩技术,采样的压缩比率依音乐中信息多寡,并利用人耳的掩蔽效应来减少冗余数据。

    展开全文
  • MIC电路原理

    2020-09-04 12:29:53
    一、MIC的电路原理                    FET:(场效应管)MIC的主要器件,起到阻抗变换和放大的作用。 C:是一个可以通过膜片...

    一、MIC的电路原理

    MIC的电路原理              

     

     

    FET(场效应管)MIC的主要器件,起到阻抗变换和放大的作用。

    C:是一个可以通过膜片震动而改变电容量的电容,声电转换的主要部件。

    C1,C2:是为了防止射频干扰而设置的,可以分别对两个射频频段的干扰起到抑制作用。C1一般是10PFC2一般是33PF10PF滤波1800Mhz33PF滤波GSM900Mhz

    RL:负载电阻,它的大小决定灵敏度的高低。

    VS:工作电压,MIC提供工作电压。

    CO:隔直电容,信号输出端。

    二、由声信号到电信号的转换:

    由静电学可知,对于平行板电容器,有如下的关系式:

    C=ε·S/L  ①

    即电容的容量与介质的介电常数成正比,与两个极板的面积成正比,与两个极板之间的距离成反比。另外,当一个电容器充有Q量的电荷,那麽电容器两个极板要形成一定的电压,有如下关系式;

    C=Q/V     ②

    对于一个驻极体传声器,内部存在一个由振膜,垫片和极板组成的电容器,因为膜片上充有电荷,并且是一个塑料膜,因此当膜片受到声压强的作用,膜片要产生振动,从而改变了膜片与极板之间的距离,从而改变了电容器两个极板之间的距离,产生了一个Δd的变化,因此由公式①可知,必然要产生一个ΔC的变化,由公式②又知,由于ΔC的变化,充电电荷又是固定不变的,因此必然产生一个ΔV的变化。

    由于这个信号非常微弱,内阻非常高,不能直接使用,因此还要进行阻抗变换和放大。

    FET场效应管是一个电压控制元件,漏极的输出电流受源极与栅极电压的控制。由于电容器的两个极是接到FETS极和G极的,因此相当于FETS极与G极之间加了一个Δv的变化量,FET的漏极电流I就产生一个ΔID的变化量,因此这个电流的变化量就在电阻RL上产生一个ΔVD的变化量,这个电压的变化量就可以通过电容C0输出,这个电压的变化量是由声压引起的,因此整个传声器就完成了一个声电的转换过程。

    三、参数

    MIC在手机上的使用条件,其中包括工作电压,负载电阻。另外在以下情况下还要对MIC的工作电流进行限定,例如有的手机给MIC的供电电压为1.8V,而负载电阻为2.2K,因为Vd=Vsd+Id*R      

    Id = (Vs- Vsd)/ RL

    为了保证MIC中的FET工作在线性工作区,不进入饱和区,应使Vsd0.7V,因此Id(1.8V- 0.7V)/ 2.2K=0.5 mA,因此在这种情况下,选用的FET的电流不能大于500μA

    从下面这个MIC的参数就可以看的出来。

     

    灵敏度

    -43+/-2dB  RL=2.2KΩ  Vs=2.0VDC)(1KHz  0dB=1V/Pa

    输出电阻

    最大2.2KΩ  1KHzRL=2.2KΩ)

    频率

    50-12000Hz

    电流损耗

    最大0.5mA  RL=2.2KΩ  Vs=2.0VDC

    操作电压范围

    1.0V-10VDC

    最大输出声压

    115dB  S.P.L

    信噪比

    58dB  1KHz0dB=1V/Pa

    灵敏度变化

    2.0V-1.5V灵敏度减小3dB

    展开全文
  • 无线路由器电路原理

    热门讨论 2013-12-19 15:02:32
    无线路由器电路原理图,可供一些用的着的朋友参考并使用,无线路由器电路原理
  • 红米K30Pro电路原理图纸 主板+小板 品牌 小米 型号 K30Pro 图纸类型 手机图纸 图纸内容 手机电路图 图纸格式 PDF K30 Pro手机图纸包括: 手机电路原理图 主板75+小板14页; 红米K30Pro手机主板电路原理图纸 ...
  • 电路原理实验八:受控源特性测试

    千次阅读 2017-04-27 00:06:35
    电路原理
  • LC滤波电路原理及设计详解pdf,
  • 清华大学电路原理真题 清华大学电路原理真题 清华大学电路原理真题 清华大学电路原理真题
  • 电路原理 范承志 答案

    热门讨论 2009-03-29 13:36:12
    电路原理 范承志 答案 浙江大学电路原理教科书
  • 斩波电路原理 https://wenku.baidu.com/view/9befaffe910ef12d2af9e76b.html 基本斩波电路 https://wenku.baidu.com/view/097c66c60c22590102029d87.html#
  • 华为荣耀10电路原理

    千次阅读 2020-06-27 11:44:24
    华为荣耀10手机图纸-电路原理图 品牌 华为 型号 荣耀10 图纸类型 手机维修图纸 图纸内容 手机电路图 图纸格式 PDF 其他信息 ...
  • 电路原理 Nilsson英文版第十版 习题详解
  • 开关升压电路原理

    千次阅读 2018-06-01 14:57:07
    开关升压电路原理 假定那个开关(三极管或者mos管)已经断开了很长时间,所有的元件都处于理想状态,电容电压等于输入电压。下面要分充电和放电两个部分来说明这个电路。 充电过程 在充电过程中,开关闭合...
  • 差分放大电路原理

    万次阅读 2019-06-02 16:39:23
    最简单的差分电路原理图如下: 输入共模信号 当ui1和ui2输入共模信号时,这种输入叫做共模输入。两个三极管的基极电压也随着输入信号的变化而变化,由于电路对称,两边的基极电流IB1和IB2也随之变化,并且电流值...
  • 倍压整流电路原理

    2019-09-18 22:53:46
    倍压整流电路原理 转载于:https://my.oschina.net/u/3424406/blog/1922823
  • IPhone6 & 6plus原厂电路原理图纸

    热门讨论 2015-03-29 08:15:21
    IPhone6 plus原厂电路原理图纸
  • 电路原理图分析浅谈

    2019-07-14 14:24:39
    电器修理、电路设计都是要通过分析电路原理图,了解电器的功能和工作原理,才能得心应手开展工作的。作为从事此项工作的同志,首先要有过硬的基本功,要能对有技术参数的电路原理图进行总体了解,能进行划分功能模块,找出...
  • iPhoneXR苹果手机中文电路原理图纸 品牌 苹果iPhone 型号 iPhoneXR 图纸类型手机图纸 图纸内容 电路原理图纸 图纸语言 中文
  • LCD屏电路原理浅析以及RK3288对应的MIPI电路设计 ## 一、 文章描述 本文主要粗略描述下普通的LCD屏相关电路方面的知识。工程师可以通过本文了解到lcd屏相关电路设计原理以及需要注意的部分。 本文主要主要分为以下几...
  • 电话机单元电路原理原理(非常实用),大家下了看看
  • 华为Mate30 4G手机电路原理图纸 品牌 华为Huawei 型号 Mate30 4G 图纸类型 手机图纸 图纸内容 手机电路图 图纸格式 PDF 共57页 原厂图纸 可复制搜索 图纸包含: HU3690V100CS原理图 HI3690V100CS原理图 Hi...
  • 如何学好电路原理

    2018-09-03 17:45:16
    如果你是学电气专业的话,电路原理是最基础最重要的一门课。学不好它,后面的模电、电机、电力系统分析、高压简直没办法学。对于这门课,你要想真正的领悟和掌握,奥秘就在于不能停止 思考。而且我觉得这是最重要的...
  • 谐振电路原理及multisim仿真

    千次阅读 2020-04-11 21:26:28
    谐振电路原理及仿真是什么用来干什么 个人笔记,可能有错 是什么 如果含电容电感的电路端口电压电流同相,呈电阻性,称电路谐振,此时电路中电容的电场能和电感的磁场能相互转换,此消彼长,完全补偿。 关于同相:...
  • 电路原理图(schematic)描述了数字电路内部组件及其相互连接。本文简单介绍一下电路原理图。
  • 单片机复位电路原理分析

    千次阅读 2019-01-04 16:18:55
    单片机复位电路原理分析  复位电路的作用  在上电或复位过程中,控制CPU的复位状态:这段时间内让CPU保持复位状态,而不是一上电或刚复位完毕就工作,防止CPU发出错误的指令、执行错误操作,也可以提高电磁兼容...
  • boost升压电路原理

    千次阅读 多人点赞 2013-12-19 20:29:52
    【转】 boost升压电路原理 2010-05-06 17:15 转载自 youhan001 最终编辑 youhan001  boost升压电路,开关直流升压电路(即所谓的boost或者step-up电路)原理2007-09-29 13:28the boost converter,...
  • arduino mega2560(AD)电路原理图和PCB图

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,354
精华内容 14,941
关键字:

电路原理