历史上的今天
返回首页

历史上的今天

今天是:2024年12月23日(星期一)

正在发生

2020年12月23日 | STM32(二)----寄存器讲解

2020-12-23 来源:eefocus

原理讲解

芯片讲解

STM32F103芯片

我们看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成。若与电脑类比,内核与外设就如同电脑上的 CPU与主板、内存、显卡、硬盘的关系。
STM32F103采用的是 Cortex-M3内核,内核即 CPU,由 ARM公司设计。ARM公司并不生产芯片,而是出售其芯片技术授权。芯片生产厂商(SOC)如 ST、TI、Freescale,负责在内核之外设计部件并生产整个芯片,这些内核之外的部件被称为核外外设或片上外设。如 GPIO、USART(串口)、I2C、SPI等都叫做片上外设。(采用野火官方的介绍)
芯片
芯片(这里指内核,或者叫 CPU)和外设之间通过各种总线连接,其中驱动单元有 4个,被动单元也有 4 个。为了方便理解,我们都可以把驱动单元理解成是CPU 部分,被动单元都理解成外设。下面我们简单介绍下驱动单元和被动单元的各个部件。

  1. ICode总线
    ICode 中的 I 表示 Instruction,即指令。我们写好的程序编译之后都是一条条指令,存放在 FLASH 中,内核要读取这些指令来执行程序就必须通过 ICode 总线,它几乎每时每刻都需要被使用,它是专门用来取指的。

  2. 驱动单元
    DCode 总线
    DCode 中的 D 表示 Data,即数据,那说明这条总线是用来取数的 。我们在写程序的时候,数据有常量和变量两种,常量就是固定不变的,用 C语言中的 const关键字修饰,是放到内部的 FLASH 当中的,变量是可变的,不管是全局变量还是局部变量都放在内部的SRAM。因为数据可以被 Dcode总线和 DMA总线访问,所以为了避免访问冲突,在取数的时候需要经过一个总线矩阵来仲裁,决定哪个总线在取数。
    系统总线
    系统总线主要是访问外设的寄存器,我们通常说的寄存器编程,即读写寄存器都是通过这根系统总线来完成的。
    DMA 总线
    DMA 总线也主要是用来传输数据,这个数据可以是在某个外设的数据寄存器,可以在SRAM,可以在内部的 FLASH。因为数据可以被 Dcode 总线和 DMA 总线访问,所以为了避免访问冲突,在取数的时候需要经过一个总线矩阵来仲裁,决定哪个总线在取数。

  3. 被动单元
    内部的闪存存储器
    内部的闪存存储器即 FLASH,我们编写好的程序就放在这个地方。内核通过 ICode 总线来取里面的指令。
    内部的 SRAM
    内部的 SRAM,即我们通常说的 RAM,程序的变量,堆栈等的开销都是基于内部的SRAM。内核通过DCode总线来访问它。
    FSMC
    FSMC 的英文全称是 Flexible static memory controller,叫灵活的静态的存储器控制器是 STM32F10xx 中一个很有特色的外设,通过 FSMC,我们可以扩展内存,如外部的SRAM,NANDFLASH 和 NORFLASH。但有一点我们要注意的是,FSMC 只能扩展静态的内存,即名称里面的 S:static,不能是动态的内存,比如 SDRAM就不能扩展。
    AHB 到 到 APB 的桥
    从 AHB 总线延伸出来的两条 APB2 和 APB1 总线,上面挂载着 STM32 各种各样的特色外设。我们经常说的GPIO、串口、I2C、SPI这些外设就挂载在这两条总线上,这个是我们学习 STM32 的重点,就是要学会编程这些外设去驱动外部的各种设备。
    STM32F10x系统框图.png?imageView2/2/w/550

存储器映射

被控单元的FLASH,RAM,FSMC和AHB到APB的桥(即片上外设),这些功能部件共同排列在一个 4GB 的地址空间内。我们在编程的时候,可以通过他们的地址找到他们,然后来操作他们(通过 C 语言对它们进行数据的读和写)。

