OpenEdv-开源电子网

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

串口中断,不能同时用两个中断

[复制链接]

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
发表于 2014-9-2 12:12:06 | 显示全部楼层 |阅读模式
5金钱
用了串口4和串口5,发现一个问题,单独接的时候,串口4也可以自发自收,串口5也可以自发自收。两个串口同时接电脑的时候,就发现只有一个能用,另外一个就用不了了。。。
这是我的NVIC配置。
[mw_shl_code=c,true]void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /*使能串口4中断,0级先占优先级,0级次占优先级*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择分组方式0 NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /*使能串口5中断,1级先占优先级,1级次占优先级 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择分组方式1 NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }[/mw_shl_code]
最奇怪的时候,今天早上我第一次用的时候,可以同时收发,过了一会就不行了。。。
现在反复试,都是只能一个串口用,俩同时接,就会出现一个不通。。。

最佳答案

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

回复【17楼】正点原子: --------------------------------- 谢谢原子大哥指导,问题解决了。。 1  我当时用电脑串口8调是通的,串口5不通,在昨天回家的路上,我想明白了,可能是串口5线坏了,那根线时好时坏。。 2  我在下面调试是通的,以前也是通的,现在不通,我用了一片RS232,ARM的一个串口和MAX232连接,中间过了一个电阻,ARM和MAX232之间的电阻没拆,可能受那个电阻影响了。。 3 我把ARM的收和M ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 12:12:07 | 显示全部楼层
回复【17楼】正点原子:
---------------------------------
谢谢原子大哥指导,问题解决了。。
1  我当时用电脑串口8调是通的,串口5不通,在昨天回家的路上,我想明白了,可能是串口5线坏了,那根线时好时坏。。
2  我在下面调试是通的,以前也是通的,现在不通,我用了一片RS232,ARM的一个串口和MAX232连接,中间过了一个电阻,ARM和MAX232之间的电阻没拆,可能受那个电阻影响了。。
3 我把ARM的收和MAX232拆开,那个电阻直接飞在空中和GSM模块相连,一切恢复正常。
     问题主要在于MAX232和ARM中间的那个电阻。。。还有就是坑爹的那根串口线。。
回复

使用道具 举报

19

主题

234

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2014-7-8
在线时间
10 小时
发表于 2014-9-2 14:43:57 | 显示全部楼层
你問題應該不在這小段程式裡, 
建議你可以先測 UART4 , 若OK , 另存新檔
在測 UART5 , 若OK , 在另存新檔
最後
想辨法把二個檔案加一起,測試 , 因為我一次開五組都沒有問題, 這東西沒有那麼爛的....
你可以的, 加油
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 15:15:46 | 显示全部楼层
回复【2楼】溫柔一刀:
---------------------------------
我单独测试串口都是对的,两个串口分别接出来,测试也是对的。
就是把串口4跟GSM模块接在一起,串口4收到数据后,通过串口5转发,发给串口助手。
现在是这样的,串口5,就是串口精灵这里,发送指令,5收到后,通过串口4发给GSM模块,GSM模块是响应的。
就是串口4收到的数据,就是没法通过串口5传上来。 我刚才单独测试两个串口都是好的。
串口4和串口5的中断程序一模一样,除了端口号。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 15:20:16 | 显示全部楼层
回复【2楼】溫柔一刀:
---------------------------------
单独测试都是好的,两个串口都用中断,也是好的,就是接上GSM模块以后,GSM模块的信息就没法上报给STM32了。。。
回复

使用道具 举报

19

主题

234

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2014-7-8
在线时间
10 小时
发表于 2014-9-2 16:15:51 | 显示全部楼层
對呀 那問題是 GSM , 跟本身串口沒有問題的

你可以把 GSM 用PC 串口試好, 在加進專案
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 16:24:38 | 显示全部楼层
回复【5楼】溫柔一刀:
---------------------------------
1  GSM是好的,我通过串口4可以给他发送信息。
2  串口4和串口5,我从板子上飞线出来,测试也是好的。。
3  接上后,串口4和GSM相接,  我是这么让软件跑的,GSM信息上报给串口4,通过串口中断,串口4收到后,通过串口5发送出来,显示在电脑端。电脑端通过串口5发送信息,串口5收到后,通过串口4发送给GSM模块,现在串口5收到后,能够发送给串口4,GSM模块响应。 GSM信息上报不上来。
4  我最郁闷的是,前几天同样的程序,同样的板子,都是通的。。。现在是分开,几个模块都是好的;接在一起,就又不行。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 16:25:04 | 显示全部楼层
回复【5楼】溫柔一刀:
---------------------------------
我把GSM模块接出来,它可以正常上报信息。。。
回复

使用道具 举报

19

主题

234

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2014-7-8
在线时间
10 小时
发表于 2014-9-2 16:29:18 | 显示全部楼层
那會不會你接線有問題? 能把你更多資料放上來, 比較好分析
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:02:16 | 显示全部楼层
回复【8楼】溫柔一刀:
---------------------------------

NVIC配置:
void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;
/*使能串口4中断,0级先占优先级,0级次占优先级*/
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


}


