#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE ((uint16_t)0x0360)
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
跟踪到这个函数:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
{
uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
uint32_t usartxbase = 0x00;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_CONFIG_IT(USART_IT));
assert_param(IS_FUNCTIONAL_STATE(NewState));
/* The CTS interrupt is not available for UART4 and UART5 */
if (USART_IT == USART_IT_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
usartxbase = (uint32_t)USARTx;
/* Get the USART register index */
usartreg = (((uint8_t)USART_IT) >> 0x05);
/* Get the interrupt position */
itpos = USART_IT & IT_Mask;
itmask = (((uint32_t)0x01) << itpos);
if (usartreg == 0x01) /* The IT is in CR1 register */
{
usartxbase += 0x0C;
}
else if (usartreg == 0x02) /* The IT is in CR2 register */
{
usartxbase += 0x10;
}
else /* The IT is in CR3 register */
{
usartxbase += 0x14;
}
if (NewState != DISABLE)
{
*(__IO uint32_t*)usartxbase |= itmask;
}
else
{
*(__IO uint32_t*)usartxbase &= ~itmask;
}
}
对着《STM32参考手册》自己慢慢分析吧。
比如 #define USART_IT_TC ((uint16_t)0x0626)
0x0626 对应的二进制为 0000 0110 0010 0110
前8位为该中断在状态寄存器中的位置。
中间3位为该中断使能所在哪个控制寄存器。
最后5位为该中断使能在其所在的控制寄存器的位置。
今天看到了,对着楼主的分析了一下,确实如楼主所言。不明白的是每一个中断使能都在手册里可以查到具体的地址,为什么不用结构体指针的方式直接定位到呢?反而要通过几次计算,得到偏移地址再定位。像这种
if (NewState != DISABLE)
{
/* Enable the selected USART by setting the UE bit in the CR1 register */
USARTx->CR1 |= USART_CR1_UE;
}
else
{
/* Disable the selected USART by clearing the UE bit in the CR1 register */
USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE);
}
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
这一句话中,为什么USART_GetITStatus(USART1, USART_IT_RXNE) 不等于RESET,就发生中断呢?我在手册里,找不到RESET的定义。
在库函数里面是有关于RESET的定义的。
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
RESET的值是0,SET的值是非0(可以理解为1)
在数据接收完毕的时候,会把寄存器某一位置为1然后发生中断。于是我们就在中断里面查询这个位的值,如果是1(也就是 不等于RESET),则说明发生的中断,是由接收数据引起的。
一周热门 更多>