OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9448|回复: 9

关于串口中断接收数据,有数据到来时不能进去中断函数

[复制链接]

5

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2014-6-13
在线时间
16 小时
发表于 2014-6-17 17:03:52 | 显示全部楼层 |阅读模式
5金钱
程序写的是中断接收数据,,但是有数据到来时不能进去中断函数,汇编窗口中显示跳到了黄色的那一行。。
然后程序就死了。。再点调试的运行按钮也只停留在这一行了。。



有人遇到过这个问题吗??求帮忙啊

最佳答案

查看完整内容[请看2#楼]

回复【2楼】正点原子: ---------------------------------thank  you、我找到问题了。这个库函数里我改过中断向量表的偏移量了。。嘿嘿,我把这事给忘了。。所以中断一直不对
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2014-6-13
在线时间
16 小时
 楼主| 发表于 2014-6-17 17:03:53 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------thank  you、我找到问题了。这个库函数里我改过中断向量表的偏移量了。。嘿嘿,我把这事给忘了。。所以中断一直不对
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-17 23:24:06 | 显示全部楼层
是不是你的中断服务函数有问题?
名字写错了?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2014-6-25
在线时间
0 小时
发表于 2014-6-25 21:52:07 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
你好,我在用STM32F407调试串口程序,一直不能进入接收中断,
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm324xg_eval.h"
#include <stdio.h>

/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup USART_Printf
  * @{
  */ 

/* rivate typedef -----------------------------------------------------------*/
/* rivate define ------------------------------------------------------------*/
/* rivate macro -------------------------------------------------------------*/
/* rivate variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;

/* rivate function prototypes -----------------------------------------------*/

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define UTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define UTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/* rivate functions ---------------------------------------------------------*/

//USART配置函数,IO口时钟源和串口时钟源:AHB1-GPIOB,APB2-USART1
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

//USART_ClockInitTypeDef USART_ClockInitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  //开启GPIOB时钟

/* Connect Xx to USARTx_Tx*/ 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);//这相当于M3的开启复用时钟?只配置复用的引脚,
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);//               
/*配置GPIOB*/
GPIO_StructInit(&GPIO_InitStructure);      //缺省值填入

/*配置GPIOB_Pin6为TX输出*/
/* Configure USART1 Tx (PB.06) as alternate function */ 
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;     //设置为复用,必须为AF,OUT不行
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);

/*配置GPIOB_Pin7为RX输入*/
/* Configure USART1 Rx (PB.7) as alternate function  */ 
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;     //这也必须为复用,与M3不同!
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOB,&GPIO_InitStructure);

  /* USARTx configured as follow:
        - BaudRate = 115200 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
*/
/*IO引脚复用功能设置,与之前版本不同*/
/*配置USART1*/
// USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate =115200;
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_ClockStructInit(&USART_ClockInitStruct);    //之前没有填入缺省值,是不行的
//USART_ClockInit(USART1, &USART_ClockInitStruct);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    //使能 USART1接收中断
USART_Cmd(USART1, ENABLE);         //使能 USART1 

//USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
//USART_ClearFlag(USART1,USART_FLAG_TC); 

}
//NVIC配置函数
void NVIC_Config(void)

NVIC_InitTypeDef NVIC_InitStructure; 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //嵌套优先级分组为1 
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//嵌套通道为USART1_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //通道中断使能 
NVIC_Init(&NVIC_InitStructure);


//主函数
//IO口时钟源和串口时钟源:AHB1-GPIOB,APB2-USART1
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */        
USART_Config();//USART配置
NVIC_Config();//NVIC配置

// STM_EVAL_COMInit(COM1, &USART_InitStructure);

  /* Output a message on Hyperterminal using printf function */
 // printf("\n\rUSART rintf Example: retarget the C library printf function to the USART\n\r");

  while (1)
  {
  }
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
//int fputc(int ch, FILE *f)
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(EVAL_COM1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
//中断服务函数
void USART1_IRQHandler(void)
{
uint32_t rx_dat;
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//判断为接收中断
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志
USART_ClearFlag(USART1,USART_FLAG_RXNE);  
rx_dat=USART_ReceiveData(USART1);//接受数据
printf("iojwfo\r\n"); 
USART_SendData(USART1,(uint8_t) rx_dat);//发送收到的数据
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
}
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-25 22:47:25 | 显示全部楼层
给你个参考代码:
[mw_shl_code=c,true]#include "sys.h" #include "usart.h" ////////////////////////////////////////////////////////////////////////////////// //如果使用ucos,则包括下面的头文件即可. #if SYSTEM_SUPPORT_UCOS #include "includes.h" //ucos 使用 #endif ////////////////////////////////////////////////////////////////////////////////// //修改说明 //无 ////////////////////////////////////////////////////////////////////////////////// //加入以下代码,支持printf函数,而不需要选择use MicroLIB #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef’ d in stdio.h. */ FILE __stdout; //定义_sys_exit()以避免使用半主机模式 _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } #endif //end ////////////////////////////////////////////////////////////////// #if EN_USART1_RX //如果使能了接收 //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15, 接收完成标志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字节数目 u16 USART_RX_STA=0; //接收状态标记 void USART1_IRQHandler(void) { u8 res; #ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了. OSIntEnter(); #endif if(USART1->SR&(1<<5))//接收到数据 { res=USART1->DR; if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 }else //还没收到0X0D { if(res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=res; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } #ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了. OSIntExit(); #endif } #endif //初始化IO 串口1 //pclk2CLK2时钟频率(Mhz) //bound:波特率 void uart_init(u32 pclk2,u32 bound) { float temp; u16 mantissa; u16 fraction; temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0 mantissa=temp; //得到整数部分 fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0 mantissa<<=4; mantissa+=fraction; RCC->AHB1ENR|=1<<0; //使能PORTA口时钟 RCC->APB2ENR|=1<<4; //使能串口1时钟 GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA9,PA10,复用功能,上拉输出 GPIO_AF_Set(GPIOA,9,7); //PA9,AF7 GPIO_AF_Set(GPIOA,10,7); //PA10,AF7 //波特率设置 USART1->BRR=mantissa; // 波特率设置 USART1->CR1|=1<<3; //串口发送使能 #if EN_USART1_RX //如果使能了接收 //使能接收中断 USART1->CR1|=1<<2; //串口接收使能 USART1->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级 #endif USART1->CR1|=1<<13; //串口使能 } [/mw_shl_code]

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2014-6-25
在线时间
0 小时
发表于 2014-6-26 10:03:31 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
有没有直接调用库函数的程序啊,
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-26 23:11:44 | 显示全部楼层
回复【6楼】tempting:
---------------------------------
没哟
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

10

主题

45

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-4-8
在线时间
1 小时
发表于 2014-7-7 01:49:19 | 显示全部楼层
这几天在调试407的串口中断,也出现了类似的问题,明早起来细看
每天奋斗一点点,终究会有成功的那一天
回复

使用道具 举报

25

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
457
金钱
457
注册时间
2015-8-16
在线时间
116 小时
发表于 2016-7-30 20:00:38 | 显示全部楼层
你好,我现在也遇到这个问题,发现库函数stm32f10x_usart.c这里:ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
{
  uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
  ITStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_USART_GET_IT(USART_IT));
  /* The CTS interrupt is not available for UART4 and UART5 */
  if (USART_IT == USART_IT_CTS)
  {
    assert_param(IS_USART_123_PERIPH(USARTx));
  }   
  
  /* Get the USART register index */
  usartreg = (((uint8_t)USART_IT) >> 0x05);
  /* Get the interrupt position */
  itmask = USART_IT & IT_Mask;
  itmask = (uint32_t)0x01 << itmask;
  
  if (usartreg == 0x01) /* The IT  is in CR1 register */
  {
    itmask &= USARTx->CR1;
  }
  else if (usartreg == 0x02) /* The IT  is in CR2 register */
  {
    itmask &= USARTx->CR2;
  }
  else /* The IT  is in CR3 register */
  {
    itmask &= USARTx->CR3;
  }
  
  bitpos = USART_IT >> 0x08;
  bitpos = (uint32_t)0x01 << bitpos;
  bitpos &= USARTx->SR;
  if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  
  return bitstatus;  
}


里面这样写:
/* The CTS interrupt is not available for UART4 and UART5 */
  if (USART_IT == USART_IT_CTS)
  {
    assert_param(IS_USART_123_PERIPH(USARTx));
  }   
没有包含串口4和串口5,于是我跟进在stm32f10x_usart.h文件里将:

#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4) || \
                                     ((PERIPH) == UART5))

#define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3))

#define IS_USART_1234_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                      ((PERIPH) == USART2) || \
                                      ((PERIPH) == USART3) || \
                                      ((PERIPH) == UART4))


改为:
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4) || \
                                     ((PERIPH) == UART5))

#define IS_USART_123_PERIPH(PERIPH)  (((PERIPH)== USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4) || \
                                     ((PERIPH) == UART5))


#define IS_USART_1234_PERIPH(PERIPH) (((PERIPH)== USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4) || \
                                     ((PERIPH) == UART5))

但我改完后发现,在中断接收数据,但有数据到来时不能进去中断函数,程序死了,请问你知道怎么解决吗?
回复

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2016-10-12
在线时间
14 小时
发表于 2016-10-13 18:03:24 | 显示全部楼层
大家好,这个问题大家现在解决了吗?我这两天也在写串口的DMA中断,也出现了这个问题,有时候中断进不去,进去了程序也死了,好着急!在线等!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-13 17:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表