简述嵌套向量中断控制器(NVIC)的主要特性。
答:STM32的嵌套向量中断控制器(NVIC) 管理着包括Cortex-M3核异常等中断,其和ARM处理器核的接口紧密相连,可以实现低延迟的中断处理,并有效地处理晚到的中断。STM32嵌套向量中断控制器(NVIC)的主要特性如下: q 具有43 个可屏蔽中断通道(不包含16 个Cortex-M3 的中断线)。 q 具有16 个可编程的优先等级。 q 可实现低延迟的异常和中断处理。 q 具有电源管理控制。 q 系统控制寄存器的实现。
1.简述STM32的ADC系统的功能特性。
答:STM32的ADC系统的主要功能特性包括如下几个方面:ADC开关控制、ADC时钟、ADC通道选择、ADC的转换模式、中断、模拟看门狗、ADC的扫描模式、ADC的注入通道管理、间断模式、ADC的校准模式、ADC的数据对齐、可编程的通道采样时间、外部触发转换、DMA请求、双ADC模式和温度传感器。
2.简述STM32的双ADC工作模式。
答:在有两个ADC的STM32器件中,可以使用双ADC模式。在双ADC模式里,根据ADC_CR1寄存器中DUALMOD[2:0]位所选的模式,转换的启动可以是ADC1主和ADC2从的交替触发或同时触发。双ADC工作模式主要包括如下几种:同时注入模式、同时规则模式、快速交替模式、慢速交替模式、交替触发模式和独立模式。
1.简述STM32的USART的功能特点。、
答:STM32的USART为通用同步异步收发器,其可以与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART还可以利用分数波特率发生器提供宽范围的波特率选择。
STM32的USART支持同步单向通信和半双工单线通信。同时,其也支持LIN(局部互连网),智能卡协议和IrDA(红外数据)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。STM32还具备多处理器通信能力。另外,通过多缓冲器配置的DMA方式,还可以实现高速数据通信。
1.简述STM32的高级控制定时器TIM1的结构。
答:STM32提供了一个高级控制定时器(TIM1)。TIM1由一个16位的自动装载计数器组成,它由一个可编程预分频器驱动。TIM1适合多种用途,包含测量输入信号的脉冲宽度,或者产生输出波形。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。 高级控制定时器TIM1和通用控制定时器TIMx是完全独立的,它们不共享任何资源,因此可以同步操作。
2.简述STM32时钟的类型。
答:STM32提供了三种不同的时钟源,其都可被用来驱动系统时钟SYSCLK,这三种时钟源分别为:q HSI振荡器时 q HSE振荡器时钟 q PLL时钟 这三种时钟源还可以有以下2种二级时钟源:
q 32kHz低速内部RC,可以用于驱动独立看门狗和RTC。其中,RTC用于从停机/待机模式下自动唤醒系统。
q 低速外部晶振也可用来驱动RTC(RTCCLK)。
任一个时钟源都可被独立地启动或关闭,这样可以通过关闭不使用的时钟源来优化整个系统的功耗。
1.简述DMA控制器的基本功能。
答:STM32的DMA 控制器有7个通道,每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA 请求的优先权。DMA 控制器和Cortex-M3 核共享系统数据线执行直接存储器数据传输。因此,1 个DMA请求占用至少2 个周期的CPU 访问系统总线时间。为了保证Cortex-M3 核的代码执行的最小带宽,DMA 控制器总是在2 个连续的DMA 请求间释放系统时钟至少1 个周期。
NVIC和外部中断:配置中断0(LED绿灯闪1次),中断1(LED蓝灯闪2次),中断2三个中断(LED绿灯闪3次),执行顺序为0-->1-->2 。(默认中断0闪烁的是绿灯)按下按键,绿灯闪(一亮一灭)1次,蓝灯闪2次,然后绿灯闪3次,
中断结束。 #include \ #include \ #include \ #include \ #include \
/* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void Init_GPIOs (void); void Delay(uint32_t nTime); void USART_Configuration(void); void EXTI_Configuration(void); void NVIC_Configuration(void);
static volatile uint32_t TimingDelay; int main(void)
{ /* Configure Clocks for Application need */ RCC_Configuration();
SysTick_Config(/ 2000); NVIC_Configuration(); /* Init I/O ports */ Init_GPIOs();
USART_Configuration(); EXTI_Configuration();
.#else...#endif结构的作用是根据预编译条件决定中断向量表起始地址*/ #ifdef VECT_TAB_RAM
/* 中断向量表起始地址从 0x 开始 */
NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0); #else /* VECT_TAB_FLASH */
/* 中断向量表起始地址从 0x 开始 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0); #endif
/* 选择NVIC优先级分组2 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* 使能EXIT 0通道 ,2级先占优先级 ,0级次占优先级 */ = TIM2_IRQn; = 0; = 0;
= ENABLE;
NVIC_Init(&NVIC_InitStructure); }
#include \ #include \
extern uint16_t CCR1_Val; /*声明输出比较通道1计数周期变量*/
extern uint16_t CCR2_Val; extern uint16_t CCR3_Val; extern uint16_t CCR4_Val; void NMI_Handler(void) {}
void HardFault_Handler(void)
{ /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } }
void MemManage_Handler(void)
{ /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } }
void BusFault_Handler(void)
{ /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } }
void UsageFault_Handler(void)
{ /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } }
void SVC_Handler(void){}
void DebugMon_Handler(void){} void PendSV_Handler(void){} void SysTick_Handler(void)
{ // TimingDelay_Decrement(); }
void DMA1_Channel1_IRQHandler (void){} void RTC_WKUP_IRQHandler(void){} void TIM2_IRQHandler(void) {
uint16_t capture=0;/*当前捕获计数值局部变量*/
/*TIM时钟=32M,分频数=1599+1,TIM2 counter clock=10khz CC1更新率=TIM2counter clock/CCRX_Val*/
if(TIM_GetITStatus(TIM2,TIM_IT_CC1)!=RESET) {
GPIO_WriteBit(GPIOB,GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_6)));
/*读出当前计数值*/
capture=TIM_GetCapture1(TIM2);
/*根据当前计数值更新输出捕获寄存器*/ TIM_SetCompare1(TIM2,capture+CCR1_Val); TIM_ClearITPendingBit(TIM2,TIM_IT_CC1); }
else if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET) {
GPIO_WriteBit(GPIOB,GPIO_Pin_7,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_7)));
capture=TIM_GetCapture2(TIM2);
TIM_SetCompare2(TIM2,capture+CCR2_Val); TIM_ClearITPendingBit(TIM2,TIM_IT_CC2); }
//else if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!=RESET) // { //
GPIO_WriteBit(GPIOA,GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_6)));
// capture=TIM_GetCapture3(TIM2);
// TIM_SetCompare3(TIM2,capture+CCR3_Val); // TIM_ClearITPendingBit(TIM2,TIM_IT_CC3); //}
//else if(TIM_GetITStatus(TIM2,TIM_IT_CC4)!=RESET) //{
//GPIO_WriteBit(GPIOA,GPIO_Pin_7,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_7)));
// capture=TIM_GetCapture4(TIM2);
// TIM_SetCompare4(TIM2,capture+CCR4_Val); // TIM_ClearITPendingBit(TIM2,TIM_IT_CC4); //} }
* @}
按键按一下,LED3和LED4灯亮,松开按键,再次按下按键,LED3和LED4灯灭。 * 使用GPIO和SysTick定时器实现按键扫描**/ #include \ #include \ #include \ #include \
/* Private function prototypes */
void RCC_Configuration(void); /*系统时钟设置*/
void Init_GPIOs (void); /*GPIO端口设置*/ void Delay(uint32_t nTime);
static volatile uint32_t TimingDelay; /*定义静态变量*/ int main(void)
{ /* Configure Clocks for Application need */ RCC_Configuration();
SysTick_Config(/ 2000); /*设置SysTick时钟*/ /* Init I/O ports */
Init_GPIOs(); while(1)
{ //GPIO_TOGGLE(LD_GPIO_PORT ,LD_GREEN_GPIO_PIN ); //Delay(1000);
if(GPIO_ReadInputDataBit(USERBUTTON_GPIO_PORT, USERBUTTON_GPIO_PIN)==0x01) { Delay(2000); /*延时1秒,即按1秒以上才翻转*/
if(GPIO_ReadInputDataBit(USERBUTTON_GPIO_PORT, USERBUTTON_GPIO_PIN)==0x01) { GPIO_TOGGLE(LD_GPIO_PORT ,LD_GREEN_GPIO_PIN ); /*翻转输出电平*/ GPIO_TOGGLE(LD_GPIO_PORT ,LD_BLUE_GPIO_PIN ); }
while(GPIO_ReadInputDataBit(USERBUTTON_GPIO_PORT, USERBUTTON_GPIO_PIN)==0x01); } } }
void RCC_Configuration(void) { RCC_DeInit();
RCC_HSICmd(ENABLE); /* 使能HSI时钟 */ /* 等待 HSI 稳定*/
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); /*选择HIS为系统时钟源*/ RCC_MSIRangeConfig(RCC_MSIRange_6);
RCC_HSEConfig(RCC_HSE_OFF); /*关闭HSE时钟*/ if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET ) /*等待关闭 稳定*/ {
while(1); }
/* Enable comparator clock LCD and PWR mngt */
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD | RCC_APB1Periph_PWR, ENABLE); 使能APB1外设时钟*/
/* Enable ADC clock & SYSCFG */
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG, ENABLE); /*使能APB2外设时钟*/ }
void Init_GPIOs (void)
{ GPIO_InitTypeDef GPIO_InitStructure; /* 使能AHB时钟*/
RCC_AHBPeriphClockCmd(LD_GPIO_PORT_CLK|USERBUTTON_GPIO_CLK, ENABLE); /* 选择输入管脚 */ = USERBUTTON_GPIO_PIN;
= GPIO_Mode_IN; //浮空输入 = GPIO_PuPd_NOPULL; = GPIO_Speed_40MHz;
GPIO_Init(USERBUTTON_GPIO_PORT, &GPIO_InitStructure);
/*/* 选择输出管脚*/
= LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN; = GPIO_Mode_OUT; = GPIO_OType_PP; = GPIO_PuPd_NOPULL; = GPIO_Speed_2MHz;
GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure); GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); /* Enable all GPIOs clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD |
RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, ENABLE); }
void Delay(uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); }
void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } }