STM32基础设计(5)---ADC转换(中断方式)

发布者:冷漠之心最新更新时间:2019-01-29 来源: eefocus关键字:STM32  ADC转换  中断方式 手机看文章 扫描二维码
随时随地手机看文章

本文简单介绍了STM32F103C8,通过中断方式读取电压,不过最后楼主读取参考电压失败,还没有找到错误,所以读取的电压只能十六进制显示,如有不便请忽略本文!


本文的介绍按照一般流程来走:


1,串口的初始化


2,ADC初始化


3,中断初始化


4,编写中断函数


5,编写主函数


接下来详细介绍:


1,串口的初始化:

void usart_init()

{

GPIO_InitTypeDef Uart_A;  

      

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);  

    Uart_A.GPIO_Pin = GPIO_Pin_9;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOA,&Uart_A);  

      

    Uart_A.GPIO_Pin = GPIO_Pin_10;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; 

    GPIO_Init(GPIOA,&Uart_A);   

USART_InitTypeDef Uart;  

      

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  

    Uart.USART_BaudRate = 115200;  

    Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

    Uart.USART_Mode = USART_Mode_Tx;  

    Uart.USART_Parity = USART_Parity_No;  

    Uart.USART_StopBits = USART_StopBits_1;  

    Uart.USART_WordLength = USART_WordLength_8b;  

    USART_Init(USART1,&Uart);  

      

    USART_Cmd(USART1,ENABLE);  

    USART_ClearFlag(USART1,USART_FLAG_TC); 

}

关于本段代码,我前面写的文章STM32基础设计(3)有详细讲解,此处不再赘述。


2,ADC初始化

typedef struct

{//配置ADC的模式,一个ADC是独立模式,2个是双模式

  uint32_t ADC_Mode;                      /*!< Configures the ADC to operate in independent or

                                               dual mode. 

                                               This parameter can be a value of @ref ADC_mode */

//配置ADC是否使用扫描,单通道不扫描,多通道扫描

  FunctionalState ADC_ScanConvMode;       /*!< Specifies whether the conversion is performed in

                                               Scan (multichannels) or Single (one channel) mode.

                                               This parameter can be set to ENABLE or DISABLE */

//配置ADC是单次转换还是连续转换

  FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in

                                               Continuous or Single mode.

                                               This parameter can be set to ENABLE or DISABLE. */

//外部触发选择

  uint32_t ADC_ExternalTrigConv;          /*!< Defines the external trigger used to start the analog

                                               to digital conversion of regular channels. This parameter

                                               can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */

//转换结果数据对其方式

  uint32_t ADC_DataAlign;                 /*!< Specifies whether the ADC data alignment is left or right.

                                               This parameter can be a value of @ref ADC_data_align */

//ADC转换的通道数目

  uint8_t ADC_NbrOfChannel;               /*!< Specifies the number of ADC channels that will be converted

                                               using the sequencer for regular channel group.

                                               This parameter must range from 1 to 16. */

}ADC_InitTypeDef;

下面粘贴代码:


void Adc_Init()

{

ADC_InitTypeDef adc;//定义ADC结构的变量

GPIO_InitTypeDef io_b;//定义串口结构体变量 ,开发板上的电源接的是GPIOB端口的 1引脚,查数据手册,其为ADC1的9通道

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB,ENABLE);//开时钟(即把心脏激活)

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

io_b.GPIO_Pin = GPIO_Pin_1;//设置端口引脚为 引脚1

io_b.GPIO_Mode = GPIO_Mode_AIN;//设置为输入模式

io_b.GPIO_Speed = GPIO_Speed_50MHz;//最高速率为50MHz

GPIO_Init(GPIOB,&io_b);初始化引脚

ADC_DeInit(ADC1);先将外设ADC1的全部寄存器重设为默认值 ADC_TempSensorVrefintCmd(ENABLE);谁能外部参照电压(勿忘)

adc.ADC_Mode = ADC_Mode_Independent;设置ADC为独立模式

adc.ADC_ScanConvMode = ENABLE;使能扫描模式

adc.ADC_ContinuousConvMode = ENABLE;使能连续扫描

adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;不使用外部触发

adc.ADC_DataAlign = ADC_DataAlign_Right;数据右对齐

adc.ADC_NbrOfChannel = 2;来制定用几个ADC通达(勿忘)

ADC_Init(ADC1,&adc);初始化ADC寄存器

ADC_RegularChannelConfig(ADC1,ADC_Channel_9,1,ADC_SampleTime_239Cycles5);制定用哪个ADC转换、第几个通道,转换的顺序、转换的周期

ADC_RegularChannelConfig(ADC1,ADC_Channel_17,2,ADC_SampleTime_239Cycles5);

//这里需要根据数据手册来设定通道,数据手册上会说明那个引脚对应那个通道,外接电源接到那个引脚上就可以了,必须按照数据手册的要求来,不然肯定会出错,博主在这里就有一个很大很大的教训,望读者谨记

ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);打开ADC中断

ADC_Cmd(ADC1,ENABLE);使能ADC1

ADC_ResetCalibration(ADC1);复位ADC1的校准寄存器

while(ADC_GetResetCalibrationStatus(ADC1));等待校准寄存器复位完成

ADC_StartCalibration(ADC1);开始ADC1校准

while(ADC_GetCalibrationStatus(ADC1));等待ADC1校准完成

ADC_SoftwareStartConvCmd(ADC1,ENABLE);使能指定的ADC1的软件转换启动功能

}

3.中断初始化

void adc_nvic_init()

{

NVIC_InitTypeDef nvic;定义中断结构体

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);设置中断分组

nvic.NVIC_IRQChannel = ADC1_2_IRQn;制定专断通道

nvic.NVIC_IRQChannelCmd = ENABLE;使能中断

nvic.NVIC_IRQChannelPreemptionPriority = 1;抢占优先级

nvic.NVIC_IRQChannelSubPriority = 1;子优先级

NVIC_Init(&nvic);初始化

NVIC_InitTypeDef usart1;定义中断结构体

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);设置中断分组

usart1.NVIC_IRQChannel = USART1_IRQn;指定中断通道

usart1.NVIC_IRQChannelCmd = ENABLE;设能中断通道

usart1.NVIC_IRQChannelPreemptionPriority = 0;抢占优先级

usart1.NVIC_IRQChannelSubPriority= 0;子优先级

NVIC_Init(&usart1);中断初始化

}

博主在这里遇到一个问题,该问题时,中断分组的设置,上面两段程序得分别设置中断分组,要不然会有一个中断不会执行(没有再次设置中断分组的那个),不知道是博主代码规范的问题还是就必须这样设置。博主还未搞懂,如果读者有知道这个问题答案的,请在评论里赐教,不胜感激。


4,编写中断函数

先粘贴代码:


void ADC1_2_IRQHandler()

{

if(ADC_GetITStatus(ADC1,ADC_IT_EOC) == SET)这里使用来判断,如果已经转换完成EOC位为1,具体请查看参考手册ADC状态寄存器ADC_SR的eEOC位

{if(count_1%2 == 0){代码中的if语句中的嵌套if语句是用来区分外接电源电压和内部参考电压的。具体见下面的解释

ADC_ConvertedValue = ADC_GetConversionValue(ADC1);

count_1++;

}else

{

ADC_ConvertedValue_1 = ADC_GetConversionValue(ADC1);

//ADC_ConvertedValue_1 = ADC1->DR;

count_1++;

}

}

ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);

}

 

void USART1_IRQHandler(void)

{

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE))判断是否可以发送数据

{

USART1->CR1 &= ~USART_CR1_TXEIE;在这里笔者也碰到了问题,详见下文

USART1->DR = car;

while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);

//USART1->CR1 &= ~USART_CR1_TXEIE;

}

if(USART1->SR & USART_SR_RXNE)判断是否可以接收数据

{

volatile int8_t com_data;

com_data = USART1->DR;

}

}

在ADC中断服务函数中,代码中的if语句中的嵌套if语句是用来区分外接电源电压和内部参考电压的,因为第一次接受的是外部电源电压,第二次接受的是内部参考电压,所以可以利用奇偶数,即偶数用ADC_ConvertedValue来存放外部电源电压值,奇数时用ADC_ConvertedValue_1来存放参考电压值。但是,笔者发现,这样会失败,经过串口调试发现两次接受到的值都一样,笔者初步认为,可能是ADC的转换速率太快了,具体什么歌情况还不清楚,等下一个基础设计ADC转换(DMA方式)的时候在细究。


笔者,在调试程序的时候发现,通过中断的方式进行串口通信必须在给DR赋值之前将CR1寄存器的 TXEIE寄存器置0,以防止DE接受完数据后再次进入中断,要不然将数据赋值给DR后会一直进入中断(笔者在调试的时候发现,会一直重复输出一个值,笔者猜测这不是因为中断结束不了,而是因为,嵌套了N层循环,但是根据STM32参考手册的543页,TXEIE为明明解释是由软件设置,笔者在主函数里设置了TXEIE为0,发现没有用,如果在中断服务函数中不再次清零,就跳不出中断。),另外DR接受完数据后,还要加一句


while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);

要是没有这一句,串口调试时发现,一个值连续打印两次。(笔者猜测是不是因为电脑速度太快了。)


以上两个问题,笔者还没有找到原因,只是找到了解决方法,希望看到这篇文章的读者,如果知道原因,请不吝赐教,在下不胜感激。


---------------------------------------------------------------------------------------------------------------------------------


2018年3月27日补:


关于那个还要在中断服务函数中再次将TXEIE设置为零,是因为发送中断是通过 打开中断函数(USART_ITConfig)进入的,该函数中已经将CR1寄存器中的TXEIE位置1 的,所以中断服务函数中还要再次清0,以防止再中断。


---------------------------------------------------------------------------------------------------------------------------------


5,编写主函数

int main()

{

void PrintU16(uint16_t num);

void PrintHexU8(uint8_t data);

 

Adc_Init();

adc_nvic_init();

usart_init();

while(1)

{

num = (uint16_t)(2.0f* ADC_ConvertedValue/ADC_ConvertedValue_1 *1.2f*100 );参考电压是1.2f通过比例关系算出实际电压。

PrintU16(num);

delay(1000);

}

}

笔者并没有计算出准确的电压值,只是采集到两个电压值,笔者猜测,可能是因为ADC的转换速率太快,导致笔者的  通过奇偶数来区分内部电压和外部电压不管用了,笔者还在思考解决方式,如果读者有好的方法,请指教。


本文到此结束,下面是完整代码:


#include

#define uint unsigned int

#define uchar unsigned char

char car;

static char count_1=0;//当做奇偶数

uint16_t ADC_ConvertedValue;//存放电源电压

uint16_t ADC_ConvertedValue_1;//存放内部参照电压

static uint16_t num=0;

void delay(uint n)

{

int i,j;

for(i=0;i

for(j=0;j<8500;j++);

}

 

void Adc_Init()

{

ADC_InitTypeDef adc;

GPIO_InitTypeDef io_b;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB,ENABLE);

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

io_b.GPIO_Pin = GPIO_Pin_1;

io_b.GPIO_Mode = GPIO_Mode_AIN;

io_b.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB,&io_b);

ADC_DeInit(ADC1);

ADC_TempSensorVrefintCmd(ENABLE);

adc.ADC_Mode = ADC_Mode_Independent;

adc.ADC_ScanConvMode = ENABLE;

adc.ADC_ContinuousConvMode = ENABLE;

adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

adc.ADC_DataAlign = ADC_DataAlign_Right;

adc.ADC_NbrOfChannel = 2;

ADC_Init(ADC1,&adc);

ADC_RegularChannelConfig(ADC1,ADC_Channel_9,1,ADC_SampleTime_239Cycles5);

ADC_RegularChannelConfig(ADC1,ADC_Channel_17,2,ADC_SampleTime_239Cycles5);

ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);

ADC_Cmd(ADC1,ENABLE);

ADC_ResetCalibration(ADC1);

while(ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);

while(ADC_GetCalibrationStatus(ADC1));

ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}

 

void adc_nvic_init()

{

NVIC_InitTypeDef nvic;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

nvic.NVIC_IRQChannel = ADC1_2_IRQn;

nvic.NVIC_IRQChannelCmd = ENABLE;

nvic.NVIC_IRQChannelPreemptionPriority = 1;

nvic.NVIC_IRQChannelSubPriority = 1;

NVIC_Init(&nvic);

NVIC_InitTypeDef usart1;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

usart1.NVIC_IRQChannel = USART1_IRQn;

usart1.NVIC_IRQChannelCmd = ENABLE;

usart1.NVIC_IRQChannelPreemptionPriority = 0;

usart1.NVIC_IRQChannelSubPriority= 0;

NVIC_Init(&usart1);

}

 

void usart_init()

{

GPIO_InitTypeDef Uart_A;  

      

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);  

    Uart_A.GPIO_Pin = GPIO_Pin_9;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOA,&Uart_A);  

      

    Uart_A.GPIO_Pin = GPIO_Pin_10;  

    Uart_A.GPIO_Speed = GPIO_Speed_50MHz;  

    Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; 

    GPIO_Init(GPIOA,&Uart_A);   

USART_InitTypeDef Uart;  

      

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  

    Uart.USART_BaudRate = 115200;  

    Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

    Uart.USART_Mode = USART_Mode_Tx;  

    Uart.USART_Parity = USART_Parity_No;  

    Uart.USART_StopBits = USART_StopBits_1;  

    Uart.USART_WordLength = USART_WordLength_8b;  

    USART_Init(USART1,&Uart);  

      

    USART_Cmd(USART1,ENABLE);  

    USART_ClearFlag(USART1,USART_FLAG_TC); 

}

int main()

{

void PrintU16(uint16_t num);

void PrintHexU8(uint8_t data);

 

Adc_Init();

adc_nvic_init();

usart_init();

while(1)

{

num = (uint16_t)(2.0f* ADC_ConvertedValue/ADC_ConvertedValue_1 *1.2f*100 );

 

PrintU16(num);

delay(1000);

}

}

 

void PrintU16(uint16_t num)

{

void PrintHexU8(uint8_t data);

uint8_t w5,w4,w3,w2,w1;

w5 = num % 100000/10000;

w4 = num % 10000/1000;

w3 = num % 1000/100;

w2 = num % 100/10;

w1 = num % 10;

PrintHexU8('0' + w5);

PrintHexU8('0' + w4);

PrintHexU8('0' + w3);

PrintHexU8('0' + w2);

PrintHexU8('0' + w1);

}

 

void PrintHexU8(uint8_t data)

{

car = data;

if(!(USART1->CR1 & USART_CR1_TXEIE))

USART_ITConfig(USART1,USART_IT_TXE,ENABLE);//打开发送中断

}

 

void ADC1_2_IRQHandler()

{

if(ADC_GetITStatus(ADC1,ADC_IT_EOC) == SET)

{if(count_1%2 == 0){

ADC_ConvertedValue = ADC_GetConversionValue(ADC1);

count_1++;

}else

{

ADC_ConvertedValue_1 = ADC_GetConversionValue(ADC1);

count_1++;

}

}

ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);

}

 

void USART1_IRQHandler(void)

{

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE))

{

USART1->CR1 &= ~USART_CR1_TXEIE;

USART1->DR = car;

while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);

//USART1->CR1 &= ~USART_CR1_TXEIE;

}

if(USART1->SR & USART_SR_RXNE)

{

volatile int8_t com_data;

com_data = USART1->DR;

}

}



关键字:STM32  ADC转换  中断方式 引用地址:STM32基础设计(5)---ADC转换(中断方式)

上一篇:STM32基础设计(7)---时钟中断(控制LED灯)
下一篇:STM32基础设计(4)---DMA通信

推荐阅读最新更新时间:2024-03-16 16:23

stm32通用定时器的PWM输出
配置过程:(以TIM3为例,其CH1-CH4为:PA6、PA7、PB0、PB1) 1)开启TIM3时钟,配置4个IO口为复用推挽输出。 2)设置TIM3的ARR和PSC来控制PWM的周期。 3)设置TIM3的CH1-CH4的PWM模式及通道方向,使能TIM3的CH1-CH4输出。 4)使能TIM3。 程序如下: /* * 函数名:TIM3_GPIO_Config * 描述 :配置TIM3复用输出PWM时用到的I/O * 输入 :无 * 输出 :无 * 调用 :内部调用 */ void TIM3_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; //PCLK1经
[单片机]
基于STM32的嵌入式测控系统设计与实现
测控系统是水动力实验中的重要测试设备。在实验中有压力、拉力、加速度等物理量通过传感器转换成电压值,需要准确记录。虽然实验模型有很多种,但是共用传感器及测控系统,因此对测控系统的通用性和用户界面友好性提出了要求。本文采用嵌入式架构设计了测控系统。 本文设计的系统硬件基于STM32芯片,具有很强的扩展能力,易于移植,其外设单元资源丰富,能够达到系统要求的精度和范围。 1、硬件架构 采用嵌入式架构(见图1)的优点是通用性强,便于在多平台移植;主控芯片外围电路模块丰富,包括ADC、DA、CAN和SDIO等接口,独立完成对多种类型设备的测量、控制。芯片的主频高,运算能力也很强,适合嵌入复杂的算法。完全适合作为测控系统,具备系统升级
[单片机]
基于<font color='red'>STM32</font>的嵌入式测控系统设计与实现
STM32定时器的分类及中断原理
本文主要介绍常规定时器中的TIM3,实现定时器中断的功能。STM32定时器的分类在其中一篇文章中已经介绍过,本文主要内容主要介绍定时器的基础功能-定时器中断,对于STM32定时器分类简单复习一下。 一、STM32定时器的分类 1.1 按照内核、外核、特定、常规分为4大类: 1)内核定时器:Systick 2)外设定时器:特定应用定时器+常规定时器 3)特定应用定时器:LPTIM,RTC,WTD,HRTIM 4)常规定时器:基本定时器TIM6&TIM7)、通用定时器(TIM2TIM5,TIM9TIM14)、高级定时器(TIM1&TIM8) 1.2 CPU时序 此处我们提一下学习单片机原理的课程时,提到的几个CPU时序。
[单片机]
<font color='red'>STM32</font>定时器的分类及<font color='red'>中断</font>原理
基于STM32LED书写点阵屏设计与实现
近年来,随着信息产业的高速发展,点阵LED 显示屏已广泛应用于金融行业、邮电行业、体育馆、广告业等各种广告发布和信息显示系统,成为信息传送的重要手段。本文介绍的LED 书写点阵屏,不但可以像普通显示屏一样作为信息输出设备,而且可以通过光笔直接在LED 显示屏上进行信息输入,普通的显示屏也具有"手写"的功能了。 1 硬件系统设计 本系统总体框图如图1 所示,由键盘与显示模块、光笔模块、LED 点阵屏模块、STM32 控制模块、电源模块五部分组成。 图1 总体方案方框图 1. 1 核心控制模块 本系统以STM32F103VCT6 为控制核心。 STM32 是32 位微处理器,具有低功耗,中断延迟小,高性能等特点
[单片机]
基于STM32LED书写点阵屏设计与实现
ADC0809A/D转换器基本应用技术
1. 基本知识 ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。它是逐次逼近式A/D转换器,可以和单片机直接接口。 (1). ADC0809的内部逻辑结构 8路模拟量开关 8路A/D转换器 三态输出锁存器 地址锁存与译码器 IN0 IN1 IN2 IN3 IN4 IN5 IN6 IN7 A B C ALE VREF(+) VREF(-) OE EOC D0 D1 D2 D3 D4 D5 D6 D7 CLK ST 由上图可知,ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共
[单片机]
<font color='red'>ADC</font>0809A/D<font color='red'>转换</font>器基本应用技术
巧用外设复位修改只读寄存器
有STM32开发者用到STM32F429芯片开发产品,并用到其中的CAN外设。在CAN应用过程中有个专门针对收发出错情况进行次数统计的两个计数器,其值通过错误状态寄存器CAN_ESR中的REC 和TEC 两个字段来体现,CAN硬件会根据错误数据大小做适当响应或处理。 根据寄存器描述得知,TEC 和REC 的值在这个寄存器里面是只读的。而此时的STM32用户有个强烈的需求,就是期望能适时地对这两个出错记录字段做清零。他自己也尝试编写一些代码想让二者清零,均以失败告终,便邮件咨询有无解决办法。 我们在阅读CAN_ESR寄存器内容时倒有个发现,即该寄存器的复位值是0x00000000。 也就是说,芯片每次复位后其值一定是0,
[单片机]
巧用外设复位修改只读寄存器
你了解ADC吗?模数转换器(ADC)不同类型数字输出深
在当今的模数转换器(ADC)领域,ADC制造商主要采用三类数字输出。这三种输出分别是:互补金属氧化物半导体(CMOS)、低压差分信号(LVDS)和电流模式逻辑(CML)。每类输出均基于采样速率、分辨率、输出数据速率和功耗要求,根据其工作方式和在ADC设计中的典型应用方式进行了论述。本文将讨论如何实现这些接口,以及各类输出的实际应用,并探讨选择和使用不同输出时需要注意的事项。此外还会给出关于如何处理这些输出的一般指南,并讨论各类输出的优劣。   基本知识   使用数字接口时,无论何种数字输出,都有一些相同的规则和事项需要考虑。首先,为实现最佳端接,接收器(FPGA或ASIC)端最好使用真正的电阻终端。接收器端的反射可能会破坏系统
[模拟电子]
你了解<font color='red'>ADC</font>吗?<font color='red'>模数转换</font>器(<font color='red'>ADC</font>)不同类型数字输出深
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved