OpenEdv-开源电子网

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

串口通信

[复制链接]

80

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
678
金钱
678
注册时间
2013-8-16
在线时间
37 小时
发表于 2014-1-8 15:26:32 | 显示全部楼层 |阅读模式
大家好,我今天遇到一个很棘手的问题。我在定时器溢出中断中初始化串口1,使用串口实现与另一块stm32芯片的双向通信,接收采用中断接收,发送数据采用轮询方式,可是会死机,怎么也找不出问题。还请各位高手帮忙看看,指点指点,谢谢。(定时器的中断优先级低于串口接收的中断优先级);
代码如下:

//-----------------------------------10ms中断一次-------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------

void TIM2_NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);               
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
void TIM2_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructure.TIM_Period=9999;          
   
    TIM_TimeBaseStructure.TIM_Prescaler= (72 - 1);        /* 时钟预分频数 72M/72 */
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;   /* 采样分频 */
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);             /* 清除溢出中断标志 */
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    TIM_Cmd(TIM2, ENABLE); 
}
//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure; 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
 
 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}


void USART1_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 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_IN_FLOATING;
 GPIO_Init(GPIOA, &GPIO_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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
 USART_Cmd(USART1, ENABLE);
}

void TIM2_IRQHandler(void)
{
 if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )
 { 
  TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
  sei();//开启所有中断
  TIM2_NVIC_Configuration();
  TIM2_Configuration();
  ……
  ……
   NVIC_Configuration();
   USART1_Config(void);
  ……
  ……
  ……
  //----------------------------采用轮询方式发送数据
 ……
 ……
 …… l

 }

u8 Re_data[14]={0};
void USART1_IRQHandler(void)
{
   u8  i;

   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
   { 
    for(i=0li<14;i++)
    { 
     Re_data=USART1->DR;
    }
  }
}




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

470

帖子

1

精华

高级会员

Rank: 4

积分
718
金钱
718
注册时间
2013-11-23
在线时间
0 小时
发表于 2014-1-8 17:14:58 | 显示全部楼层
回复【楼主位】星空:
---------------------------------
楼主为什么要每次溢出中断都初始化串口?还配置一遍NVIC?更不解的是还专门写个函数进来后开启所有中断(sei();//开启所有中断)不懂。。你想定时串口发送的话只需在定时中断里发送就行了啊
回复 支持 反对

使用道具 举报

80

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
678
金钱
678
注册时间
2013-8-16
在线时间
37 小时
 楼主| 发表于 2014-1-8 20:03:42 | 显示全部楼层
因为我的程序中还有很多其他类型的中断,这些中断的优先级有些低于串口接收中断,有些高于它,有些和他的优先级一样,所以要这样写。至于每次溢出都初始化一边USART和配置NVIC这是上面的要求所以只能执行了。现在我的困惑是------我的程序我使用了自发自收的测试方式,测试得到的数据与我发送的数据一致(也采用轮询发送,中断接收),证明我的软件功能设置是基本正确,现在我要使用另一个设备发数据给我,我收这些数据。请问我需要在我发送完数据的时候是失能发送功能吗?在发送数据之前失能接收中断吗?实际上我是和发送数据给我的设备进行双向通信的(有发送数据给对方,也有从对方接收数据);我需要怎么做阿?求指点,指点,谢谢。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-1-9 00:30:00 | 显示全部楼层
回复【3楼】星空:
---------------------------------
你很多中断,可以同时设置的啊。
比如3个中断都可以设置为组2,抢占2,子优先级2。
stm32的串口是全双工的,所以接收的时候可以发送,发送的时候,也可以接收。

你现在死机,我建议你用仿真器跟踪下代码,看看死在哪里,是什么条件引起的。对症下药,才能得治啊。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

80

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
678
金钱
678
注册时间
2013-8-16
在线时间
37 小时
 楼主| 发表于 2014-1-9 17:41:51 | 显示全部楼层
我跟踪来一下,如果在串口中断处理函数中有sei()(即是:开启所有中断)就会死机,屏蔽掉就不死了,但是屏蔽掉之后只能一个数据一个数据的发,这边才能收到数据,比且也是正常的,要是多个数据同时发送过来一会死掉。这是什么原因啊,怎么才能狗一次性接收多个数据。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-1-10 13:27:12 | 显示全部楼层
回复【5楼】星空:
---------------------------------
u8 Re_data[14]={0};
void USART1_IRQHandler(void)
{
   u8  i;

   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
   { 
    for(i=0li<14;i++)
    { 
     Re_data=USART1->DR;
    }
  }
}

你这写法有问题,串口中断是一次接收1个字节,你连续读14次,完全无意义
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

80

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
678
金钱
678
注册时间
2013-8-16
在线时间
37 小时
 楼主| 发表于 2014-1-13 18:27:15 | 显示全部楼层
哦,谢谢了
回复 支持 反对

使用道具 举报

80

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
678
金钱
678
注册时间
2013-8-16
在线时间
37 小时
 楼主| 发表于 2014-1-13 18:31:18 | 显示全部楼层
我现在修改了,现在已经成功了。我现在用两台设备分别发送数据给接收设备,一台可以收到,并且数据成功。另一台可以收到但是数据不对。收到数据正确的那台设备用的是STM32F103VC,收到的数据不成功的设备使用的是AVR。波特率设置都是一样的。怎么什么原因导致接收的两台设备的数据不同呢?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 13:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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