第17章     EXTI—外部中断/事件控制器

全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn

野火视频教程优酷观看网址:http://i.youku.com/firege

本章参考资料:《STM32F4xx中文参考手册》系统配置控制器以及中断和事件章节。

上一章节我们已经详细介绍了NVIC,对STM32F4xx中断管理系统有个全局的了解,我们这章的内容是NVIC的实例应用,也是STM32F4xx控制器非常重要的一个资源。学习本章时,配合《STM32F4xx中文参考手册》系统配置控制器以及中断和事件章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。

特别说明,本书内容是以STM32F42xxx系列控制器资源讲解。

17.1 EXTI简介

外部中断/事件控制器(EXTI)管理了控制器的23个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

17.2 EXTI功能框图

EXTI的功能框图包含了EXTI最核心内容,掌握了功能框图,对EXTI就有一个整体的把握,在编程时就思路就非常清晰。EXTI功能框图见图 171。

在图 171可以看到很多在信号线上打一个斜杠并标注"23"字样,这个表示在控制器内部类似的信号线路有23个,这与EXTI总共有23个中断/事件线是吻合的。所以我们只要明白其中一个的原理,那其他22个线路原理也就知道了。

图 171 EXTI功能框图

EXTI可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不同。

首先我们来看图 171中红色虚线指示的电路流程。它是一个产生中断的线路,最终信号流入到NVIC控制器内。

编号1是输入线,EXTI控制器有23个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个GPIO,也可以是一些外设的事件,这部分内容我们将在后面专门讲解。输入线一般是存在电平变化的信号。

编号2是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1给编号3电路,否则输出无效信号0。而EXTI_RTSR和EXTI_FTSR两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。

编号3电路实际就是一个或门电路,它一个输入来自编号2电路,另外一输入来自软件中断事件寄存器(EXTI_SWIER)。EXTI_SWIER允许我们通过程序控制就可以启动中断/事件线,这在某些地方非常有用。我们知道或门的作用就是有"就为1,所以这两个输入随便一个有有效信号1就可以输出1给编号4和编号6电路。

编号4电路是一个与门电路,它一个输入编号3电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。与门电路要求输入都为1才输出1,导致的结果如果EXTI_IMR设置为0时,那不管编号3电路的输出信号是1还是0,最终编号4电路输出的信号都为0;如果EXTI_IMR设置为1时,最终编号4电路输出的信号才由编号3电路的输出信号决定,这样我们可以简单的控制EXTI_IMR来实现是否产生中断的目的。编号4电路输出的信号会被保存到挂起寄存器(EXTI_PR)内,如果确定编号4电路输出为1就会把EXTI_PR对应位置1。

编号5是将EXTI_PR寄存器内容输出到NVIC内,从而实现系统中断事件控制。

接下来我们来看看绿色虚线指示的电路流程。它是一个产生事件的线路,最终输出一个脉冲信号。

产生事件线路是在编号3电路之后与中断线路有所不同,之前电路都是共用的。编号6电路是一个与门,它一个输入编号3电路,另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。如果EXTI_EMR设置为0时,那不管编号3电路的输出信号是1还是0,最终编号6电路输出的信号都为0;如果EXTI_EMR设置为1时,最终编号6电路输出的信号才由编号3电路的输出信号决定,这样我们可以简单的控制EXTI_EMR来实现是否产生事件的目的。

编号7是一个脉冲发生器电路,当它的输入端,即编号6电路的输出端,是一个有效信号1时就会产生一个脉冲;如果输入端是无效信号就不会输出脉冲。

编号8是一个脉冲信号,就是产生事件的线路最终的产物,这个脉冲信号可以给其他外设电路使用,比如定时器TIM、模拟数字转换器ADC等等。

产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传输,属于硬件级的。

另外,EXTI是在APB2总线上的,在编程时候需要注意到这点。

17.3 中断/事件线

EXTI有23个中断/事件线,每个GPIO都可以被设置为输入线,占用EXTI0至EXTI15,还有另外七根用于特定的外设事件,见表 171。

七根特定外设中断/事件线由外设触发,具体用法参考《STM32F4xx中文参考手册》中对外设的具体说明。

表 171 EXTI中断/事件线

中断/事件线

输入源

EXTI0

PX0(X可为A,B,C,D,E,F,G,H,I)

EXTI1

PX1(X可为A,B,C,D,E,F,G,H,I)

EXTI2

PX2(X可为A,B,C,D,E,F,G,H,I)

EXTI3

PX3(X可为A,B,C,D,E,F,G,H,I)

EXTI4

PX4(X可为A,B,C,D,E,F,G,H,I)

EXTI5

PX5(X可为A,B,C,D,E,F,G,H,I)

EXTI6

PX6(X可为A,B,C,D,E,F,G,H,I)

EXTI7

PX7(X可为A,B,C,D,E,F,G,H,I)

EXTI8

PX8(X可为A,B,C,D,E,F,G,H,I)

EXTI9

PX9(X可为A,B,C,D,E,F,G,H,I)

EXTI10

PX10(X可为A,B,C,D,E,F,G,H,I)

EXTI11

PX11(X可为A,B,C,D,E,F,G,H,I)

EXTI12

PX12(X可为A,B,C,D,E,F,G,H,I)

EXTI13

PX13(X可为A,B,C,D,E,F,G,H,I)

EXTI14

PX14(X可为A,B,C,D,E,F,G,H,I)

EXTI15

PX15(X可为A,B,C,D,E,F,G,H)

EXTI16

可编程电压检测器(PVD)输出

EXTI17

RTC闹钟事件

EXTI18

USB OTG FS唤醒事件

EXTI19

以太网唤醒事件

EXTI20

USB OTG HS(在FS中配置)唤醒事件

EXTI21

RTC入侵和时间戳事件

EXTI22

RTC唤醒事件

EXTI0至EXTI15用于GPIO,通过编程控制可以实现任意一个GPIO作为EXTI的输入源。由表 171可知,EXTI0可以通过SYSCFG外部中断配置寄存器1(SYSCFG_EXTICR1)的EXTI0[3:0]位选择配置为PA0、PB0、PC0、PD0、PE0、PF0、PG0、PH0或者PI0,见图 172。其他EXTI线(EXTI中断/事件线)使用配置都是类似的。

图 172 EXTI0输入源选择

17.4 EXTI初始化结构体详解

标准库函数对每个外设都建立了一个初始化结构体,比如EXTI_InitTypeDef,结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如EXTI_Init()调用,这些设定参数将会设置外设相应的寄存器,达到配置外设工作环境的目的。

初始化结构体和初始化库函数配合使用是标准库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在stm32f4xx_exti.h文件中,初始化库函数定义在stm32f4xx_exti.c文件中,编程时我们可以结合这两个文件内注释使用。

代码清单 171 EXTI初始化结构体

1 typedef struct {

2 uint32_t EXTI_Line; // 中断/事件线

3 EXTIMode_TypeDef EXTI_Mode; // EXTI模式

4 EXTITrigger_TypeDef EXTI_Trigger; // 触发事件

5 FunctionalState EXTI_LineCmd; // EXTI控制

6 } EXTI_InitTypeDef;

1)    EXTI_Line:EXTI中断/事件线选择,可选EXTI0至EXTI22,可参考表 171选择。

2)    EXTI_Mode:EXTI模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)。

3)    EXTI_Trigger:EXTI边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、下降沿触发( EXTI_Trigger_Falling)或者上升沿和下降沿都触发( EXTI_Trigger_Rising_Falling)。

4)    EXTI_LineCmd:控制是否使能EXTI线,可选使能EXTI线(ENABLE)或禁用(DISABLE)。

17.5 外部中断控制实验

中断在嵌入式应用中占有非常重要的地位,几乎每个控制器都有中断功能。中断对保证紧急事件得到第一时间处理是非常重要的

我们设计使用外接的按键来作为触发源,使得控制器产生中断,并在中断服务函数中实现控制RGB彩灯的任务。

17.5.1 硬件设计

轻触按键在按下时会使得引脚接通,通过电路设计可以使得按下时产生电平变化,见图 171。

图 173 按键电路设计

17.5.2 软件设计

这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们创建了两个文件:bsp_exti.c和bsp_exti.h文件用来存放EXTI驱动程序及相关宏定义,中断服务函数放在stm32f4xx_it.h文件中。

1.    编程要点

1)    初始化RGB彩灯的GPIO;

2)    开启按键GPIO时钟和SYSCFG时钟;

3)    配置NVIC;

4)    配置按键GPIO为输入模式;

5)    将按键GPIO连接到EXTI源输入;

6)    配置按键EXTI中断/事件线;

7)    编写EXTI中断服务函数。

2.    软件分析
按键和EXTI宏定义

代码清单 172 按键和EXTI 宏定义

1 //引脚定义

2 /*******************************************************/

3 #define KEY1_INT_GPIO_PORT GPIOA

4 #define KEY1_INT_GPIO_CLK RCC_AHB1Periph_GPIOA

5 #define KEY1_INT_GPIO_PIN GPIO_Pin_0

6 #define KEY1_INT_EXTI_PORTSOURCE EXTI_PortSourceGPIOA

7 #define KEY1_INT_EXTI_PINSOURCE EXTI_PinSource0

8 #define KEY1_INT_EXTI_LINE EXTI_Line0

9 #define KEY1_INT_EXTI_IRQ EXTI0_IRQn

10

11 #define KEY1_IRQHandler EXTI0_IRQHandler

12

13 #define KEY2_INT_GPIO_PORT GPIOC

14 #define KEY2_INT_GPIO_CLK RCC_AHB1Periph_GPIOC

15 #define KEY2_INT_GPIO_PIN GPIO_Pin_13

16 #define KEY2_INT_EXTI_PORTSOURCE EXTI_PortSourceGPIOC

17 #define KEY2_INT_EXTI_PINSOURCE EXTI_PinSource13

18 #define KEY2_INT_EXTI_LINE EXTI_Line13

19 #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn

20

21 #define KEY2_IRQHandler EXTI15_10_IRQHandler

使用宏定义方法指定与电路设计相关配置,这对于程序移植或升级非常有用的。

嵌套向量中断控制器NVIC配置

代码清单 173 NVIC配置

1 static void NVIC_Configuration(void)

2 {

3 NVIC_InitTypeDef NVIC_InitStructure;

4

5 /* 配置NVIC为优先级组1 */

6 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

7

8 /* 配置中断源:按键1 */

9 NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;

10 /* 配置抢占优先级:1 */

11 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

12 /* 配置子优先级:1 */

13 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

14 /* 使能中断通道 */

15 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

16 NVIC_Init(&NVIC_InitStructure);

17

,其他使用上面相关配置 */

19 NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;

20 NVIC_Init(&NVIC_InitStructure);

21 }

有关NVIC配置问题可参考上一章节内容,这里不做过多解释。

EXTI中断配置

代码清单 174 EXTI中断配置

1 void EXTI_Key_Config(void)

2 {

3 GPIO_InitTypeDef GPIO_InitStructure;

4 EXTI_InitTypeDef EXTI_InitStructure;

5

6 /*开启按键GPIO口的时钟*/

7 RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK|KEY2_INT_GPIO_CLK ,ENABLE);

8

9 /* 使能 SYSCFG 时钟,使用GPIO外部中断时必须使能SYSCFG时钟*/

10 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

11

12 /* 配置 NVIC */

13 NVIC_Configuration();

14

的引脚 */

16 GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;

17 /* 设置引脚为输入模式 */

18 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

19 /* 设置引脚不上拉也不下拉 */

20 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

21 /* 使用上面的结构体初始化按键 */

22 GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

23

24 /* 连接 EXTI 中断源到key1引脚 */

25 SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,

26 KEY1_INT_EXTI_PINSOURCE);

27

28 /* 选择 EXTI 中断源 */

29 EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;

30 /* 中断模式 */

31 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

32 /* 下降沿触发 */

33 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

34 /* 使能中断/事件线 */

35 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

36 EXTI_Init(&EXTI_InitStructure);

37

的引脚 */

39 GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;

40 /* 其他配置与上面相同 */

41 GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

42

43 /* 连接 EXTI 中断源到key2 引脚 */

44 SYSCFG_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE,

45 KEY2_INT_EXTI_PINSOURCE);

46

47 /* 选择 EXTI 中断源 */

48 EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;

49 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

50 /* 上升沿触发 */

51 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

52 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

53 EXTI_Init(&EXTI_InitStructure);

54 }

首先,使用GPIO_InitTypeDef和EXTI_InitTypeDef结构体定义两个用于GPIO和EXTI初始化配置的变量,关于这两个结构体前面都已经做了详细的讲解。

使用GPIO之前必须开启GPIO端口的时钟;用到EXTI必须开启SYSCFG时钟。

调用NVIC_Configuration函数完成对按键1、按键2优先级配置并使能中断通道。

作为中断/时间输入线把GPIO配置为输入模式,这里不使用上拉或下拉,有外部电路完全决定引脚的状态。

SYSCFG_EXTILineConfig函数用来指定中断/事件线的输入源,它实际是设定SYSCFG外部中断配置寄存器的值,该函数接收两个参数,第一个参数指定GPIO端口源,第二个参数为选择对应GPIO引脚源编号。

我们的目的是产生中断,执行中断服务函数,EXTI选择中断模式,按键1使用下降沿触发方式,并使能EXTI线。

按键2基本上采用与按键1相关参数配置,只是改为上升沿触发方式。

EXTI中断服务函数

代码清单 175 EXTI中断服务函数

1 void KEY1_IRQHandler(void)

2 {

3 //确保是否产生了EXTI Line中断

4 if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {

5 // LED1 取反

6 LED1_TOGGLE;

7 //清除中断标志位

8 EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);

9 }

10 }

11

12 void KEY2_IRQHandler(void)

13 {

14 //确保是否产生了EXTI Line中断

15 if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {

16 // LED2 取反

17 LED2_TOGGLE;

18 //清除中断标志位

19 EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);

20 }

21 }

当中断发生时,对应的中断服务函数就会被执行,我们可以在中断服务函数实现一些控制。

一般为确保中断确实发生,我们会在中断服务函数调用中断标志位状态读取函数读取外设中断标志位并判断标志位状态。

EXTI_GetITStatus函数用来获取EXTI的中断标志位状态,如果EXTI线有中断发生函数返回"SET"否则返回"RESET"。实际上,EXTI_GetITStatus函数是通过读取EXTI_PR寄存器值来判断EXTI线状态的。

按键1的中断服务函数我们让LED1翻转其状态,按键2的中断服务函数我们让LED2翻转其状态。执行任务后需要调用EXTI_ClearITPendingBit函数清除EXTI线的中断标志位。

主函数

代码清单 176 主函数

1 int main(void)

2 {

3 /* LED 端口初始化 */

4 LED_GPIO_Config();

5

6 /* 初始化EXTI中断,按下按键会触发中断,

7 * 触发中断会进入stm32f4xx_it.c文件中的函数

8 * KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。

9 */

10 EXTI_Key_Config();

11

12 /* 等待中断,由于使用中断方式,CPU不用轮询按键 */

13 while (1) {

14 }

15 }

主函数非常简单,只有两个任务函数。LED_GPIO_Config函数定义在bsp_led.c文件内,完成RGB彩灯的GPIO初始化配置。EXTI_Key_Config函数完成两个按键的GPIO和EXTI配置。

17.5.3 下载验证

保证开发板相关硬件连接正确,把编译好的程序下载到开发板。此时RGB彩色灯是暗的,如果我们按下开发板上的按键1,RGB彩灯变亮,再按下按键1,RGB彩灯又变暗;如果我们按下开发板上的按键2并弹开,RGB彩灯变亮,再按下开发板上的KEY2并弹开,RGB彩灯又变暗。

每课一问

1、    是否可以同时使用PA0和PB0中断?如果不可以,有什么解决方法。

2、    从硬件角度结合程序分析,为什么按下按键1RGB彩灯就马上变化,而按键2却需要按下按键再弹开之后RGB彩灯才变化?

第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列的更多相关文章

  1. 第17章 EXTI—外部中断/事件控制器

    第17章     EXTI—外部中断/事件控制器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  2. EXTI—外部中断/事件控制器

    外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线.每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测. EXTI 可以实现对每个中断/事件线进行单独 ...

  3. 第25章 串行FLASH文件系统FatFs—零死角玩转STM32-F429系列

    第25章     串行FLASH文件系统FatFs 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.c ...

  4. 第16章 STM32中断应用概览—零死角玩转STM32-F429系列

    第16章     STM32中断应用概览 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...

  5. 第36章 SDIO—SD卡读写测试—零死角玩转STM32-F429系列

    第36章     SDIO—SD卡读写测试 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...

  6. 第49章 在SRAM中调试代码—零死角玩转STM32-F429系列

    第49章     在SRAM中调试代码 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...

  7. 第24章 SPI—读写串行FLASH—零死角玩转STM32-F429系列

    第24章     SPI—读写串行FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  8. 第21章 DMA—直接存储区访问—零死角玩转STM32-F429系列

    第21章     DMA—直接存储区访问 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...

  9. 第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

    第47章     QR-Decoder-OV5640二维码识别 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.y ...

随机推荐

  1. 五种I/O模型的学习

    来自   http://www.52im.net/thread-1935-1-1.html 4.互联网服务端处理网络请求的原理 首先看看一个典型互联网服务端处理网络请求的典型过程:<ignore ...

  2. Jquery 获取table中的td元素的值

    <table id="t1"> <tr> <td> 1-1 </td> <td> 1-2 </td> < ...

  3. goodBye wordPress

    2016-07-28,我自己在GoDaddy上面注册了一个自己的域名,www.codetree.tech,同时在老薛主机上面购买了一个主机域名.我搭建了一个属于自己的博客,开心了很久.最近收到了域名续 ...

  4. & 和nohup使用

    " & "的使用  将工作丢到背景(这里指的背景并非是系统的背景,指的是在终端模式下,可以避免ctrl+c中断的一个情景)中去执行(但是如果终端关闭时,程序也就退出了,这时 ...

  5. SSRS 参数 单选 多选

    前段时间 公司要求报表的选项可以多选. 知道需求后,研究了下实现. 首先我们创建一个报表,然后添加3个数据集,2个参数,如下图. DataSet1数据集:存放主数据. ddl_emplid数据集:存放 ...

  6. Redis的原子自增性

    INCR key 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示为数字,那 ...

  7. Redis入门--(二)Redis的概述

    1.Redis的由来 创始人觉得Mysql不好用,就自己写了: 国内使用Redis的网站有新浪微博,知乎: 国外GitHub: VMWare也支持redis的开发 2.Redis的概述 官方提供的测试 ...

  8. agc001E - BBQ Hard(dp 组合数)

    题意 题目链接 Sol 非常妙的一道题目. 首先,我们可以把\(C_{a_i + b_i + a_j + b_j}^{a_i + a_j}\)看做从\((-a_i, -b_i)\)走到\((a_j, ...

  9. ASP.NET MVC 音乐商店 - 1 创建项目

    我们的项目从在 Visual Studio 中的文件菜单中选择“新建”,选择“项目”开始. 然后,选择 C# 中的 Web 模板组,在右边的项目模板中选择 ASP.NET MVC3 Web 应用程序, ...

  10. Java线程堆栈分析

    不知觉间工作已有一年了,闲下来的时候总会思考下,作为一名Java程序员,不能一直停留在开发业务使用框架上面.老话说得好,机会是留给有准备的人的,因此,开始计划看一些Java底层一点的东西,尝试开始在学 ...