void UART4_IRQHandler(void)
{

if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) 

    {  
 USART_ClearITPendingBit(UART4, USART_IT_RXNE);   
    USART_SendData(UART5,USART_ReceiveData(UART4));   //缓存COM4中断接收的数据 
 }
 if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
 {
 USART_ClearITPendingBit(UART4, USART_IT_TC); 
 }
}

/*******************************************************************************
* Function Name: UART5_IRQHandler
* Description : This function handles UART5 global interrupt request.
* Input       : None
* Output      : None
* Return      : None
*******************************************************************************/
void UART5_IRQHandler(void)
{  
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) 

    {  
 USART_ClearITPendingBit(UART5, USART_IT_RXNE);   
    USART_SendData(UART4,USART_ReceiveData(UART5));  //缓存COM4中断接收的数据 
    }
 if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
 {
 USART_ClearITPendingBit(UART5, USART_IT_TC); 
 }
}


这是中断配置





基础配置

我觉得基础配置应该没有错误。。

void GpioInitialisation(void)
{
    /* 定义GPIO初始化结构体 GPIO_InitStructure*/
    GPIO_InitTypeDef GPIO_InitStructure;

/* 设置PA10,最大翻转频率为50MHz*/
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOA , &GPIO_InitStructure);


 /* 设置USART3的Tx脚(PB.10)为第二功能推挽输出模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB , &GPIO_InitStructure);
    
    /* 设置USART3的Rx脚(PB.11)为浮空输入脚  */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB , &GPIO_InitStructure);  

     /* 设置USART2的Tx脚(PA.2)为第二功能推挽输出模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA , &GPIO_InitStructure);
    
    /* 设置USART2的Rx脚(PA.3)为浮空输入脚 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


   /* 设置UART5的Tx脚(PC.12)为第二功能推挽输出模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC , &GPIO_InitStructure);
    
    /* 设置UART5的Rx脚(PD.2)为浮空输入脚 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOD , &GPIO_InitStructure);





    /* 设置UART4的Tx脚(PC.10)为第二功能推挽输出模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC , &GPIO_InitStructure);
    
    /* 设置UART4的Rx脚(PC.11)为浮空输入脚 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC , &GPIO_InitStructure);




  /* 设置 GPIOA.0 为推挽输出,最大翻转频率为50MHz*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


}
/**************************************************************************
* 函数名   : SystickInitialisation
* 函数描述     : 设置Systick定时器,重装载时间为20ms
* 输入参数   : 无
* 输出结果   : 无
* 返回值     : 无
**************************************************************************/
void Delay_us(vu32 n)


{

 SysTick->LOAD=72*n;             //装载计数值,,因为时钟为72M,72次计时1us
 SysTick->CTRL=0x00000005;       //时钟来源为HCLK(72M),打开定时器
 while(!(SysTick->CTRL&0x00010000));     //等待计数到0
 SysTick->CTRL=0x00000004;   //关闭定时器

}
void Delay_3s(void)
{
  vu16 i;
  for (i=0;i<15;i++)
  Delay_us(200000); 

}

void USART_Configuration(void)
{
    /* 定义USART初始化结构体 USART_InitStructure */
    USART_InitTypeDef USART_InitStructure;
    
    /*
    * 波特率为9600bps
    * 8位数据长度
    * 1个停止位,无校验
    * 禁用硬件流控制
    * 禁止USART时钟
    * 时钟极性低
    * 在第2个边沿捕获数据
    * 最后一位数据的时钟脉冲不从 SCLK 输出
    */ 
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(USART2 , &USART_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(USART3 , &USART_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(UART4 , &USART_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(UART5 , &USART_InitStructure);

    /* 使能USART3 */
USART_Cmd(USART3 , ENABLE);
USART_Cmd(USART2 , ENABLE);
USART_Cmd(UART4 , ENABLE);
USART_Cmd(UART5 , ENABLE);
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//使能接受中断,在接受移位 寄存器中有数据是产生
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
}


void USART_Printf(USART_TypeDef* USARTx,char *pch) 
{
/* 这里是判断'\0'是否到了字符串的行尾,这个字符是看不到的,字符串的结束符就是'\0'
 * 如果具体还有不懂的请看C语言,这里通过while()循环,逐个字符逐个字符的传输和显示 */
    while(*pch != '\0')  /* 我们这里用指针表示,*pch就是一个字符,pch就是该字符的地址 */
{
        USART_SendData(USARTx,*pch); /* 在这里我们将这个要显示的字符地址传输给另外一个函数 */

/* 当发送完一个字节后,检测一下“TDR(串口的数据传输寄存器)”是否为空了,因为有可能在一些
 * 其他某些模式,缓冲寄存器可能会有很多数据,需要一点时间才能清空,其实增加了这句代码之后
 * 会让我们的串口驱动更加健壮,在各种情况下都能正常稳定的工作 */
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); 
/* 以下是我们查看《STM32F103中文手册》获得494页24.6.1节 状态寄存器(USART_SR)章节
这里说的就是我们程序代码里的USART_FLAG_TXE这个标志位,发送完毕后,再进行标志清空,进行下一次传输
TXE:发送数据寄存器空
当TDR寄存器中的数据被硬件转移到移位寄存器的时候,该位被硬件置位。
0:数据还没有被转移到移位寄存器;
1:数据已经被转移到移位寄存器。
注意:单缓冲器传输中使用该位。*/
  USART_ClearFlag(USARTx, USART_FLAG_TXE);
        pch++;    /* 此时pch地址加1,指向下一个字符 */
    }
}
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:02:51 | 显示全部楼层
回复【8楼】溫柔一刀:
---------------------------------
串口单独接出来,都可以中断收发。。
回复

使用道具 举报

19

主题

234

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2014-7-8
在线时间
10 小时
发表于 2014-9-2 17:08:54 | 显示全部楼层
你這樣子訊息還不是很完整, 但我有幾點建議

1. GSM模組就我之前用的經驗是, 比如你下 AT\r\n
他會回你 \r\nOK\r\n    (並不會回 \0 , 這是要軟體自已加的)

2. UART 接受最好用斷中來接收, 先存到某個Buffer去, 必竟MCU RAM 很大, 
可以先測試收完的內容是否跟GSM模組回的相同

3. 一 段一段分析, 你三方面都你都說OK, 但整在一起就有問題,  一定有地方有問題, 你看下是不是第 1點, 你對GSM at command 不熟?
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:19:05 | 显示全部楼层
回复【11楼】溫柔一刀:
---------------------------------
我对AT指令还是比较熟悉的。。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:40:19 | 显示全部楼层
回复【11楼】溫柔一刀:
---------------------------------
我去,刚拆下来,只有一个方向能通。。
但是那个方向是变的,谁接电脑串口8,谁能收到数据,发不出数据。。
我的程序是4.5对发的。。
串口4收到发给串口5,串口5收到发给串口4
只有一个方向通。
俩串口同时接的话,有一个串口显示不到接收到数据。。根据我刚才的经验,应该是发送出去了。。
比较纠结,拆下来,发现不对劲了。。一次接一个串口,就是正常的。俩同时接,就有一个不行。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:42:13 | 显示全部楼层
回复【13楼】fly0000:
---------------------------------
并且谁接电脑串口8,谁就是正常,对方发送数据,串口8可以收到,串口8发送数据,对方收不到。串口软件换了好几个了。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 17:46:32 | 显示全部楼层
回复【14楼】fly0000:
---------------------------------
我让串口单独中断收发,谁接电脑串口8,谁就是正常的,另外那个发不出来数据。也收不到。。。
回复

使用道具 举报

19

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2014-8-20
在线时间
0 小时
 楼主| 发表于 2014-9-2 18:14:59 | 显示全部楼层
回复【15楼】fly0000:
---------------------------------
用串口8测两个串口都是正常的。。。。。但是两个ARM串口同时接电脑串口5,就都不行。。。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-9-2 23:27:51 | 显示全部楼层
不是中断的问题了。
5个串口同时开我都用过。
重点检查你代码的逻辑,加入一些printf或者其他指示代码,来监控下问题出在哪里。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-2 13:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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