ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[STM32F1] 串口中断

[复制链接]
454|40
 楼主 | 2019-6-23 15:35 | 显示全部楼层 |阅读模式
32串口中断接收数据的程序,想把一串数据比如:A4 A2 A3 A4 A4...接收并存到一个数组中作数据分析,现在卡在了中断接收这一块,把数据接收到数组get_ch[8]之后,不能在主程序中使用这个数组并且进行数据分析,甚至不能将其元素赋给其他数组,不然串口就不能用。

使用特权

评论回复
 楼主 | 2019-6-23 15:38 | 显示全部楼层
中断处理程序如下:
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;
                }
       }
  }

使用特权

评论回复
| 2019-6-23 15:42 | 显示全部楼层
这段程序也没什么问题;

使用特权

评论回复
| 2019-6-23 15:48 | 显示全部楼层
用不用中断都没问题吧。

使用特权

评论回复
 楼主 | 2019-6-23 15:57 | 显示全部楼层
就是一旦在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;
                }
}

使用特权

评论回复
| 2019-6-23 16:00 | 显示全部楼层
无法理解,怎么操作数据的时候会导致初始化失败?

使用特权

评论回复
 楼主 | 2019-6-23 16:03 | 显示全部楼层
不知道是什么原因,判断为初始化失败是因为while()之前打印的那句都打印不出来,才这样判断的,用了一个其他的工程试了之后发现没什么问题。更尴尬了。

使用特权

评论回复
| 2019-6-23 16:07 | 显示全部楼层

用双缓冲吧。
还有在中断里请不要使用printf这种很费时的操作。中断处理要尽量的短。

使用特权

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

使用特权

评论回复
 楼主 | 2019-6-23 16:18 | 显示全部楼层
谢谢指导,想问下用FIFO建立缓冲区和提前建立一个容量大的数组存放有什么不同?是数组进中断数据会被保护起来吗?

使用特权

评论回复
 楼主 | 2019-6-23 16:22 | 显示全部楼层
谢谢您的意见,已经改过来了,还是没有解决,不知道哪里的BUG,目前准备用DMA+接受双缓冲试试。

使用特权

评论回复
| 2019-6-23 16:26 | 显示全部楼层
你把改过来的代码发上来

使用特权

评论回复
| 2019-6-23 16:30 | 显示全部楼层

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

使用特权

评论回复
| 2019-6-23 16:34 | 显示全部楼层
数组下标越界。。。char get_ch[8];
这个数组的下标是0-7,没有8.但是你main函数里面的循环条件是<=8,可以循环到8。。。

使用特权

评论回复
 楼主 | 2019-6-23 16:38 | 显示全部楼层
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;
                }
  }
}

使用特权

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

使用特权

评论回复
| 2019-6-23 16:44 | 显示全部楼层

你要尝试把发送指令放在主循环里

使用特权

评论回复
| 2019-6-23 16:47 | 显示全部楼层
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做操作。主需要初始化时做一次清零就行了

使用特权

评论回复
| 2019-6-23 16:52 | 显示全部楼层

volatile int Rev_flag; // 这样声明这个变量

使用特权

评论回复
| 2019-6-23 16:57 | 显示全部楼层
是中断程序不能运行吗?

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表