打印

ST单片机,串口中断使能打开,无法进入串口中断函数,为啥

[复制链接]
3824|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Jay_Lynn 于 2013-1-15 22:19 编辑

今天调STM8208串口发送,崩溃了,原因是这样的我每次发送前我都检查缓冲是否充足,但是当我在main()函数中去掉延时函数Delay(0x5ff),或者改小延时值时候串口输出乱码了,之后串口就停止工作了(无法进入串口中断函数的断点)
观察寄存器发现,求解~~~


串口发上来的数正常是这样,无限多的数据
01 02 03 04 0506 07 08 09 0A 0B 0C 0D 0E 0F
01 02 03 04 0506 07 08 09 0A 0B 0C 0D 0E 0F
01 02 03 04 0506 07 08 09 0A 0B 0C 0D 0E 0F
01 02 03 04 0506 07 08 09 0A 0B 0C 0D 0E 0F
把延时去掉后变成这样,发完这几个就不发了
01 02 03 04 05 0A 0B 0C 0D 0C 0D 0E0F 01 06 07 08 09 0E 0F 01 06 07 08 09 0E 0F 01 02 07 08 09 0E 0F 01 02 07 0809 0E 0F

上代码
------ztUart_Transmission_Handle.h-----
#ifndef ztUart_Transmission_Handle_H
#define ztUart_Transmission_Handle_H
#include "stm8s.h"
#define  Txbuf_Size 64
extern uint8_t *pInTxbuf;
extern uint8_t *pOutTxbuf;
extern uint8_t TxBuf[Txbuf_Size];
extern void TxBufQueue_Init(void);
extern uint8_t Get_Remainder_Len_of_TxBufQueue(void);
extern void Increase_pInTxbuf(uint8_t Num);
extern void Increase_pOutTxbuf(uint8_t Num);
extern void Copy_data_to_Txbuf(uint8_t *psource,uint8_t len);
extern bool Send_data_to_Uart(uint8_t *pdata,uint8_t len_of_data);
extern  void UART1_TX_IRQHandler_CB();
#endif
------ztUart_Transmission_Handle.c-----
uint8_t *pInTxbuf = NULL;
uint8_t *pOutTxbuf = NULL;
uint8_t TxBuf[Txbuf_Size] = {0};
void TxBufQueue_Init(void)
{
    pInTxbuf = &TxBuf[0];
    pOutTxbuf = pInTxbuf;
}
uint8_t Get_Remainder_Len_of_TxBufQueue(void)
{
    disableInterrupts();
    if (pInTxbuf <pOutTxbuf)
    {
        return uint8_t(pOutTxbuf-pInTxbuf );
    }
    else
    {
        return uint8_t(Txbuf_Size +pOutTxbuf-pInTxbuf );
    }

    enableInterrupts();
}
void Increase_pInTxbuf(uint8_t Num)
{
    disableInterrupts();
    if ((pInTxbuf + Num) >= (&TxBuf[0] + Txbuf_Size))
    {
        pInTxbuf = (pInTxbuf + Num - Txbuf_Size);
    }
    else
    {
        pInTxbuf += Num;

    }
    enableInterrupts();
}
void Increase_pOutTxbuf(uint8_t Num)
{
    disableInterrupts();
    if ((pOutTxbuf + Num) >= (&TxBuf[0] + Txbuf_Size))
    {
        pOutTxbuf = (pOutTxbuf + Num - Txbuf_Size);
    }
    else
    {
        pOutTxbuf += Num;

    }
    enableInterrupts();
}
void Copy_data_to_Txbuf(uint8_t *psource, uint8_t len)
{
    if (len <= (&TxBuf[0] + Txbuf_Size - pInTxbuf))
    {
        //当没有溢出卷积的时候,剩余空间足够的时候
        memcpy(pInTxbuf, psource, len);
    }
    else
    {
        memcpy(pInTxbuf, psource, &TxBuf[0] + Txbuf_Size - pInTxbuf);
        memcpy(&TxBuf[0], psource + (&TxBuf[0] + Txbuf_Size - pInTxbuf), len - (&TxBuf[0] + Txbuf_Size - pInTxbuf));
    }
    Increase_pInTxbuf(len);
}
bool Send_data_to_Uart(uint8_t *pdata, uint8_t len_of_data)
{
    uint8_t try_times = 0;
    uint8_t Now_Remainder_Len_of_TxBufQueue = Get_Remainder_Len_of_TxBufQueue();

[color=Red] while (Now_Remainder_Len_of_TxBufQueue <= len_of_data&&(try_times < 4))
{
    Delay(0x0f00);
        Now_Remainder_Len_of_TxBufQueue = Get_Remainder_Len_of_TxBufQueue();
        try_times++;
    }[/color]
    if (try_times < 4)
{
    Copy_data_to_Txbuf(pdata, len_of_data);
        if (!(UART1->CR2 & (0x01 << 6))) //这里要获取UART_TX的中断使能状态,注意有两种中断,A.TX发送完成中断,TX空中断,这里只要检测发送完成中断就可以了
        {
            //要是中断没有使能,就打开中断
            UART1_ITConfig(UART1_IT_TXE, ENABLE);
      

        }
        return true;
    }
    else
    {
        return false;
    }
}
void UART1_TX_IRQHandler_CB()
{//应该先检查可靠性
    //边界条件:首次发送肯定不等于
    //要是等于了也没有发的必要了
    if (pInTxbuf == pOutTxbuf)
    {
        UART1_ITConfig(UART1_IT_TXE, DISABLE);
        UART1_ITConfig(UART1_IT_TC, DISABLE);
    }
    else
    { UART1_SendData8(*pOutTxbuf);
      Increase_pOutTxbuf(1);

    }
}
------mian.c------
void main(void)
{uint8_t P[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
uint8_t P1[]={0x0a,0x0b,0x0c};  
while(1)  
{
    uint8_t k=sizeof(P);
   Send_data_to_Uart(P,k);
   [color=Red]// Delay(0x5ff);[/color]
   Send_data_to_Uart(P1,3);

}
}
沙发
huangxz| | 2013-1-15 22:31 | 只看该作者
楼主在while(1)里面发送数据的速度已经超出了uart的负载了。一般情况下这样使用uart本身就是非法的。如果使用阻塞发送方式程序不会出现什么问题,但是用中断方式肯定会出现问题的。

使用特权

评论回复
板凳
Jay_Lynn|  楼主 | 2013-1-15 22:44 | 只看该作者
不过我发送都检验是否有足够缓冲给我发送的啊??当串口没有发送完成时候就延时阻塞,等待串口发送完成,
while (Now_Remainder_Len_of_TxBufQueue <= len_of_data&&(try_times < 4))
{
    Delay(0x0f00);
        Now_Remainder_Len_of_TxBufQueue = Get_Remainder_Len_of_TxBufQueue();
        try_times++;
    }

使用特权

评论回复
地板
Jay_Lynn|  楼主 | 2013-1-16 00:39 | 只看该作者
丢人,我竟然犯了这种粗心错,大家来尽情的骂我吧,我找到问题,哈哈    竟然是这种小错误,太不好意思了

使用特权

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

本版积分规则

2

主题

16

帖子

0

粉丝