历史上的今天
返回首页

历史上的今天

今天是:2024年12月10日(星期二)

正在发生

2018年12月10日 | STM32之定时器中断控制LED闪烁

2018-12-10 来源:eefocus

上篇博客我们是用延时函数实现了LED的闪烁,今天我们使用STM32的定时器来使LED闪烁。 


关于32的定时器的种类,今天我在这先不做过多的说明,有时间我会再另写一篇博客来专门介绍32的定时器。今天我们使用32的定时器3来产生中断,以实现LED的闪烁。 


今天我们需要配置的有LED和定时器,首先来配置LED,我们还是使用正点原子精英版开发板上的DS0来进行实验 


配置LED的过程还是和上篇博客中点亮LED的方法一样,我就不再过多的说明,只贴下代码 


led.c文件如下


#include"led.h"


void led_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

    GPIO_Init(GPIOB,&GPIO_InitStructure);

}


led.h文件如下


#ifndef __LED_H

#define __LED_H

#include "sys.h"


#define LED0 PBout(5)


void led_init(void);


#endif


配置完LED之后,下面就要开始配置今天的主角—定时器,首先我们还是像之前那样,先在工程文件所在的文件夹里面的HARDWARE文件夹里面重新建立一个新文件夹,并命名为Timer,,如下图 



然后我们进入到Keil MDK中,建立两个空白的文件,并分别命名为time.c和time.h,然后都保存在我们刚才在HARDWARE文件夹里面所建立的Timer文件夹里面,如下图 



然后我们再在Keil MDK中点击HARDWARE文件,然后把刚才保存的time.c和time.h文件都给添加到此工程中去。(这些步骤以后我就不再一一说明了),添加完成如下图 

 

 


添加完之后,我们不要忘了要再把这个文件的路径也添加到工程中去,具体做法我在上一篇博客中有介绍。 


上面这些都做好之后,我们就可以开始写配置定时器的程序了,首先我们来写time.c文件。 


我们这次用到了定时器3,所以我们先来写一个定时器3的初始化函数,如下


void time3_init(u16 per,u16 pre)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的时钟

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0

    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数

    TIM_TimeBaseStructure.TIM_Period=per;//周期

    TIM_TimeBaseStructure.TIM_Prescaler=pre;//分频系数

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中断

    TIM_Cmd(TIM3,ENABLE);//使能TIM3

}


初始化函数还是上篇博客中我们配置GPIO口时的老套路,首先就是先定义一个结构体(注意定义结构体必须在函数的开头)


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

1

因为我们用到了定时器3,所以我们就要使能定时器3的时钟


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的时钟

1

然后就是对刚才定义过的结构体进行成员赋值


TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数

TIM_TimeBaseStructure.TIM_Period=per;//周期

TIM_TimeBaseStructure.TIM_Prescaler=pre;//分频系数


这里面每一个成员变量所赋的值都是在32的.c文件中已经定义好的,我们只需要去找到相应的.c和.h文件进行复制到这里就行。 


这个结构体的第一个变量是时钟分频因子,这个变量其实我现在也不是很理解它的含义,暂时先不做过多介绍,我们在这里只是给他复制为TIM_CKD_DIV1,也就是让他等于0,具体变量内容如下


#define TIM_CKD_DIV1                       ((uint16_t)0x0000)

#define TIM_CKD_DIV2                       ((uint16_t)0x0100)

#define TIM_CKD_DIV4                       ((uint16_t)0x0200)

#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \

                             ((DIV) == TIM_CKD_DIV2) || \

                             ((DIV) == TIM_CKD_DIV4))


然后这个结构体的第二个成员是选择计数方式,因为我们知道,定时器的本质也就是计数,所以这里我们选择它的计数方式,一般我们选择向上计数(也就是计数器从0开始计数), 即选择TIM_CounterMode_Up,具体变量内容如下


#define TIM_CounterMode_Up                 ((uint16_t)0x0000)

#define TIM_CounterMode_Down               ((uint16_t)0x0010)

#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)

#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)

#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)

