NVIC介绍
NVIC的含义是“Nested Vectored Interrupt Controller”,即嵌套向量中断控制器。
NVIC是负责控制和管理微控制器中中断的硬件组件,它允许处理器在响应一个中断时处理更高优先级的嵌套中断。通过配置NVIC寄存器,可以控制内核和片上外设的中断。NVIC在微控制器的运作中起着至关重要的作用,因为它决定了中断的响应顺序和优先级。
中断执行流程

NVIC基本结构

NVIC根据优先级分组
NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级
抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队

NVIC配置

设置优先级分组模式(五种参数)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC结构体

参数一:选择中断通道
参数二:是否使能通道
参数三:抢占优先级
参数四:子优先级
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //子优先级
设置中断(需要结合GPIO、USART一同配置)
#include "Usart.h"
stPeriQueue gTxQueue;
/*串口外设初始化*/
void LeNvUsart_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
/*初始化LED*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/*初始化子板外设*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
/*串口初始化*/
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&USART_InitStruct);
/*开启串口响应中断*/
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_ITConfig(USART1,USART_IT_TC,ENABLE);
/*中断配置*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//选择USART1中断
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //子优先级
NVIC_Init(&NVIC_InitStruct);
/*清除USART中断挂起位的函数*/
USART_ClearITPendingBit(USART1, USART_IT_TC | USART_IT_RXNE);
/*使能串口*/
USART_Cmd(USART1,ENABLE);
}
int rd = 0;
unsigned char Buff[100];
int Index = 0;
/*串口中断*/
void USART1_IRQHandler(void)
{
unsigned char Data;
if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
{
// Data = USART_ReceiveData(USART1);
// if(Index < 100)
// {
// Buff[Index++] = Data;
// }
// else
// {
// Index = 0;
// }
}
if(USART_GetITStatus(USART1,USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_TC);
rd = PeriQueue_Rd(&gTxQueue,Data,1);
if(rd > 0)
{
USART_SendData(USART1,Data[0]);
}
}
}
/*串口写进缓冲区*/
void USART1_WrToQueue(unsigned char* pSendData,int SendLen)
{
PeriQueue_Init(&gTxQueue);
PeriQueue_Wr(&gTxQueue,pSendData,SendLen);
}
/*串口中断发送*/
void USART1_StartITSend(void)
{
unsigned char Data[1];
if(USART_GetITStatus(USART1,USART_IT_TC) == RESET)
{
rd = PeriQueue_Rd(&gTxQueue,Data,1);
if(rd > 0)
{
USART_SendData(USART1,Data[0]);
}
}
}

3577

被折叠的 条评论
为什么被折叠?



