圆形缓冲队列没有延时发送就无法进入发送中断的问题
大家好,小弟用的是STM8208的单片机,内存64k,为了加快串口工作速度,我发送的时候选择了中断模式发送,现在碰到一个问题
//源码
------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
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();
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++;
}
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);
}
}
void main(void)
{uint8_t P[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
uint8_t P1[]={0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
while(1)
{
uint8_t k=sizeof(P);
Send_data_to_Uart(P,k);
// Delay(0x5ff);
Send_data_to_Uart(P1,6);
}
}
怀疑是队列中数据覆盖了,但是我有进行缓冲队列检测啊??
请问大虾,什么时候程序时无法进入中断程序的 STM8?串口?缓冲?队列?
[解决办法]
Get_Remainder_Len_of_TxBufQueue函数临界区使用有问题,关中断没开就返回了