#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) ||  \

                                   ((MODE) == TIM_CounterMode_Down) || \

                                   ((MODE) == TIM_CounterMode_CenterAligned1) || \

                                   ((MODE) == TIM_CounterMode_CenterAligned2) || \

                                   ((MODE) == TIM_CounterMode_CenterAligned3))


然后结构体的第三个成员是计数周期,也就是说这个成员变量的内容就代表着我们让计数器计数到哪一个数要重现返回0,重新开始计数,这个参数也是我们这个初始化函数的第一个入口参数,待会我们会在主函数中进行调用,并传入参数。(假如说我们让计数周期等于100,那么计数器计数过程就是,0,1,2,3,…,98,99,100,0,1,2,3…98,99,100,0,1,2,3,…) 


然后结构体的第四个成员是分频系数,如果我们让分频系数等于1,那么就是选择不分频,不分频的意思也就是说,定时器计数的频率就等于定时器的输入频率,这里我们使用的是定时器3,它现在的输入时钟频率是72MHz(具体为啥是72MHz,有时间我会再讲),那么他就是以72M的频率进行计数,假如说我们让分频系数等于2,那么他就是以72M / 2的频率进行计数,这就是分频系数的概念。这个定时器的初始化函数,我们通过传入不同的参数,也就是设置不同的计数周期和频率,我们就可以设置定时器多长时间产生一次中断。 


我们把各个成员都赋值之后,然后就是把这些成员利用下面这个函数给导入到相应的寄存器中,函数如下


TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


通过以上的步骤,我们已经把定时器3的工作方式都给配置好了,接下来我们要做的就是再使能一些玩意。因为我们今天用到了中断,所以我们要使能定时器3的中断,函数如下


TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中断


其中这个函数的第一个入口参数就是我们要使能的是哪一个定时器,然后第二个入口参数就是我们要使能的是哪一种中断,这里我们选择使能更新(溢出)中断,也就是每当计数器溢出的时候,会产生一次中断,第三个入口参数就是选择使能或者不使能,我们选择使能ENABLE。


然后我们用到了定时器3,所以说我们要使能定时器3(要区分开使能定时器3和使能定时器3的时钟),函数如下


TIM_Cmd(TIM3,ENABLE);//使能TIM3


定时器初始化完成之后,因为我们用到了定时器中断,所以说我们要写定时器中断服务函数,本程序中断服务函数如下


void TIM3_IRQHandler(void) //TIME3中断服务函数  需要设定中断优先级  即NVIC配置

{

    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否发生了更新(溢出)中断

    {

        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位

    }


    LED0=!LED0;

}


注意在32里面,各个中断服务函数的名字不能乱写,只能是固定的名字,写错一个字母都不行,其中定时器3的中断服务函数名字为TIM3_IRQHandler(void),大家一定不要写错。 

然后进入中断服务函数里面,首先我们进行中断的判断,我们要判断的是刚才发生的中断是不是我们想要的中断。在32里面,判断中断有固定的函数,我们通过这个函数来获得相应的中断标志位的值,以此来判断定时器是否真正发生了相应的中断,函数如下


TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)


这个函数共有两个入口参数,其中第一个参数就是填入你要判断的是哪一个定时器的中断,然后第二个参数是填入你要判断的是哪一种类型的中断,(因为一个定时器中断类型有好几个,所以说我们必须指明判断的类型),这里我们使用的是定时器3的更新(溢出)中断,所以说此函数应写成如下形式


if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否发生了更新(溢出)中断


这个函数的意思其实就是先得到中断标志位的值,然后判断中断标志位的值是0(RESET)还是1(SET),当发生中断的时候,对应的中断标志位会被置为1,也就是SET,如果没有发生中断,那么标志位的值就是0,也就是RESET,所我们在这里判断:如果标志位不是RESET,那么就是发生了中断。如果我们发现标志位被置1了,那么就进入if里面,然后我们第一步要做的就是清零中断标志位,以防程序会多次进入中断服务函数,清零中断标志位函数也是由专门的函数,如下


TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位


这个函数也是有两个入口参数,他和刚才的获取中断标志位值的函数是一样的入口参数。 

这些都写好之后,我们就可以开始写具体的中断服务函数了,这里我们让LED0的状态进行翻转,程序如下


LED0=!LED0;


这些都配置完之后,还没有完成任务,对于32来说,我们还需要再配置一下中断优先级,程序如下


void NVIC_INIT(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设定中断优先级分组0

    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//设定中断向量   本程序为TIM3的中断

    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能响应中断向量的中断响应

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//配置中断向量的抢占优先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//配置中断向量的响应优先级

    NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

}


配置中断优先级也是一样的套路,定义结构体,然后对结构体的变量进行复制,然后就是把这些成员变量给导入到相应的寄存器中,。 


其中这个结构体的第一个参数是设置中断向量,我们这次使用的是定时器3的中断,所以我们要设置成TIM3_IRQn。 


结构体的第二个参数是使能控制,我们要使能中断响应,也就是说,我们要开启定时器的中断响应(当发生中断的时候,允许程序去响应这个中断)所以要把它设置为ENABLE。 


结构体的第三个成员变量是设置抢占优先级,第四个成员变量是设置响应优先级,关于这两个参数,我在这里不做过多的解释,等有时间我再深入了解一下这两个变量的意义。其实他就是来配置我们当前使用的中断的优先级。 


然后还有一句程序就是


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设定中断优先级分组0

1


这条语句是用来设定中断优先级分组,在不同的分组里面会有不同的抢占优先级和响应优先级可供选择,这里我也不多讲。 


到此为止我们的time.c文件就写完了,time.c文件代码如下


#include "time.h"

#include "led.h"

void time3_init(u16 per,u16 pre)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的时钟

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0

    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数

    TIM_TimeBaseStructure.TIM_Period=per;//周期

    TIM_TimeBaseStructure.TIM_Prescaler=pre;//分频系数

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中断

    TIM_Cmd(TIM3,ENABLE);//使能TIM3

}

void NVIC_INIT(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设定中断优先级分组0

    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//设定中断向量   本程序为TIM3的中断

    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能响应中断向量的中断响应

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//配置中断向量的抢占优先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//配置中断向量的响应优先级

    NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

}


void TIM3_IRQHandler(void) //TIME3中断服务函数  需要设定中断优先级  即NVIC配置

{

    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否发生了更新(溢出)中断

    {

        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位

    }


    LED0=!LED0;

}


接下来我们开始写time.h文件,time.h文件主要就是定义一个头文件”time.h”,然后就是声明一下我们在time.c文件中所定义的所有函数(中断服务函数可以不用再time.h文件声明),time.h文件程序如下


#ifndef __TIME_H_

#define __TIME_H_

#include "sys.h"


void time3_init(u16 per,u16 pre);

void NVIC_INIT(void);


#endif


接下来我们开始写main.c文件,程序如下


#include "sys.h"

#include "led.h"

#include "time.h"

int main(void)

{

    led_init();

    time3_init(7199,9999);//1s产生一次中断,用于控制LED进行闪烁

    NVIC_INIT();

    while(1)

    {

    }

}


main.c文件中程序就稍微简单了一些,它主要就是调用一些我们写好的函数,我们主要就是来看一下time3_init(7199,9999)中的两个参数。回想一下我们上面提到的这个定时器初始化函数的入口参数的意义,第一个入口参数是设定计数周期,我们这里设定为7199,那么程序的计数过程就是:0,1,2,3,…,7199,0,1,2,3,…,7199,…也就是说程序从0开始计数,然后一直计到7199,一个周期总共计了7200个数,计到7199之后,再返回到0重新开始下一轮计数,当它每次计到7199时,定时器就会产生一次中断;然后我们来看这个初始化函数的第二个参数,这个参数控制的是计数的频率,也就是控制计数器多长时间计一个数,这里我们选择参数为9999,也就是定时器计数的频率为72MHz / (9999+1)=7200Hz。(至于为什么要在原来的基础上加1,也就是为什么是9999+1,可能在32里面他都是从0开始算的吧)总体来说,现在计数器是以7200Hz的频率来计数,每计到7199就中断一次,也就是说现在中断是1s产生一次,(1s是这样算出来的:计数频率是7200Hz,也就是说每计一个数需要花费1/7200s的时间,而总共一个周期需要计7199+1个数,那么也就是需要花费t=(1/7200)*(7199+1)=1s)相应的LED也就是1s闪烁一次。如果我们想改变LED闪烁的频率,我们只需要更改 


time3_init(7199,9999); 


这个初始化函数的两个入口参数即可。 


至此,我们本次使用定时器中断来控制LED进行闪烁的实验到此就结束了,把写好的程序烧录到开发板中就会发现LED灯在进行闪烁,闪烁频率是受定时器初始化函数的两个入口参数进行控制。


其实我发现用定时器中断的时候,我们可以不用写中断服务函数,我们可以这样直接在主函数中(或者其他的函数)进行中断标志位的判断,一旦判断出相应的中断标志位被置1的话,我们可以直接在下面写中断服务函数,并且这样我们也就不用再去写那个中断优先级配置的函数了。主函数代码如下


#include "sys.h"

#include "led.h"

#include "time.h"


int main(void)

{

    led_init();

    time3_init(7199,9999);

    while(1)

    {


//一秒产生以一次中断,使得LED的状态发生反转   没用用到中断函数,直接进行中断判断


        if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否发生了更新(溢出)中断

        {

            TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位

            LED0=!LED0;

        }

    }

}


这个时候time.c文件代码如下(省去了中断优先级配置函数和定时器3的中断观服务函数)


#include "time.h"

#include "led.h"

void time3_init(u16 per,u16 pre)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的时钟

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0

    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数

    TIM_TimeBaseStructure.TIM_Period=per;//周期

    TIM_TimeBaseStructure.TIM_Prescaler=pre;//分频系数

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中断

    TIM_Cmd(TIM3,ENABLE);//使能TIM3

}


time.h文件代码如下


#ifndef __TIME_H_

#define __TIME_H_

#include "sys.h"


void time3_init(u16 per,u16 pre);


#endif


不过我还是建议大家用标准的中断服务函数来写,不要直接在主函数中进行判断中断标志位,因为写成标准中断服务函数的形式,如果中断到来了,程序会立马进入到中断服务函数,而如果你没有写中断服务函数,而是直接在主函数或者其他函数中进行判断中断标志位的话,如果中断发生了,程序不会立即执行你想要的中断服务,你必须等到程序执行到判断中断标志位的那个地方,他才会执行相应的所谓的中断服务函数,如果你的程序比较多的话,可能就会对中断的响应有所影响,所以还是建议大家写成标准的中断服务函数,然后不要忘了要对中断有优先级进行配置。


推荐阅读

史海拾趣

Danaher Corporation公司的发展小趣事

随着全球化趋势的加强,丹纳赫集团开始积极拓展国际市场。通过在全球各地设立研发中心、生产基地和销售网络,丹纳赫集团成功地将产品和服务推向了全球市场。同时,丹纳赫集团还加强了与国际知名企业的合作,共同开发新技术和产品,进一步巩固了其在电子行业中的领先地位。

以上五个故事梗概概述了丹纳赫集团在电子行业中的发展历程和关键节点。如需更详细的信息和故事背景,建议查阅丹纳赫集团的官方资料或相关新闻报道。

Hirose公司的发展小趣事

丹纳赫集团一直重视科技创新和产品研发。在电子行业,丹纳赫集团不断推出具有创新性和竞争力的产品,如高精度测量仪器、自动化测试设备和电子制造解决方案等。这些产品不仅满足了客户对高质量、高效率生产的需求,还帮助丹纳赫集团在电子行业中树立了良好的品牌形象。

统宇电研(Coilmaster)公司的发展小趣事

随着电子行业的快速发展,统宇电研始终保持着技术创新的步伐。公司不断投入研发资源,积极引进先进技术和设备,提升产品性能和质量。同时,统宇电研还与多所高校和研究机构建立合作关系,共同开展前沿技术研究。这些努力使得统宇电研在行业内树立了技术创新的标杆,引领着行业的发展方向。

HTSEMI( Jin Yu Semiconductor )公司的发展小趣事

为了加速国际化进程,金宇半导体于2020年制定了详细的国际化战略。公司首先在欧洲设立了研发中心,以吸引更多国际顶尖人才加入。随后,金宇半导体又通过一系列并购整合动作,收购了多家在特定领域具有领先技术的海外企业。这些并购不仅增强了金宇半导体的技术实力和市场影响力,还为其在全球范围内的业务拓展提供了有力支持。通过国际化战略的实施,金宇半导体正逐步成为一家具有全球竞争力的半导体企业。

ELMOS公司的发展小趣事

ELMOS作为一家欧洲公司,在世界各地都设有研发和销售办事处。这种全球化的布局使得ELMOS能够更好地了解不同市场的需求,为客户提供更加贴近市场的产品和服务。同时,通过与全球各地的客户和合作伙伴的紧密合作,ELMOS不断拓展其国际市场份额,进一步提升了公司的国际影响力。

依必安派特(ebmpapst)公司的发展小趣事

为了进一步满足中国市场的本地化需求,依必安派特在2005年成立了依必安派特电机(上海)有限公司,开始了国产化进程。这一举措不仅提高了产品的性价比,还缩短了交货周期,使得依必安派特在中国市场的竞争力得到了显著提升。随着国产化产品的快速增长,依必安派特在中国的前十年市场业绩突飞猛进,为后续的飞跃发展打下了坚实基础。

问答坊 | AI 解惑

汽车前轮侧滑计算机检测系统的设计

1 引言    汽车前轮侧滑量是机动车辆安全技术检测的重要指标。当汽车直线行驶时前轮的横向位移量称侧滑量,它是前轮定位参数在动态情况下匹配性能的综合反映,若侧滑量超出规定范围,不仅会磨损轮胎、增大油耗,还会因转向轮操纵不灵、汽车行 ...…

查看全部问答>

各类开发实用电路图

各类开发实用电路图…

查看全部问答>

请各位高手指教,下面的电路能不能成立,不能成立的原因是什么?

电路是我自己画的,个人分析如下,有不对的地方希望大家指正:谢谢~ 1》通电,12V经R1到Q1的C极,经R2加至Q1的B极,Q1饱和导通,C极等于0 此时Q2,Q3,Q4的B极全部为0 Q2为PNP管,此时是导通状态,但对电路没影响 2》按S1, ...…

查看全部问答>

秒表计程序

请问存储的数据怎样让它循环调出呢?…

查看全部问答>

Linux系统移植(相当清晰的一份文档)推荐

该文档的目的是总结我们在工作中的一些经验,并把它们分享给喜欢ARM和Linux的朋友, 如有错误之处,请大家多多指点. 同样, 我们也希望更多人能把自己的工作经验和体会加入该文档,让大家共同进步. 该文档是一份交流性文档, 只供个人学习与交流,不允许 ...…

查看全部问答>

【藏书阁】晶体管脉冲电路一百例

目录: 详细信息: 一本很老的书,还有毛主席语录。里面介绍了100例由三极管组成的脉冲电路,很多电路设计很精妙,适合广大电子制作爱好者制作参考之用。 书名:晶体管脉冲电路一百例   作者:《晶体管脉冲电路一百例》编译组 ...…

查看全部问答>

【藏书阁】模-数与数-模转换技术基础

目录: 第一章 概论 第二章 采样和量化 第三章 模拟开关和多路切换器 第四章 放大器、采样/保持器和比较器 第五章 数-模转换器 第六章 模-数转换器 第七章 数据采集系统与数据分配系统 第八章 转角/直线位移-数字转换器 第九章 噪声干扰 ...…

查看全部问答>

绝好机会!! 推荐进华为

西安华为研究所开始了新一轮招聘,     专业:计算机,通信,电子,物理等工科专业(这次专业要求不很严)     工作经验:至少工作一年            如有意者:请将自己的建立发到邮箱& ...…

查看全部问答>