本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。
前面章节我们讲解了基本定时器和高级控制定时器功能,这一章我们将介绍定时器输入捕获一个应用实例,帮助我们更加深入理解定时器。
33.1 电容按键原理
电容器(简称为电容)就是可以容纳电荷的器件,两个金属块中间隔一层绝缘体就可以构成一个最简单的电容。如图 331(俯视图),有两个金属片,之间有一个绝缘介质,这样就构成了一个电容。这样一个电容在电路板上非常容易实现,一般设计四周的铜片与电路板地信号连通,这样一种结构就是电容按键的模型。当电路板形状固定之后,该电容的容量也是相对稳定的。
图 331 片状电容器
电路板制作时都会在表面上覆盖一层绝缘层,用于防腐蚀和绝缘,所以实际电路板设计时情况如图 332。电路板最上层是绝缘材料,下面一层是导电铜箔,我们根据电路走线情况设计决定铜箔的形状,再下面一层一般是FR-4板材。金属感应片与地信号之间有绝缘材料隔着,整个可以等效为一个电容Cx。一般在设计时候,把金属感应片设计成方便手指触摸大小。
图 332 无手指触摸情况
在电路板未上电时,可以认为电容Cx是没有电荷的,在上电时,在电阻作用下,电容Cx就会有一个充电过程,直到电容充满,即Vc电压值为3.3V,这个充电过程的时间长短受到电阻R阻值和电容Cx容值的直接影响。但是在我们选择合适电阻R并焊接固定到电路板上后,这个充电时间就基本上不会变了,因为此时电阻R已经是固定的,电容Cx在无外界明显干扰情况下基本上也是保持不变的。
现在,我们来看看当我们用手指触摸时会是怎样一个情况?如图 333,当我们用手指触摸时,金属感应片除了与地信号形成一个等效电容Cx外,还会与手指形成一个Cs等效电容。
图 333 有手指触摸情况
此时整个电容按键可以容纳的电荷数量就比没有手指触摸时要多了,可以看成是Cx和Cs叠加的效果。在相同的电阻R情况下,因为电容容值增大了,导致需要更长的充电时间。也就是这个充电时间变长使得我们区分有无手指触摸,也就是电容按键是否被按下。
现在最主要的任务就是测量充电时间。充电过程可以看出是一个信号从低电平变成高电平的过程,现在就是要求出这个变化过程的时间,这样的一个命题与上一章讲解高级控制定时器的输入捕获功能非常吻合。我们可以利用定时器输入捕获功能计算充电时间,即设置TIMx_CH为定时器输入捕获模式通道。这样先测量得到无触摸时的充电时间作为比较基准,然后再定时循环测量充电时间与无触摸时的充电时间作比较,如果超过一定的阈值就认为是有手指触摸。
图 334为Vc跟随时间变化情况,可以看出在无触摸情况下,电压变化较快;而在有触摸时,总的电容量增大了,电压变化缓慢一些。
图 334 Vc电压与充电时间关系
为测量充电时间,我们需要设置定时器输入捕获功能为上升沿触发,图 334中VH就是被触发上升沿的电压值,也是STM32认为是高电平的最低电压值,大约为1.8V。t1和t2可以通过定时器捕获/比较寄存器获取得到。
不过,在测量充电时间之前,我们必须想办法制作这个充电过程。之前的分析是在电路板上电时会有充电过程,现在我们要求在程序运行中循环检测按键,所以必须可以控制充电过程的生成。我们可以控制TIMx_CH引脚作为普通的GPIO使用,使其输出一小段时间的低电平,为电容Cx放电,即Vc为0V。当我们重新配置TIMx_CH为输入捕获时电容Cx在电阻R的作用下就可以产生充电过程。
33.2 电容按键检测实验
电容按键不需要任何外部机械部件,使用方便,成本低,很容易制成与周围环境相密封的键盘,以起到防潮防湿的作用。电容按键优势突出使得越来越多电子产品使用它代替传统的机械按键。
本实验实现电容按键状态检测方法,提供一个编程实例。
33.2.1 硬件设计
开发板板载一个电容按键,原理图设计参考图 335。
图 335 电容按键电路设计
标示TPAD1在电路板上就是电容按键实体,它通过一根导线连接至定时器通道引脚,这里选用的电阻阻值为1M。
实验还用到调试串口和蜂鸣器功能,用来打印输入捕获信息和指示按键状态,这两个模块电路可参考之前相关章节。
33.2.2 软件设计
这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们创建了两个文件:bsp_touchpad.c和bsp_touchpad.h文件用来存放电容按键检测相关函数和宏定义。
1. 编程要点
(1) 初始化蜂鸣器、调试串口以及系统滴答定时器;
(2) 配置定时器基本初始化结构体并完成定时器基本初始化;
(3) 配置定时器输入捕获功能;
(4) 使能电容按键引脚输出低电平为电容按键放电;
(5) 待放电完整后,配置为输入捕获模式,并获取输入捕获值,该值即为无触摸时输入捕获值;
(6) 循环执行电容按键放电、读取输入捕获值检过程,将捕获值与无触摸时捕获值对比,以确定电容按键状态。
2. 软件分析
宏定义
代码清单 331 宏定义
1 #define TPAD_TIMx TIM2
2 #define TPAD_TIM_CLK RCC_APB1Periph_TIM2
3
4 #define TPAD_TIM_Channel_X TIM_Channel_1
5 #define TPAD_TIM_IT_CCx TIM_IT_CC1
6 #define TPAD_TIM_GetCaptureX TIM_GetCapture1
7
8 #define TPAD_TIM_GPIO_CLK RCC_AHB1Periph_GPIOA
9 #define TPAD_TIM_CH_PORT GPIOA
10 #define TPAD_TIM_CH_PIN GPIO_Pin_5
11 #define TPAD_TIM_AF GPIO_AF_TIM2
12 #define TPAD_TIM_SOURCE GPIO_PinSource5
使用宏定义非常方便程序升级、移植。
开发板选择使用通用定时器2的通道1连接到电容按键,对应的引脚为PA5。
定时器初始化配置
代码清单 332 定时器初始化配置
1 static void TIMx_CHx_Cap_Init(uint32_t arr,uint16_t psc)
2 {
3 GPIO_InitTypeDef GPIO_InitStructure;
4 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
5 TIM_ICInitTypeDef TIM_ICInitStructure;
6
7 //使能TIM时钟
8 RCC_APB1PeriphClockCmd(TPAD_TIM_CLK,ENABLE);
9 //使能通道引脚时钟
10 RCC_AHB1PeriphClockCmd(TPAD_TIM_GPIO_CLK, ENABLE);
11 //指定引脚复用
12 GPIO_PinAFConfig(TPAD_TIM_CH_PORT,TPAD_TIM_SOURCE,TPAD_TIM_AF);
13
14 //端口配置
15 GPIO_InitStructure.GPIO_Pin = TPAD_TIM_CH_PIN;
16 //复用功能
17 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
18 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
19 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
20 //不带上下拉
21 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
22 GPIO_Init(TPAD_TIM_CH_PORT, &GPIO_InitStructure);
23
24 //初始化TIM
25 //设定计数器自动重装值
26 TIM_TimeBaseStructure.TIM_Period = arr;
27 //预分频器
28 TIM_TimeBaseStructure.TIM_Prescaler =psc;
29 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
30 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
31 TIM_TimeBaseInit(TPAD_TIMx, &TIM_TimeBaseStructure);
32 //初始化通道
33 //选择定时器输入通道
34 TIM_ICInitStructure.TIM_Channel = TPAD_TIM_Channel_X;
35 //上升沿触发
36 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
37 // 输入捕获选择
38 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
39 //配置输入分频,不分频
40 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
41 //配置输入滤波器不滤波
42 TIM_ICInitStructure.TIM_ICFilter = 0x00;
43 TIM_ICInit(TPAD_TIMx, &TIM_ICInitStructure);
44 //使能TIM
45 TIM_Cmd ( TPAD_TIMx, ENABLE );
46 }
首先定义三个初始化结构体变量,这三个结构体之前都做了详细的介绍,可以参考相关章节理解。
使用外设之前都必须开启相关时钟,这里开启定时器时钟和定时器通道引脚对应端口时钟,并指定定时器通道引脚复用功能。
接下来初始化配置定时器通道引脚为复用功能,无需上下拉。
然后,配置定时器功能。定时器周期和预分频器值由函数形参决定,采用向上计数方式。指定输入捕获通道,电容按键检测需要采用上升沿触发方式。
最后,使能定时器。
电容按键复位
代码清单 333 电容按键复位
1 static void TPAD_Reset(void)
2 {
3 GPIO_InitTypeDef GPIO_InitStructure;
4
5 //配置引脚为普通推挽输出
6 GPIO_InitStructure.GPIO_Pin = TPAD_TIM_CH_PIN;
7 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
8 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
9 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
10 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
11 GPIO_Init(TPAD_TIM_CH_PORT, &GPIO_InitStructure);
12
13 //输出低电平,放电
14 GPIO_ResetBits ( TPAD_TIM_CH_PORT, TPAD_TIM_CH_PIN );
15 //保持一小段时间低电平,保证放电完全
16 Delay_ms(5);
17
18 //清除中断标志
19 TIM_ClearITPendingBit(TPAD_TIMx, TPAD_TIM_IT_CCx|TIM_IT_Update);
20 //计数器归0
21 TIM_SetCounter(TPAD_TIMx,0);
22
23 //引脚配置为复用功能,不上、下拉
24 GPIO_InitStructure.GPIO_Pin = TPAD_TIM_CH_PIN;
25 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
26 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
27 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
28 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
29 GPIO_Init(TPAD_TIM_CH_PORT,&GPIO_InitStructure);
30 }
该函数实现两个主要功能:控制电容按键放电和复位计数器。
首先,配置定时器通道引脚作为普通GPIO,使其为下拉的推挽输出模式。然后调用GPIO_ResetBits函数输出低电平,为保证放电完整,需要延时一小会时间,这里调用Delay_ms函数完成5毫秒的延时。Delay_ms函数是定义在bsp_SysTick.h文件的一个延时函数,它利用系统滴答定时器功能实现毫秒级的精准延时。也因此要求在调用电容按键检测相关函数之前必须先初始化系统滴答定时器。
这里还需要一个注意的地方,在控制电容按键放电的整个过程定时器是没有停止的,计数器还是在不断向上计数的,只是现阶段计数值对我们来说没有意义而已。
然后,清除定时器捕获/比较标志位和更新中断标志位以及将定时器计数值赋值为0,使其重新从0开始计数。
最后,配置定时器通道引脚为定时器复用功能,不上下拉。在执行完该GPIO初始化函数后,电容按键就马上开始充电,定时器通道引脚电压就上升,当达到1.8V时定时器就输入捕获成功。所以在执行完TPAD_Reset函数后应用程序需要不断查询定时器输入捕获标志,在发送输入捕获时马上读取TIMx_CCRx寄存器的值,作为该次电容按键捕获值。
获取输入捕获值
代码清单 334 获取输入捕获值
1 //定时器最大计数值
2 #define TPAD_ARR_MAX_VAL 0XFFFF
3
4 static uint16_t TPAD_Get_Val(void)
5 {
6 /* 先放电完全,并复位计数器 */
7 TPAD_Reset();
8 //等待捕获上升沿
9 while (TIM_GetFlagStatus ( TPAD_TIMx, TPAD_TIM_IT_CCx ) == RESET) {
10 //超时了,直接返回CNT的值
11 if (TIM_GetCounter(TPAD_TIMx)>TPAD_ARR_MAX_VAL-500)
12 return TIM_GetCounter(TPAD_TIMx);
13 };
14 /* 捕获到上升沿后输出TIMx_CCRx寄存器值 */
15 return TPAD_TIM_GetCaptureX(TPAD_TIMx );
16 }
开始是TPAD_ARR_MAX_VAL的宏定义,它指定定时器自动重载寄存器(TIMx_ARR)的值。
TPAD_Get_Val函数用来获取一次电容按键捕获值,包括电容按键放电和输入捕获过程。
先调用TPAD_Reset函数完成电容按键放电过程,并复位计数器。
接下来,使用TIM_GetFlagStatus函数获取当前计数器的输入捕获状态,如果成功输入捕获就使用TPAD_TIM_GetCaptureX函数获取此刻定时器捕获/比较寄存器的值并返回该值。如果还没有发生输入捕获,说明还处于充电过程,就进入等待状态。
为防止无限等待情况,加上超时处理函数,如果发生超时则直接返回计数器值。实际上,如果发生超时情况,很大可能是硬件出现问题。
获取最大输入捕获值
代码清单 335 获取最大输入捕获值
1 static uint16_t TPAD_Get_MaxVal(uint8_t n)
2 {
3 uint16_t temp=0;
4 uint16_t res=0;
5 while (n--) {
6 temp=TPAD_Get_Val();//得到一次值
7 if (temp>res)res=temp;
8 };
9 return res;
10 }
该函数接收一个参数,用来指定获取电容按键捕获值的循环次数,函数的返回值则为n次发生捕获中最大的捕获值。
电容按键捕获初始化
代码清单 336 电容按键捕获初始化
1 uint8_t TPAD_Init(void)
2 {
3 uint16_t buf[10];
4 uint16_t temp;
5 uint8_t j,i;
6
7 //设定定时器预分频器目标时钟为:9MHz(180Mhz/20)
8 TIMx_CHx_Cap_Init(TPAD_ARR_MAX_VAL,20-1);
9 for (i=0; i<10; i++) { //连续读取10次
10 buf[i]=TPAD_Get_Val();
11 Delay_ms(10);
12 }
13 for (i=0; i<9; i++) { //排序
14 for (j=i+1; j<10; j++) {
15 if (buf[i]>buf[j]) { //升序排列
16 temp=buf[i];
17 buf[i]=buf[j];
18 buf[j]=temp;
19 }
20 }
21 }
22 temp=0;
23 //取中间的6个数据进行平均
24 for (i=2; i<8; i++) {
25 temp+=buf[i];
26 }
27
28 tpad_default_val=temp/6;
29 /* printf打印函数调试使用,用来确定阈值TPAD_GATE_VAL,在应用工程中应注释掉 */
30 printf("tpad_default_val:%drn",tpad_default_val);
31
32 //初始化遇到超过TPAD_ARR_MAX_VAL/2的数值,不正常!
33 if (tpad_default_val>TPAD_ARR_MAX_VAL/2) {
34 return 1;
35 }
36
37 return 0;
38 }
39
该函数实现定时器初始化配置和无触摸时电容按键捕获值确定功能。它一般在main函数靠前位置调用完成电容按键初始化功能。
程序先调用TIMx_CHx_Cap_Init函数完成定时器基本初始化和输入捕获功能配置,两个参数用于设置定时器的自动重载计数和定时器时钟频率,这里自动重载计数被赋值为TPAD_ARR_MAX_VAL,这里对该值没有具体要求,不要设置过低即可。定时器时钟配置设置为9MHz为合适,实验中用到TIM2,默认使用内部时钟为180MHz,经过参数设置预分频器为20分频,使定时器时钟为9MHz。
接下来,循环10次读取电容按键捕获值,并保存在数组内。TPAD_Init函数一般在开机时被调用,所以认为10次读取到的捕获值都是无触摸状态下的捕获值。
然后,对10个捕获值从小到大排序,取中间6个的平均数作为无触摸状态下的参考捕获值,并保存在tpad_default_val变量中,该值对应图 334中的时间t1。
程序最后会检测tpad_default_val变量的合法性。
电容按键状态扫描
代码清单 337 电容按键状态扫描
1 //阈值:捕获时间必须大于(tpad_default_val + TPAD_GATE_VAL),才认为是有效触摸.
2 #define TPAD_GATE_VAL 100
3
4 uint8_t TPAD_Scan(uint8_t mode)
5 {
6 //0,可以开始检测;>0,还不能开始检测
7 static uint8_t keyen=0;
8 //扫描结果
9 uint8_t res=0;
10 //默认采样次数为3次
11 uint8_t sample=3;
12 //捕获值
13 uint16_t rval;
14
15 if (mode) {
16 //支持连按的时候,设置采样次数为6次
17 sample=6;
18 //支持连按
19 keyen=0;
20 }
21 /* 获取当前捕获值(返回 sample 次扫描的最大值) */
22 rval=TPAD_Get_MaxVal(sample);
23 /* printf打印函数调试使用,用来确定阈值TPAD_GATE_VAL,在应用工程中应注释掉 */
24 // printf("scan_rval=%dn",rval);
25
26 //大于tpad_default_val+TPAD_GATE_VAL,且小于10倍tpad_default_val,则有效
27 if (rval>(tpad_default_val+TPAD_GATE_VAL)&&rval<(10*tpad_default_val)) {
28 //keyen==0,有效
29 if (keyen==0) {
30 res=1;
31 }
32 keyen=3; //至少要再过3次之后才能按键有效
33 }
34
35 if (keyen) {
36 keyen--;
37 }
38 return res;
39 }
TPAD_GATE_VAL用于指定电容按键触摸阈值,当实时捕获值大于该阈值和无触摸捕获参考值tpad_default_val之和时就认为电容按键有触摸,否则认为没有触摸。阈值大小一般需要通过测试得到,一般做法是通过串口在TPAD_Init函数中把tpad_default_val值打印到串口调试助手并记录下来,在TPAD_Scan函数中也把实时捕获值打印出来,在运行时触摸电容按键,获取有触摸时的捕获值,这样两个值对比就可以大概确定TPAD_GATE_VAL。
TPAD_Scan函数用来扫描电容按键状态,需要被循环调用,类似独立按键的状态扫描函数。它有一个形参,用于指定电容按键的工作模式,当为赋值为1时,电容按键支持连续触发,即当一直触摸不松开时,每次运行TPAD_Scan函数都会返回电容按键被触摸状态,直到松开手指,才返回无触摸状态。当参数赋值为0时,每次触摸函数只返回一次被触摸状态,之后就总是返回无触摸状态,除非松开手指再触摸。TPAD_Scan函数有一个返回值,用于指示电容按键状态,返回值为0表示无触摸,为1表示有触摸。
TPAD_Scan函数主要是调用TPAD_Get_MaxVal函数获取当前电容按键捕获值,该值这里指定在连续触发模式下取6次扫描的最大值为当前捕获值,如果是不连续触发只取三次扫描的最大值。正常情况下,如果无触摸,当前捕获值与捕获参考值相差很小;如果有触摸,当前捕获值比捕获参考值相差较大,此时捕获值对应图 334的时间t2。
接下来比较当前捕获值与无触摸捕获参考值和阈值之和的关系,以确定电容按键状态。这里为增强可靠性,还加了当前捕获值不能超过参考值的10倍的限制条件,因为超过10倍关系几乎可以认定为出错情况。
主函数
代码清单 338 main函数
1 int main(void)
2 {
3 /* 初始化蜂鸣器 */
4 Beep_GPIO_Config();
5
6 /* 初始化调试串口,一般为串口1 */
7 Debug_USART_Config();
8
9 /* 初始化系统滴答定时器 */
10 SysTick_Init();
11
12 /* 初始化电容按键 */
13 TPAD_Init();
14
15 while (1) {
16 if (TPAD_Scan(0)) {
17 BEEP_ON;
18 Delay_ms(100);
19 BEEP_OFF;
20 }
21 Delay_ms(50);
22 }
23 }
24
主函数分别调用Beep_GPIO_Config()、Debug_USART_Config()、和SysTick_Init()完成蜂鸣器、调试串口和系统滴答定时器参数。
TPAD_Init函数初始化配置定时器,并获取无触摸时的捕获参考值。
无限循环中调用TPAD_Scan函数完成电容按键状态扫描,指定为不连续触发方式。如果检测到有触摸就让蜂鸣器响100ms。
33.2.3 下载验证
上一篇:STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)
下一篇:第10章 新建工程-库函数版—零死角玩转STM32-F429系列
推荐阅读
史海拾趣
Analog Modules Inc. 是一家总部位于美国马萨诸塞州的公司,专注于设计和生产高性能模拟电子模块和系统,为军事、航空航天、医疗和工业等领域提供解决方案。以下是 Analog Modules Inc. 公司发展的相关故事:
创立与初期阶段:Analog Modules Inc. 成立于1970年,由一群电子工程师创办。公司最初的目标是满足军事和航天领域对高性能模拟电子模块的需求。在成立初期,公司致力于开发和生产高精度的模拟信号处理模块和系统,以满足客户对于高可靠性和高性能的要求。
技术创新与产品优化:Analog Modules Inc. 在技术方面不断进行创新,并持续优化其产品线。公司的产品涵盖了广泛的领域,包括模拟信号处理、数据采集、激光驱动、通信和雷达等。这些产品具有高精度、高可靠性和耐用性,得到了客户的广泛认可和信赖。
市场拓展与全球业务:随着业务的不断发展,Analog Modules Inc. 将市场重点逐渐扩展到了全球范围。公司与全球各地的客户建立了长期稳定的合作关系,拓展了产品的销售渠道和市场份额。同时,公司还积极参与国际展会和行业交流活动,提升了品牌知名度和影响力。
应用领域与客户合作:Analog Modules Inc. 的产品广泛应用于军事、航空航天、医疗和工业等多个领域。公司与各类客户进行紧密合作,包括政府军方、航空航天机构、医疗设备制造商和工业自动化企业等。通过与客户的合作,公司不断了解市场需求,提供定制化的解决方案,满足客户的特定需求。
持续发展与未来展望:Analog Modules Inc. 将继续致力于技术创新和产品研发,以满足不断变化的市场需求。公司将继续加强与客户和合作伙伴的合作关系,不断拓展业务领域,进一步提升产品性能和服务水平。在未来,Analog Modules Inc. 将继续保持行业领先地位,为客户提供更加优质和可靠的解决方案。
雅特力公司自成立以来,始终致力于技术创新和产品升级。在早期的发展阶段,公司便推出了一系列具有竞争力的电子产品,通过不断的技术突破,逐渐在市场中占据了一席之地。特别是在集成电路设计领域,雅特力凭借其高效能、低能耗的产品特性,赢得了众多客户的青睐。随着技术的不断进步,雅特力逐渐成为了电子行业的佼佼者,引领着市场的发展方向。
雅特力在追求经济效益的同时,也高度重视企业社会责任和可持续发展。公司积极参与社会公益事业,通过捐款、捐物等方式支持教育、环保等领域的发展。此外,雅特力还注重环境保护和资源利用,采用环保材料和节能技术,努力降低生产过程中的能耗和排放。这些举措不仅有助于提升公司的社会形象,也为实现可持续发展做出了积极贡献。
随着技术的不断积累,Babcock开始将研发重点转向市场需求旺盛的产品领域。通过深入分析市场趋势和客户需求,公司成功推出了一系列具有创新性和竞争力的电子产品。这些产品不仅性能卓越,而且设计新颖,很快便赢得了市场的广泛认可,为公司带来了可观的收益。
随着电子行业的快速发展和变革,Bogen Communications Inc公司面临着巨大的挑战。为了应对这些变革,公司不断调整战略、优化组织结构、提升研发能力。同时,公司还密切关注行业动态和市场需求,及时调整产品方向和市场策略。通过这些努力,公司成功地适应了行业变革,保持了稳健的发展态势。
为了进一步巩固市场地位和提升技术实力,EDAL公司开始通过收购和合作的方式拓展业务。公司成功收购了几家在EDA领域具有领先地位的公司,获得了更多的技术专利和市场份额。此外,EDAL公司还与其他科技公司建立了战略合作关系,共同研发新技术、新产品,推动整个EDA行业的发展。
1、在自己得到了别人的帮助以后,一定在最后总结一下,请不要一声不吭的走人。 总结的内容包括:1、问题到底出在哪里。2、通过第几楼的方法解决的。 这种总结,对其他人很有用,通过看总结他们可以知道第几楼的方法是对的。 在自己的求助帖最后 ...… 查看全部问答∨ |
请问什么是网络抖动?如何模拟、测量和抑制? 从来没关注过这个问题,突然上马竟然一点都不了解。到处询问身边的朋友居然没人知道,哥又寂寞了@~#¥&^@~#¥请各位高人给小弟指点迷津吧~跪谢了。… 查看全部问答∨ |
pb 5.0 中自带的.net compact framework是1.0的。vs2005用的是2.0的。 因此我想生成印象时将2.0的.net framework包含进去。 于是安装了WinCEPB50-071231-Product-Update-Rollup-Armv4I.msi这个补丁。 在**catalog items中的Applications and Ser ...… 查看全部问答∨ |
|
1. 请问是否可行? 2. 需要学习哪些方面的东西? 我没有做过开发,但是必须实现这个功能。只有最基本的编程能力。所用的芯片是TI的CC2531.芯片自带USB controller,例子程序里有基本的USB library,但是无法实现向PC读写文件。 谢谢。… 查看全部问答∨ |
我想在日历控件上(MFC的DateTimePicker控件)上弹出TAH(上下文菜单,类似pc上的右键弹出菜单),请问该如何实现,能给个例子吗? 网上的例子都千篇一律的出自codeproject上一位葡萄牙工程师的论文,看了几遍都没看懂,里面很多函数参数不知从何而来.不知大哥能否给小弟指导一下?感激不尽… 查看全部问答∨ |
本帖最后由 dontium 于 2015-1-23 13:26 编辑 请问有一线性调频信号要用ADS62P48进行采集,ADS62P48前变压器要怎么设计??? … 查看全部问答∨ |
介绍了程控恒流源电路的设计。该程控恒流源电路的原理是由单片机片内定时器输出的脉宽调 制信号产生可控的电压输出, 并用该电压控制恒流源产生可控电流 , 通过单片机的键盘接口对输出电流进行设定, 从而实现输出电流的连续凋节与电流的动态测量 ...… 查看全部问答∨ |