存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射。如果给存储器再分配一个地址就叫存储器重映射。
在这里插入图片描述
存储器区域功能划分
在这 4GB 的地址空间中,ARM 已经粗线条的平均分成了 8 个块,每块 512MB,每个块也都规定了用途,每个块的大小都有 512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。
存储器分类
在这 8个Block里面,有 3个块非常重要,也是我们最关心的三个块。Block0用来设计成内部 FLASH,Block1 用来设计成内部 RAM,Block2 用来设计成片上的外设,下面我们简单的介绍下这三个 Block 里面的具体区域的功能划分。

  1. 存储器 Block0 内部区域功能划分
    Block0 主要用于设计片内的 FLASH,STM32F103ZET6和STM32F103VET6的 FLASH 都是 512KB,属于大容量。要在芯片内部集成更大的 FLASH或者 SRAM都意味着芯片成本的增加,往往片内集成的 FLASH都不会太大,ST能在追求性价比的同时做到512KB,实乃良心之举。

  2. 存储器 Block1 内部区域功能划分
    Block1 用 于 设 计 片 内 的 SRAM 。 STM32F103ZET6 和STM32F103VET6的 SRAM 都是 64KB。

  3. 存储器 Block2 内部区域功能划分
    Block1 用 于 设 计 片 内 的 SRAM 。STM32F103ZET6 和STM32F103VET6的 SRAM 都是 64KB。

寄存器映射

我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射。
在存储器 Block2这块区域,设计的是片上外设,它们以四个字节为一个单元,共 32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
比如,我们找到 GPIOB 端口的输出数据寄存器 ODR 的地址是 0x4001 0C0C(至于这个地址如何找到可以先跳过,后面我们会有详细的讲解),ODR 寄存器是 32bit,低 16bit有效,对应着 16 个外部 IO,写 0/1 对应的的 IO 则输出低/高电平。现在我们通过 C 语言指针的操作方式,让 GPIOB 的 16 个 IO都输出高电平。

// GPIOB 端口全部输出 高电平

 *(unsigned int*)(0x4001 0C0C) = 0xFFFF;


0x4001 0C0C在我们看来是 GPIOB端口ODR的地址,但是在编译器看来,这只是一个普通的变量,是一个立即数,要想让编译器也认为是指针,我们得进行强制类型转换,把它转换成指针,即(unsigned int *)0x4001 0C0C,然后再对这个指针进行 * 操作。

刚刚我们说了,通过绝对地址访问内存单元不好记忆且容易出错,我们可以通过寄存器的方式来操作。


 // GPIOB 端口全部输出 高电平

 #define GPIOB_ODR (unsigned int*)(GPIOB_BASE+0x0C)

 * GPIOB_ODR = 0xFF;


为了方便操作,我们干脆把指针操作“*”也定义到寄存器别名里面


 // GPIOB 端口全部输出 高电平

 #define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C)

 GPIOB_ODR = 0xFF;


STM32的外设地址映射

片上外设区分为三条总线,根据外设速度的不同,不同总线挂载着不同的外设,APB1挂载低速外设,APB2 和 AHB 挂载高速外设。相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外设的地址。其中 APB1 总线的地址最低,片上外设从这里开始,也叫外设基地址。


  1. 总线基地址

总线名称总线基地址相对外设基地址的偏移
APB10x4000 00000x0
APB20x4001 00000x0001 0000
AHB0x4001 80000x0001 8000
  1. 外设基地址
    总线上挂载着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为“XX外设基地址”,也叫 XX外设的边界地址。具体有关 STM32F10xx外设的边界地址请参考《STM32F10xx 参考手册》的 2.3 小节的存储器映射的表 1:STM32F10xx 寄存器边界地址。
    这里面我们以 GPIO 这个外设来讲解外设的基地址,GPIO 属于高速的外设 ,挂载到APB2总线上.
    d

  2. 外设寄存器
    在 XX 外设的地址范围内,分布着的就是该外设的寄存器。以 GPIO 外设为例,GPIO是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,基本功能是控制引脚输出高电平或者低电平。最简单的应用就是把 GPIO 的引脚连接到 LED 灯的阴极,LED 灯的阳极接电源,然后通过 STM32控制该引脚的电平,从而实现控制 LED 灯的亮灭。
    GPIO 有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节,在该外设的基地址上按照顺序排列,寄存器的位置都以相对该外设基地址的偏移地址来描述。这里我们以 GPIOB 端口为例,来说明 GPIO 都有哪些寄存器.

    有关外设的寄存器说明可参考《STM32F10xx 参考手册》中具体章节的寄存器描述部分,在编程的时候我们需要反复的查阅外设的寄存器说明。
    这里我们以“GPIO 端口置位/复位寄存器”为例,教大家如何理解寄存器的说明.

    ①名称
    寄存器说明中首先列出了该寄存器中的名称,“(GPIOx_BSRR)(x=A…E)”这段的意思是该寄存器名为“GPIOx_BSRR”其中的“x”可以为 A-E,也就是说这个寄存器说明适用于 GPIOA、GPIOB至 GPIOE,这些 GPIO端口都有这样的一个寄存器。
    ②偏移地址
    偏移地址是指本寄存器相对于这个外设的基地址的偏移。本寄存器的偏移地址是 0x18,从参考手册中我们可以查到 GPIOA外设的基地址为 0x4001 0800 ,我们就可以算出 GPIOA的这个 GPIOA_BSRR 寄存器的地址为:0x4001 0800+0x18 ;同理,由于 GPIOB 的外设基地址为 0x4001 0C00,可算出 GPIOB_BSRR 寄存器的地址为:0x4001 0C00+0x18 。其他GPIO端口以此类推即可。
    ③寄存器位表
    紧接着的是本寄存器的位表,表中列出它的 0-31 位的名称及权限。表上方的数字为位编号,中间为位名称,最下方为读写权限,其中w表示只写,r表示只读,rw表示可读写。本寄存器中的位权限都是 w,所以只能写,如果读本寄存器,是无法保证读取到它真正内容的。而有的寄存器位只读,一般是用于表示 STM32 外设的某种工作状态的,由 STM32硬件自动更改,程序通过读取那些寄存器位来判断外设的工作状态。
    ④位功能说明
    位功能是寄存器说明中最重要的部分,它详细介绍了寄存器每一个位的功能。例如本寄存器中有两种寄存器位,分别为 BRy及 BSy,其中的 y数值可以是 0-15,这里的 0-15表示端口的引脚号,如 BR0、BS0 用于控制 GPIOx的第 0 个引脚,若 x 表示 GPIOA,那就是控制 GPIOA的第 0 引脚,而 BR1、BS1就是控制 GPIOA 第 1个引脚。
    其中 BRy 引脚的说明是“0:不会对相应的 ODRx 位执行任何操作;1:对相应 ODRx位进行复位”。这里的“复位”是将该位设置为 0 的意思,而“置位”表示将该位设置为1;说明中的 ODRx是另一个寄存器的寄存器位,我们只需要知道 ODRx位为 1的时候,对应的引脚 x 输出高电平,为 0 的时候对应的引脚输出低电平即可(感兴趣的读者可以查询该寄存器 GPIOx_ODR 的说明了解)。所以,如果对 BR0 写入“1”的话,那么 GPIOx 的第 0
    个引脚就会输出“低电平”,但是对 BR0 写入“0”的话,却不会影响 ODR0 位,所以引脚电平不会改变。要想该引脚输出“高电平”,就需要对“BS0”位写入“1”,寄存器位BSy与 BRy是相反的操作。

操作实例

C语言对寄存器的封装

以上所有的关于存储器映射的内容,最终都是为大家更好地理解如何用 C 语言控制读写外设寄存器做准备,此处是本章的重点内容。

封装总线和外设基地址

在编程上为了方便理解和记忆,我们把总线基地址和外设基地址都以相应的宏定义起来,总线或者外设都以他们的名字作为宏名。

/* 外设基地址 */

#define  PERIPH_BASE               ((unsigned int)0x40000000)

/* 总线基地址 */

#define  APB1PERIPH_BASE           PERIPH_BASE

#define  APB2PERIPH_BASE          (PERIPH_BASE + 0x10000)

#define  AHBPERIPH_BASE           (PERIPH_BASE + 0x20000)

/* GPIO 外设基地址 */

#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)

#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)

#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)

#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)

#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)

/* 寄存器基地址,以 GPIOB 为例 */

#define GPIOA_CRL   *(unsigned int*)(GPIOA_BASE+0x00)

#define GPIOA_CRH   *(unsigned int*)(GPIOA_BASE+0x04)

#define GPIOA_IDR   *(unsigned int*)(GPIOA_BASE+0x08)

#define GPIOA_ODR   *(unsigned int*)(GPIOA_BASE+0x0C)

#define GPIOA_BSRR  *(unsigned int*)(GPIOA_BASE+0x10)

#define GPIOA_BRR   *(unsigned int*)(GPIOA_BASE+0x14)

#define GPIOA_LCKR  *(unsigned int*)(GPIOA_BASE+0x18)


#define GPIOB_CRL   *(unsigned int*)(GPIOB_BASE+0x00)

#define GPIOB_CRH   *(unsigned int*)(GPIOB_BASE+0x04)

#define GPIOB_IDR   *(unsigned int*)(GPIOB_BASE+0x08)

#define GPIOB_ODR   *(unsigned int*)(GPIOB_BASE+0x0C)

#define GPIOB_BSRR  *(unsigned int*)(GPIOB_BASE+0x10)

#define GPIOB_BRR   *(unsigned int*)(GPIOB_BASE+0x14)

#define GPIOB_LCKR  *(unsigned int*)(GPIOB_BASE+0x18) 


#define GPIOC_CRL   *(unsigned int*)(GPIOC_BASE+0x00)

#define GPIOC_CRH   *(unsigned int*)(GPIOC_BASE+0x04)

#define GPIOC_IDR   *(unsigned int*)(GPIOC_BASE+0x08)

#define GPIOC_ODR   *(unsigned int*)(GPIOC_BASE+0x0C)

#define GPIOC_BSRR  *(unsigned int*)(GPIOC_BASE+0x10)

#define GPIOC_BRR   *(unsigned int*)(GPIOC_BASE+0x14)

#define GPIOC_LCKR  *(unsigned int*)(GPIOC_BASE+0x18) 


#define GPIOD_CRL   *(unsigned int*)(GPIOD_BASE+0x00)

#define GPIOD_CRH   *(unsigned int*)(GPIOD_BASE+0x04)

#define GPIOD_IDR   *(unsigned int*)(GPIOD_BASE+0x08)

#define GPIOD_ODR   *(unsigned int*)(GPIOD_BASE+0x0C)

#define GPIOD_BSRR  *(unsigned int*)(GPIOD_BASE+0x10)

#define GPIOD_BRR   *(unsigned int*)(GPIOD_BASE+0x14)

#define GPIOD_LCKR  *(unsigned int*)(GPIOD_BASE+0x18)

 

#define GPIOE_CRL   *(unsigned int*)(GPIOE_BASE+0x00)

#define GPIOE_CRH   *(unsigned int*)(GPIOE_BASE+0x04)

#define GPIOE_IDR   *(unsigned int*)(GPIOE_BASE+0x08)

#define GPIOE_ODR   *(unsigned int*)(GPIOE_BASE+0x0C)

#define GPIOE_BSRR  *(unsigned int*)(GPIOE_BASE+0x10)

#define GPIOE_BRR   *(unsigned int*)(GPIOE_BASE+0x14)

#define GPIOE_LCKR  *(unsigned int*)(GPIOE_BASE+0x18)


首先定义了 “片上外设”基地址 PERIPH_BASE,接着在 PERIPH_BASE上加入各个总线的地址偏移,得到 APB1、APB2 总线的地址 APB1PERIPH_BASE、APB2PERIPH_BASE,在其之上加入外设地址的偏移,得到 GPIOA-G 的外设地址,最后在外设地址上加入各寄存器的地址偏移,得到特定寄存器的地址。一旦有了具体地址,就可

以用指针读写。


 /* 控制 GPIOB 引脚 0 输出低电平(BSRR 寄存器的 BR0 置 1) */

 *(unsigned int *)GPIOB_BSRR = (0x01<<(16+0));

 /* 控制 GPIOB 引脚 0 输出高电平(BSRR 寄存器的 BS0 置 1) */

 *(unsigned int *)GPIOB_BSRR = 0x01<<0;

 unsigned int temp;

 /* 读取 GPIOB 端口所有引脚的电平(读 IDR 寄存器) */

 temp = *(unsigned int *)GPIOB_IDR;


该代码使用 (unsigned int *) 把 GPIOB_BSRR宏的数值强制转换成了地址,然后再用“ * ”号做取指针操作,对该地址的赋值,从而实现了写寄存器的功能。同样,读寄存器也是用取指针操作,把寄存器中的数据取到变量里,从而获取 STM32外设的状态。


封装寄存器列表

用上面的方法去定义地址,还是稍显繁琐,例如 GPIOA-GPIOE 都各有一组功能相同的寄存器,如 GPIOA_ODR/GPIOB_ODR/GPIOC_ODR 等等,它们只是地址不一样,但却要为每个寄存器都定义它的地址。为了更方便地访问寄存器,我们引入 C 语言中的结构体语法对寄存器进行封装。


typedef unsigned int uint32_t; /*无符号 32 位变量*/

typedef unsigned short int uint16_t; /*无符号 16 位变量*/

 /* GPIO 寄存器列表 */

typedef struct {

 uint32_t CRL; /*GPIO 端口配置低寄存器 地址偏移: 0x00 */

 uint32_t CRH; /*GPIO 端口配置高寄存器 地址偏移: 0x04 */

 uint32_t IDR; /*GPIO 数据输入寄存器 地址偏移: 0x08 */

 uint32_t ODR; /*GPIO 数据输出寄存器 地址偏移: 0x0C */

 uint32_t BSRR; /*GPIO 位设置/清除寄存器 地址偏移: 0x10 */

 uint32_t BRR; /*GPIO 端口位清除寄存器 地址偏移: 0x14 */

 uint16_t LCKR; /*GPIO 端口配置锁定寄存器 地址偏移: 0x18 */

 } GPIO_TypeDef;


这段代码用 typedef 关键字声明了名为 GPIO_TypeDef的结构体类型,结构体内有 7个成员变量,变量名正好对应寄存器的名字。C 语言的语法规定,结构体内变量的存储空间

是连续的,其中 32 位的变量占用 4个字节,16位的变量占用 2 个字节。

也就是说,我们定义的这个 GPIO_TypeDef ,假如这个结构体的首地址为 0x4001 0C00(这也是第一个成员变量 CRL 的地址), 那么结构体中第二个成员变量 CRH 的地址即为

0x4001 0C00 +0x04 ,加上的这个 0x04 ,正是代表 CRL所占用的 4个字节地址的偏移量,其它成员变量相对于结构体首地址的偏移,在上述代码右侧注释已给。


这样的地址偏移与 STM32 GPIO 外设定义的寄存器地址偏移一一对应,只要给结构体设置好首地址,就能把结构体内成员的地址确定下来,然后就能以结构体的形式访问寄存器


GPIO_TypeDef * GPIOx; //定义一个 GPIO_TypeDef 型结构体指针 GPIOx

GPIOx = GPIOB_BASE; //把指针地址设置为宏 GPIOH_BASE 地址

GPIOx->IDR = 0xFFFF;

GPIOx->ODR = 0xFFFF;

int32_t temp;

temp = GPIOx->IDR; //读取 GPIOB_IDR 寄存器的值到变量 temp 中

推荐阅读

史海拾趣

EF Johnson Technologies Inc公司的发展小趣事

在电子行业中,技术创新是企业持续发展的关键。EF Johnson公司深知这一点,始终将研发作为公司发展的核心驱动力。公司不断加大对研发的投入,积极引进高端人才,并与高校和研究机构建立紧密的合作关系。这些举措让EF Johnson在技术上始终保持领先地位,不断推出具有竞争力的新产品和解决方案。

Foxboro I C T Inc公司的发展小趣事

在电子行业中,技术创新是企业持续发展的关键。EF Johnson公司深知这一点,始终将研发作为公司发展的核心驱动力。公司不断加大对研发的投入,积极引进高端人才,并与高校和研究机构建立紧密的合作关系。这些举措让EF Johnson在技术上始终保持领先地位,不断推出具有竞争力的新产品和解决方案。

Horizon Electronics Enterprises Group公司的发展小趣事

在21世纪初,随着数字技术的兴起,Horizon Electronics Enterprises Group(以下简称“Horizon”)由一群对电子技术充满热情的工程师创立。公司初期专注于研发高性能的半导体芯片,以解决当时市场上对高速、低功耗芯片的迫切需求。通过不懈努力,Horizon成功研发出了一款具有突破性的芯片产品,该产品在数据处理速度和能效比上远超同类产品,迅速获得了市场的认可。这一技术创新不仅为公司赢得了首批客户,也为后续发展奠定了坚实的技术基础。

Embedded Artists公司的发展小趣事

在业务迅速发展的同时,Embedded Artists公司也始终关注环境保护和可持续发展。他们致力于采用环保材料和节能技术来生产产品,并通过优化生产流程来降低能源消耗和废物排放。此外,公司还积极参与公益活动,支持环保组织和项目。这些举措不仅提高了公司的社会形象,也为公司的长期发展奠定了坚实基础。

DS-IMP公司的发展小趣事

DS-IMP公司在发展过程中,非常重视市场拓展和品牌建设。公司制定了详细的市场战略和营销计划,通过参加国内外展会、举办技术研讨会、开展产品推广活动等方式,不断提升品牌知名度和影响力。同时,公司还积极开拓国际市场,与多家国际知名企业建立了长期合作关系。这些努力使得公司的市场份额不断扩大,品牌影响力逐渐增强。

D3 Semiconductor公司的发展小趣事

作为一家以技术创新为核心竞争力的公司,D3 Semiconductor始终保持对新技术、新应用的关注和研究。公司不断投入研发资源,推出了一系列具有创新性的半导体产品,满足了市场的多样化需求。这种持续创新的精神推动了D3 Semiconductor的不断发展,也使其在竞争激烈的电子行业中保持领先地位。

问答坊 | AI 解惑

计算机类的电子书下载

Free Ebook Latest Update [2007-01-29] Agile Web Development with Rails [2007-01-29] rails-documentation [2007-01-26] 10 minutes start your ruby on rails [2007-01-26] Algorithms [2007-01-25] Designing a Windows Server 2003 Active D ...…

查看全部问答>

汽车爆震传感器测试系统的工作原理

  压电式爆震传感器广泛应用于发动机机体或气缸的爆震检测中。汽车防爆震系统通过检测出压电传感器的电压值来判断爆震强度。        因此,功能完善、性能稳定、操作简单、测试精度高,可满足大批量生产测试需要的爆震传感 ...…

查看全部问答>

逆变的一些材料

本帖最后由 paulhyde 于 2014-9-15 03:02 编辑 大家都说可能出逆变的题目,和大家分享一些逆变的材料    …

查看全部问答>

微小信号放大电路设计

讲的还不错…………………………………………………

查看全部问答>

这是咋回事啊????

今天写了一个小程序,其中包括了按键和数码管,刚开始时一切正常,但是第二次用AS 下载时却发现数码管灭了,当时也没在意,然后再下一遍程序,数码管啥也不显示。最后我用最基本的 非门来验证,却发现所有没用的管脚都是3.2v。是不是我的芯片坏了 ...…

查看全部问答>

硬件工程师手册最全版本(159页)

华为硬件工程师手册目前最全版本(159页) 说明:目前网上包括本论坛的华为硬件工程师手册通常是不全版本(73页),希望大家下载是千万要注意。也希望大家如果没有更全的版本就不要在重复上传了,这可能是论坛重复率最高的一篇文档了,更不要冠以 ...…

查看全部问答>

智能家居系统案例--比尔·盖茨的“未来之家”

现在最著名的智能家居要数比尔·盖茨的豪宅了。他在《未来之路》一书中以很大篇幅来描绘他正在华盛顿湖建造的私人豪宅。在他的描绘中,这个住宅是“由硅片和软件建成的”并且要“采纳不断变化的尖端技术”。经过7年的建设,1997年,比尔·盖茨的豪 ...…

查看全部问答>

求救:交叉编译EXPAT和LIBXML2都不能通过,有人能帮我看看吗?

我用ARM-ELF-GCC交叉编译EXPAT和LIBXML2,都遇到同样的问题: ./configure --host=arm-elf --prefix=/home/expat 提示 checking for C compiler default output file name... configure: error: C compiler cannot create executables See ` ...…

查看全部问答>

WinCE论坛

我最近刚接触WinCE,遇到好多问题,不知道如何解决,无意发现了一个论坛, 里面有不少好文章,我明白了好多东西。现在我把这个论坛告诉大家,让大家分享一下, 对像我这样的初学者帮助确实很大,论坛的网址是 http://www.embeddedsoft.cn/bbs…

查看全部问答>

这回,MAX1640估计是真的废了

晚上我接着想检测MAX1640的板子。 我一直怀疑MOS管会有问题。 于是我想到把两根MOS管短路了,看看情况会不会有好转。 之所以考虑短路,而不是检测好坏,因为MOS管在线,测起来比较麻烦,如果要焊下来,太费周章。 于是就想着把它短路了。 在这 ...…

查看全部问答>