UART串口通信问题
每次用16位变量读取UiRB。只有这样才能清除高位的标志。
下面是读数的中断程序:
#pragma interrupt UART0Recv
VOID UART0Recv( )
{
SINT16 temp_data;
temp_data = u0rb;
if ( temp_data < 0 ) //总错误标志为1
{
//错误处理,如果有
}
else
{
dataBuf0[buf0Ptr] = (UINT8) temp_data;
buf0Ptr ++;
if(buf0Ptr > MAX_DATA_NUM)
{
buf0Ptr = 0;
}
}
}
谢谢回复!
我有程序也是按你上面写的,
void INT_Receive_UART0(void)
{
unsigned short tempdata;
tempdata = u0rb;
if (sum_u0rb==0)
{
Rece_UART0[Rece_Count] = tempdata;
if (Rece_UART0[Rece_Count]==BT_LF) //end flag
{
if (Rece_Count > 2){
Rece_Count = 0;
return;
}
}
Rece_Count++;
if (Rece_Count > BT_RECV_MAXLENGTH){
Rece_Count = 0;
}
}else{ //clear flag
Rece_Count = 0;
re_u0c1=0;
_Wait4NOP;
re_u0c1=1;
}
}
上面的错误处理,要re_u0c1=0,才能清除,这样操作对串口接收有没有影响。
一般是怎么清除错误标志的
你说的不错,部分错误标志(总错误标志和溢出错误标志)的确只能通过初始化串口(SiMR = 0x00或者RE_UiC1 = 0)来清除。但是格式错误和校验错误通过读高8位就行了。
但是在你这里,是溢出错误0x90XX,对吧?
一般溢出错误主要是由于MCU的速度较慢造成的。
看看你的CPU时钟(不是主时钟)和UART的波特率的比值。
UART 的波特率 = fn/16/UiBRG,如果CPU和UART都使用同样的时钟源,比如f1,也就是说在两个连续的数据中,CPU只能执行10 x 16 x (UiBRG + 1)条指令(汇编级的单周期连续指令)。虽然你采用了中断,但是进入中断和退出中断都需要花时间。
建议如下:
一、使用高速中断(如果允许中断嵌套的话,只能对一个中断函使用)
#pragma interrupt /B UART1Recv
"/B"表示在中断中使用另一组寄存器,而不压栈保存,差不多能比不使用"/B"的中断节省32个周期。
二、简化你的中断程序
在外面来判断
三、由于你的数据串是连续的,可以考虑一下方案,第一个数据使用中断,随后的使用查询直至收满一包。
VOID UART1Recv( )
{
int temp_data;
int time_out = 10000; //设定超时
temp_data = u0rb; //第一个数
if (temp_data >= 0) //接受正确
{
Rece_UART0[0] = (char)temp_data;
while((char)temp_data != BT_LF) //如果不是数据包结尾
{
if(ri_u0c1) //如果有新数据
{
temp_data = u0rb; //收一个数
if (temp_data < 0)
{
break; //接收错误
}
else
{
Rece_UART0[Rece_Count] = (char)temp_data;
Rece_Count ++
time_out = 10000; //重新设定超时
if(Rece_Count > BT_RECV_MAXLENGTH)
{
break; //接收buffer已经满了,但是还没有收到结束码
}
}
}
//超时判定
if(time_out > 0)
{
time_out --;
}
else
{
break; //超时
}
}
//接受完成或者错误
re_u0c1 = 0; //关闭接受,以清除标志
ir_s0ic = 0; //清除中断标志
Rece_Count = 1; //第一个数是直接写的Rece_UART0[0],所以是从1开始
re_u0c1 = 1; //重新允许接受
}
}
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |