[STM32F1]

32串口中断问题求助

[复制链接]
2857|40
手机看帖
扫描二维码
随时随地手机跟帖
Static0|  楼主 | 2017-12-19 17:02 | 显示全部楼层 |阅读模式
本人目前在写一个32串口中断接收数据的程序,想把一串数据比如:A4 A2 A3 A4 A4...接收并存到一个数组中作数据分析,现在卡在了中断接收这一块,把数据接收到数组get_ch[8]之后,不能在主程序中使用这个数组并且进行数据分析,甚至不能将其元素赋给其他数组,不然串口就不能用。不知道是什么原因。求各位大佬救助!
Static0|  楼主 | 2017-12-19 17:06 | 显示全部楼层
中断处理程序如下:
char get_ch[8];
static int ch_num=0;
void USART1_IRQHandler(void)
{                if(USART_GetFlagStatus (USART1,USART_IT_RXNE)!=RESET)          {
            USART_ClearITPendingBit(USART1,USART_IT_RXNE);
            get_ch[ch_num]=USART_ReceiveData(USART1);            
            printf("%c",get_ch[ch_num++]);
           //Con_i ++;
                if(ch_num==8)
                {
                        Con_i =0;
                        Rev_flag=1;
                        ch_num=0;
                }
       }
  }

使用特权

评论回复
mmuuss586| | 2017-12-19 17:21 | 显示全部楼层

这段程序也没什么问题;

使用特权

评论回复
幸福小强| | 2017-12-19 17:31 | 显示全部楼层
用不用中断都没问题吧。

使用特权

评论回复
Static0|  楼主 | 2017-12-19 17:32 | 显示全部楼层
mmuuss586 发表于 2017-12-19 17:21
这段程序也没什么问题;

就是一旦在main中想使用数据,就会出现串口初始化好像都失败了的问题,不知道什么原因啊,想把数据传递出来也不行。
int main(void)
{
  NVIC_Configuration();
        USART_Configuration();
  //LED_GPIO_Configuration();
       
  printf("\r\n  begin.  \n\n");
        while(1)
        {
                Rev_to_Handle();
        }
}
void Rev_to_Handle(void)
{
        int array_num;
        switch(Rev_flag)  
        {
                case 1:
                        for(array_num=0;array_num<=8;array_num++)
                {
                        Handle_ch[array_num]=get_ch[array_num];
                        Rev_flag++;
                }
          break;
                case 2:
                  for(array_num=0;array_num<=8;array_num++)
                {
                        Handle_ch[array_num+8]=get_ch[array_num];
                        Rev_flag=0;
                }
                break;
                deflaut:
       break;
                }
}
       

使用特权

评论回复
dongnanxibei| | 2017-12-19 21:49 | 显示全部楼层
无法理解,怎么操作数据的时候会导致初始化失败?

使用特权

评论回复
Static0|  楼主 | 2017-12-20 11:11 | 显示全部楼层
dongnanxibei 发表于 2017-12-19 21:49
无法理解,怎么操作数据的时候会导致初始化失败?

不知道是什么原因,判断为初始化失败是因为while()之前打印的那句都打印不出来,才这样判断的,用了一个其他的工程试了之后发现没什么问题。更尴尬了。

使用特权

评论回复
Ketose| | 2017-12-20 11:42 | 显示全部楼层
用双缓冲吧。
还有在中断里请不要使用printf这种很费时的操作。中断处理要尽量的短。

使用特权

评论回复
kingkits| | 2017-12-20 13:06 | 显示全部楼层
1 不要在中断里用printf函数
2 把 if(USART_GetFlagStatus (USART1,USART_IT_RXNE)!=RESET)  中的if改成while
3 清中断标志的命令要放在最后

使用特权

评论回复
Static0|  楼主 | 2017-12-20 14:59 | 显示全部楼层
Ketose 发表于 2017-12-20 11:42
用双缓冲吧。
还有在中断里请不要使用printf这种很费时的操作。中断处理要尽量的短。 ...

谢谢指导,想问下用FIFO建立缓冲区和提前建立一个容量大的数组存放有什么不同?是数组进中断数据会被保护起来吗?

使用特权

评论回复
Static0|  楼主 | 2017-12-20 15:01 | 显示全部楼层
kingkits 发表于 2017-12-20 13:06
1 不要在中断里用printf函数
2 把 if(USART_GetFlagStatus (USART1,USART_IT_RXNE)!=RESET)  中的if改成w ...

谢谢您的意见,已经改过来了,还是没有解决,不知道哪里的BUG,目前准备用DMA+接受双缓冲试试。

使用特权

评论回复
kingkits| | 2017-12-20 16:08 | 显示全部楼层
你把改过来的代码发上来

使用特权

评论回复
Ketose| | 2017-12-20 16:11 | 显示全部楼层
Static0 发表于 2017-12-20 14:59
谢谢指导,想问下用FIFO建立缓冲区和提前建立一个容量大的数组存放有什么不同?是数组进中断数据会被保护 ...

FIFO内部也是一个数组,只是它有自己的机制。
你的数组是个全局变量,裸机程序,没有什么会对数据进行保护。都可以读写。

使用特权

评论回复
blust5| | 2017-12-20 16:32 | 显示全部楼层
本帖最后由 blust5 于 2017-12-20 16:35 编辑

数组下标越界。。。char get_ch[8];
这个数组的下标是0-7,没有8.但是你main函数里面的循环条件是<=8,可以循环到8。。。

使用特权

评论回复
Static0|  楼主 | 2017-12-20 16:34 | 显示全部楼层
kingkits 发表于 2017-12-20 16:08
你把改过来的代码发上来

char get_ch[8];
static int Handle_ch[16];
static int ch_num=0;
int Con_i=0;
int Rev_flag=0;
int main(void)
{
        delay_init(72);
        delay_ms(10);
        NVIC_Configuration();
        USART_Configuration();
  //LED_GPIO_Configuration();
       
  printf("\r\n  begin.  \n\n");
        while(1)
        {
                Rev_to_Handle();
        }
}
void Rev_to_Handle(void)
{
        int array_num;
        switch(Rev_flag)  
        {
                case 1:
                        for(array_num=0;array_num<=8;array_num++)
                {
                        Handle_ch[array_num]=get_ch[array_num];
                        Rev_flag++;
                }
          break;
                case 2:
                  for(array_num=0;array_num<=8;array_num++)
                {
                        Handle_ch[array_num+8]=get_ch[array_num];
                        Rev_flag=0;
                }
                break;
                deflaut:
       break;
                }
                //½«Handle_chµÄÊý¾Ý´«µÝ¸øData_Handle
}
       
void USART1_IRQHandler(void)
{
        while(USART_GetFlagStatus (USART1,USART_IT_RXNE)!=RESET)  
        {
   get_ch[ch_num]=USART_ReceiveData(USART1);            
         USART1_Put_Char(get_ch[ch_num++]);
         //Con_i ++;
         USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                if(ch_num==8)
                {
                        Con_i =0;
                        Rev_flag=1;
                        ch_num=0;
                }
  }
}

使用特权

评论回复
Static0|  楼主 | 2017-12-20 16:37 | 显示全部楼层
调试的时候发现的初始化之后就进入了硬件错误
stm32f10x_it.c中的这个
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

使用特权

评论回复
kingkits| | 2017-12-20 16:41 | 显示全部楼层
你要尝试把发送指令放在主循环里

使用特权

评论回复
kingkits| | 2017-12-20 16:48 | 显示全部楼层
void USART1_IRQHandler(void)
{
        while(USART_GetFlagStatus (USART1,USART_IT_RXNE)!=RESET)  
        {
         get_ch[ch_num]=USART_ReceiveData(USART1);            
         //USART1_Put_Char(get_ch[ch_num]);  // 这个注销掉
         ch_num++;
         //Con_i ++;
                if(ch_num>=8)  //这里改为 >=
                {
                        Con_i =0;
                        Rev_flag=1;
                        ch_num=0;
                }
          }
          USART_ClearITPendingBit(USART1,USART_IT_RXNE);  // 放在这里清除中断标记
}

主程序里不要对Rev_flag做操作。主需要初始化时做一次清零就行了

使用特权

评论回复
kingkits| | 2017-12-20 16:50 | 显示全部楼层
volatile int Rev_flag; // 这样声明这个变量

使用特权

评论回复
dspmana| | 2017-12-20 17:50 | 显示全部楼层
是中断程序不能运行吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

19

帖子

0

粉丝