打印
[STM8]

请问STM8S105串口中断无法跳出来是什么原因

[复制链接]
1975|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rookie108|  楼主 | 2017-1-2 13:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序如下:
int main(void)
{
CLK_DeInit();                                      //--> 时钟各变量初始化
CLK_HSECmd(ENABLE);                                //--> 外部高速晶振使能
while(SET != CLK_GetFlagStatus(CLK_FLAG_HSERDY)); //--> 测试外部高速晶振位是不是使能
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);           //--> 外部时钟预分频器,1分频
CLK_ClockSwitchCmd(ENABLE);                        //--> 使能时钟切换功能
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO,CLK_SOURCE_HSE,DISABLE,CLK_CURRENTCLOCKSTATE_DISABLE);
                                                      //--> 时钟切换 ( 自动切换模式 , 切换到外部高速晶振 , 禁止切换中断 ,内部时钟禁止 )   
  USART_Configuration();//串口配置
  enableInterrupts();//允许中断
  while (1)
  {
    delay(100);
  }
}

//串口接收中断
#pragma vector=0x17
__interrupt void UART2_RX_IRQHandler(void)
{
  
  if(UART2_GetFlagStatus(UART2_FLAG_RXNE)!=RESET){
    UART_Send( "REC OK2\n\r", 8);
  }
  UART2_ClearITPendingBit(UART2_IT_RXNE);//清除接收标志位
  return;
}

运行后,电脑往STM8S105发送命令后,串口接收中断能正常反应,并发回响应字符。但是只能反应一次。接下来就没反应了。加了断点观察发现,程序还一直在串口接收中断里面运行。但因为RXNE被清零了,所以虽然没有内容发出,实际上还是在中断里面运行。请问这是什么原因?如果不加UART2_ClearITPendingBit(UART2_IT_RXNE);这一句的话,就一直不断发送字符串。
沙发
xyz549040622| | 2017-1-2 14:17 | 只看该作者
贴出你的串口配置和你的串口发送函数。你中断函数中居然后return,去掉这个。。。

使用特权

评论回复
板凳
mmuuss586| | 2017-1-2 14:41 | 只看该作者
还加return干嘛啊?
可能是加了这个原因,你再试试;

使用特权

评论回复
地板
rookie108|  楼主 | 2017-1-2 15:40 | 只看该作者
谢谢大家。我是按着例程来的最后有个return。等下回去把return去掉试下。

使用特权

评论回复
5
mintspring| | 2017-1-2 18:01 | 只看该作者
return的是什么啊,后面没挂个数。

使用特权

评论回复
6
rookie108|  楼主 | 2017-1-2 18:32 | 只看该作者
发送函数是这个:
void UART_Send(uint8_t *Buffer, uint16_t Length)
{
  uint16_t l=0;
  for(;l<Length;l++)
    UART_send_byte(Buffer[l]);
}

刚才试了下,去掉return也不行。

使用特权

评论回复
7
junyee| | 2017-1-2 20:08 | 只看该作者
串口中断中要避免串口发送操作!

使用特权

评论回复
8
icecut| | 2017-1-3 09:17 | 只看该作者
明显是串口发送这个问题.无论是阻塞还是非阻塞,这样用都不行.

使用特权

评论回复
9
dragon_hn| | 2017-1-3 10:29 | 只看该作者
return这样用没有任何问题.但是中断函数中发送不要超过1个字节的数据.

使用特权

评论回复
10
dzguang| | 2017-1-3 14:00 | 只看该作者
在中断发送代码 if(UART2_GetFlagStatus(UART2_FLAG_RXNE)!=RESET){1},1的位置加一个断点,然后上位机发送,进入断点后,将断点的位置移到 if(UART2_GetFlagStatus(UART2_FLAG_RXNE)!=RESET)判断的位置,看是不是又进来了。如果是的话原因可能和你配置有关系,和你的外部接线有关系。因为他认为你又接收到东西了。同时可以先观察一下这个‘l’局部变量的值,是不是到8就出来了。不过,话说你的代码写的确实是想法上有一定的问题。

使用特权

评论回复
11
xieguangye2001| | 2017-1-3 15:58 | 只看该作者
本帖最后由 xieguangye2001 于 2017-1-3 16:17 编辑

这个问题我刚刚解决掉。
楼主是否使用了IAR下的库函数?在使用过程中个人发现STM8S的库函数存在一些问题。
1.强制类型转换失败
  比如
/**
  * @brief  Reads the specified GPIO input data pin.
  * @param  GPIOx : Select the GPIO peripheral number (x = A to I).
  * @param  GPIO_Pin : Specifies the pin number.
  * @retval BitStatus : GPIO input pin status.
  */
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
{
    return ((BitStatus)(GPIOx->IDR & (uint8_t)GPIO_Pin));
}

该函数应返回RESET或者SET;但我测试下来返回的是)(GPIOx->IDR & (uint8_t)GPIO_Pin)
串口库函数读取标志位楼主可以测试下。

2.IAR环境下打开串口接收中断,则串口溢出/错误中断也会自动打开。即使只定义了UART2_ITConfig(UART2_IT_RXNE, ENABLE); //接收中断使能
这个是我在调试GSM模块AT指令通信过程中发现的。在MCU发送数据给应用终端,终端返回数据的模式下,程序经常运**死在读取发送完成标志或者接收中断处理位置。
修改办法如下:

#pragma vector=0x17
__interrupt void UART2_RX_IRQHandler(void)
{
    static uint8_t data = 0;
   
    if(UART2->SR & 0x08)//STM8S特有溢出错误处理(即使未开中断)
    {
       data =  UART2_ReceiveData8();
       if(data);
    }
    else if(UART2->SR & 0x20)
    {
        UART2->SR &= ~0x20;
        Uart2RxBuf= UART2_ReceiveData8();     // 读取串口数据存储于Uart2RxBuf 读操作清自动清
    }
    return;
}

个人理解可能有不足,希望大神纠正



使用特权

评论回复
12
狼烟客| | 2017-1-3 17:13 | 只看该作者
if(UART2_GetFlagStatus(UART2_FLAG_RXNE)!=RESET){
    UART_Send( "REC OK2\n\r", 8);
    UART2_ClearITPendingBit(UART2_IT_RXNE);//清除接收标志位
  }
  这样试试,愚见!

使用特权

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

本版积分规则

10

主题

29

帖子

3

粉丝