完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我跑裸机的时候在中断里面接收到数据就马上发送出来没有问题,但是在Ucos系统下只有第一次进了UART中断服务程序,ucos其它任务照常运行。这是怎么回事?(备注:接收的是GPS模块传过来的数据,然后在任务中串口输出是没问题的,就是中断接收有问题)
中断服务程序如下: void USART1_IRQHandler(void) { INT8U i = 0; OS_CPU_SR cpu_sr; OS_ENTER_CRItiCAL(); OSIntNesting++; OS_EXIT_CRITICAL(); while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) { } i = USART_ReceiveData(USART1); printf("%c",i); OSIntExit(); } 初始化那些应该没问题,跑裸机是可以的 下面是初始化程序: void NvicInit(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void UartInit(void) { INT8U i; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA , ENABLE); // 使能GPIOA端口 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); // 使能串口1时钟 GPIO_PinAFConfig(GPIOA ,GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA ,GPIO_Pin_10, GPIO_AF_1); ///////////////////////////////////////////////////////////////////////////////////// /* PA9==TX PA10-RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA , &GPIO_InitStructure); ///////////////////////////////////////////////////////////////////////////////////// USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); //串口配置 USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);//打开中断 USART_Cmd(USART1, ENABLE);//使能串口1 USART_ClearFlag(USART1, USART_FLAG_TC); } |
|
相关推荐
19个回答
|
|
自己顶一下
|
|
|
|
中断中不要写死循环,用if来判断,并且要清除串口标志位。
OSIntEnter(); if(USART_GetITStatus(USART1, USART_IT_RXNE) !=RESET) { ch =USART_ReceiveData(USART1); USART_ClearITPendingBit(USART1, USART_IT_RXNE); } OSIntExit(); |
|
|
|
F0系列好像跟其他系列不一样,我都是先在裸机上测试的,裸机下情况:一开始我也是用if来判断标志位,if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) { i = USART_ReceiveData(USART1); printf("%c",i); } 至于清除标志位数据手册上面是这么说的:In single buffer mode, clearing the RXNE bit is performed by a software read to the USARTx_RDR register. 那么我读完寄存器标志位也就清除了。然而上述程序跑裸机状态下是不行的,然后我看了摩尔吧枫叶老师的例程是这么写的: while(USART_GetFlagStatus(F072RB_COM, USART_FLAG_RXNE) == RESET);//等待接收为空 Uart_buf[0] = (unsigned char)(USART_ReceiveData(F072RB_COM)); // 接收单个字符 他用一个while阻塞到数据接收完,但是我看数据手册并没有说接受完RENE位会被清除,但我试着用他的方法,还真成功接收然后发送出来了。这点我百思不得其解,F0怎么跟其他的有这样的差别。但是移植到操作系统下就出现问题了,只进去一次中断 |
|
|
|
测试表明那个while并不是死循环,状态位会被清除,然后往下执行 |
|
|
|
这里就怕会产生死循环,是个隐性问题。下次再接收时,发生什么情况?退出中断以后,对应的寄存器是否发生了变化?
|
|
|
|
In single buffer mode, clearing the RXNE bit is performed by a software read to the USARTx_RDR register,说的是在single buffer 模式 是在软件读USARTx_RDR 的时候产生的清楚RXNE 位,while(USART_GetFlagStatus(F072RB_COM, USART_FLAG_RXNE) == RESET);//这句话应该是当有数据的时候RXNE置位1这时才读取读取完自动会清除 USART_FLAG_RXNE,就会跳出循环,并不是循环等待接受,跟IF 是一个意思。为什么你上面写的是!= RESET啊,只是没有接收到数据的意思啊
|
|
|
|
下次不会再进中断了,系统的几个任务都还正常运行,看寄存器RX使能位开着没问题,但是RXNE中断标志位一直没置位,RDR寄存器也一直是0。还有我定义了一个全局数组变量,然后如果用这个数组来存数据的话会发生段错误,所以后来就用了个i来接收,然后调试的时候会看到那个全局变量数组里面的值一直在变化,除了初始化一次后,我又没对它进行操作,这是怎么回事 |
|
|
|
kghfh 发表于 2019-3-7 21:02 之前逻辑乱了,是寄存器接收完数据后才会往下执行,我刚用if来接收,在裸机状态下也可以了,就是跑操作系统时不行 |
|
|
|
|
|
|
|
你看一下标志位,是不是串口接收中断产生的。还有看一下溢出中断标志位。
|
|
|
|
这跟变量没关系吧,接收寄存器是16位的,我初始化时设置是八位,我是接收1字节发送1字节,一个unsigned char型的就行了
|
|
|
|
大神。。。。。我把GPS模块拿掉,RXNE位也会被置位一次,然后进中断,也就是说那次中断不是因为接收到我的gps信号而产生的,溢出错误标志位一直都是0 |
|
|
|
还是把你的配置代码发一下吧。
|
|
|
|
void NvicInit(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void UartInit(void) { INT8U i; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA , ENABLE); // 使能GPIOA端口 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); // 使能串口1时钟 GPIO_PinAFConfig(GPIOA ,GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA ,GPIO_Pin_10, GPIO_AF_1); ///////////////////////////////////////////////////////////////////////////////////// /* PA9==TX PA10-RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA , &GPIO_InitStructure); ///////////////////////////////////////////////////////////////////////////////////// USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); //串口配置 USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);//打开中断 USART_Cmd(USART1, ENABLE);//使能串口1 USART_ClearFlag(USART1, USART_FLAG_TC); } 以上是初始化,我单步调试发现执行完 USART_Cmd(USART1, ENABLE);后RXNE标志位就被置位了 |
|
|
|
这是ST的库函数,执行完USARTx->CR1 |= USART_CR1_UE;后标志位就被置位了 void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) { /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_FUNCTIONAL_STATE(NewState)); 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 &= (uint32_t)~((uint32_t)USART_CR1_UE); } } 看汇编代码如下: 0x080021B6 4770 BX lr 403: if (NewState != DISABLE) 404: { 405: /* Enable the selected USART by setting the UE bit in the CR1 register */ 0x080021B8 2900 CMP r1,#0x00 0x080021BA D004 BEQ 0x080021C6 406: USARTx->CR1 |= USART_CR1_UE; 407: } 408: else 409: { 410: /* Disable the selected USART by clearing the UE bit in the CR1 register */ 0x080021BC 6802 LDR r2,[r0,#0x00] 0x080021BE 2301 MOVS r3,#0x01 0x080021C0 431A ORRS r2,r2,r3 0x080021C2 6002 STR r2,[r0,#0x00] 0x080021C4 E003 B 0x080021CE 411: USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UE); 412: } 0x080021C6 6802 LDR r2,[r0,#0x00] 0x080021C8 0852 LSRS r2,r2,#1 0x080021CA 0052 LSLS r2,r2,#1 0x080021CC 6002 STR r2,[r0,#0x00] 413: } |
|
|
|
|
|
|
|
找到原因了!多谢版主热心指点,今天太开心了。 GPIO_PinAFConfig(GPIOA ,GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA ,GPIO_Pin_10, GPIO_AF_1); 仔细看这两句发现应该写作GPIO_PinSource10的写成GPIO_Pin_10,而GPIO_Pin_10也有宏定义,编译器没查出来错。 |
|
|
|
不客气。有问题的话,继续在论坛留贴就好了
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1252 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1184 浏览 3 评论
2263 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1351 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1774 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 07:58 , Processed in 0.923492 second(s), Total 78, Slave 71 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号