打印

再请教USART发送CONST数组死机问题

[复制链接]
3578|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huanyufei|  楼主 | 2009-8-23 21:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 huanyufei 于 2009-8-23 21:29 编辑

知道16F查表不能越界,而导致死机应该还是查表时超出了范围。可3天了,仍然没有找到真正原因。

要发送的字符数组
const unsigned char acucHead[7]={"\n$SIG,"};
const unsigned char acucCmd[6][10]={{"ON\n"},{"OFF\n"},{"FAIL\n"},{"REST\n"},{"TEST ON\n"},{"TEST OFF\n"}};
const unsigned char acucName[27][33]={
           {"STEERING LIGHT.P(01),"},   
          {"DANGEROUS LIGHT(02),"},
          {"SUEZ SIGNAL L.T-R.P(03),"},
          {"SUEZ SIGNAL L.T-W.P(04),"},
          {"SUEZ SIGNAL L.T-G.P(05),"},
          {"SUEZ SIGNAL L.T-R.P(06),"},
          {"SUEZ SIGNAL L.T-R.P(07),"},
          {"SUEZ SIGNAL L.T-W.P(08),"},
          {"STEERING LIGHT.S(09),"},
          {"SUEZ SIGNAL L.T-R.S(10),"},
          {"SUEZ SIGNAL L.T-W.S(11),"},
          {"SUEZ SIGNAL L.T-R.S(12),"},
          {"SUEZ SIGNAL L.T-W.S(13),"},
          {"SUEZ SIGNAL L.T-R.S(14),"},
          {"SUEZ SIGNAL L.T-R.S(15),"},
          {"SUEZ SIGNAL L.T(16),"},
          {"NULL(17),"},
          {"NULL(18),"},
          {"NULL(19),"},
          {"NULL(20),"},
          {"NULL(21),"},
          {"NULL(22),"},
          {"NULL(23),"},
          {"NULL(24),"},

          {"POWER MSB,"},
          {"POWER ESB,"},
          {"SYSTEM,"}         
          };


发送函数:(发送前获得ucNameIndex、ucCmdIndex值
void UsartSnd()
{
while(TXIE)  //等待上一次发送完成
{
  asm("clrwdt");
}
ucHdNameIndex=ucNameIndex;  //发送系统开始工作
ucHdCmdIndex=ucCmdIndex;

ucHdIndex=0;
ucHdElmtPlace=0;
TXIE=1;
}


中断处理函数:
if(TXIE&&TXIF)  //USART发送中断
{  
  GIE=0;

  switch(ucHdIndex)
  {
   case 0x00: TXREG=acucHead[ucHdElmtPlace];
      if(acucHead[ucHdElmtPlace]==',')
      {
       ucHdIndex=1;
       ucHdElmtPlace=0;
      }
      else
       ucHdElmtPlace++;

      break;
   case 0x01: TXREG=acucName[ucHdNameIndex][ucHdElmtPlace];
      if(acucName[ucHdNameIndex][ucHdElmtPlace]==',')
      {
       ucHdIndex=2;
       ucHdElmtPlace=0;
      }
      else
       ucHdElmtPlace++;

      break;
   case 0x02: TXREG=acucCmd[ucHdCmdIndex][ucHdElmtPlace];
      if(acucCmd[ucHdCmdIndex][ucHdElmtPlace]=='\n')
      {
       ucHdIndex=0;
       ucHdElmtPlace=0;
       TXIE=0;
      
      }
      else
       ucHdElmtPlace++;

      break;
   default: TXIE=0;
  }
  GIE=1;
}
沙发
huanyufei|  楼主 | 2009-8-23 21:28 | 只看该作者
Debugger中,RUN后发现ucHdElmtPlace越界。是哪里的逻辑出了问题呢?
之前怀疑在对ucHdNameIndex、ucHdCmdIndex付值时进入中断,导致了逻辑错误,加等待TXIE==0,问题还是存在!

使用特权

评论回复
板凳
XIEYUANBIN| | 2009-8-24 10:48 | 只看该作者
程序页面分页,这个是PIC的规矩,如果发生查表越界基本上是分页问题.

使用特权

评论回复
地板
huanyufei|  楼主 | 2009-8-24 12:27 | 只看该作者
PICC不是可以不用考虑分页吗?

使用特权

评论回复
5
yewuyi| | 2009-8-24 13:30 | 只看该作者
你在发送中不断在开启和关闭TXIE吗?

void UsartSnd()
{
while(TXIE)  //等待上一次发送完成
{
  asm("clrwdt");
}
ucHdNameIndex=ucNameIndex;  //发送系统开始工作
ucHdCmdIndex=ucCmdIndex;
ucHdIndex=0;
ucHdElmtPlace=0;
TXIE=1;
}

你判断TXIE有什么用呢?这个好象只是TX发送容许把,看上去似乎有点乱。

使用特权

评论回复
6
huanyufei|  楼主 | 2009-8-24 13:40 | 只看该作者
本帖最后由 huanyufei 于 2009-8-24 13:47 编辑

TXIE=1后,发送3个字符串acucHead[]、acucCmd[][]、acucName[][]。
3个字符串都发送完后关闭中断允许TXIE。
判断TXIE是为了等待前一次发送的字符串发送完毕。防止没有发完就修改ucHdIndex、ucHdElmtPlace、ucHdNameIndex、ucHdCmdIndex,导致查表错误。当然,也为了保证上次发送结果完整。

使用特权

评论回复
7
yewuyi| | 2009-8-24 14:05 | 只看该作者
你放到了发送缓冲寄存器中,并不代表就发送完毕了,发送是需要时间的,在你发送的缓冲寄存器中后,你需要判断有关TX的一些标志来判断发送寄存器中是否为空,如果在这前面关闭了TXIE,那也就提前终止了发送过程。

动不动就开启和关闭TXIE的做法似乎不符合常理把,我现在在外面,呵呵,记性不太好,需要回去翻翻书看一下到底是什么标志,但TXIE的标志不应该随便去动的把!?

看你的描述和代码,你的发送程序似乎很不合理,可先在网络上查查别人是怎么写UART程序的,别闭门造车。。。

使用特权

评论回复
8
huanyufei|  楼主 | 2009-8-24 15:04 | 只看该作者
本帖最后由 huanyufei 于 2009-8-24 15:08 编辑

TXIE只是USART中断使能位!即使发送缓冲寄存器中的值没有发送完,就关闭TXIE,也只是关闭也中断允许而已。
只要TXEN=1,SPEN=1没有改变,TSR寄存器依然有效。,会随波特率继续发送。
我是想通过开关TXIE来实现自动发送(由中断来完成每个字符的发送,判断发送完‘,’后发送另一字符串,最后一个字符串由换行符结束),程序中不用再管它。发送的字符串比较长,大概需要10ms才能发完。而这期间每208us(波特率4800)才进一次中断。我还有一个模拟的USART口需要扫描。

使用特权

评论回复
9
lhzw2001| | 2009-8-26 13:08 | 只看该作者
发送没问题,我也是那么搞的,你确定是发送const区死了?、

使用特权

评论回复
10
huanyufei|  楼主 | 2009-9-17 23:13 | 只看该作者
不好意思,没有及时回帖。终于找到问题!
const区没有问题!
本来硬件在进入中断时自动将GIE清0,退出中断时GIE自动置1。而我在中断处理的时候画蛇添足地加了GIE=0;GIE=1;而GIE=1语句又不是放在整个中断处理末尾,而是放到每个分支的结尾。
分析错误是:进入if(TXIE&&TXIF) 中断后,如果这时有别的中断申请发生,在执行GIE=1语句后,立即响应中断申请,而本次中断还没有执行完。PIC16F不支持中断嵌套,导致退出中断时PC指针跑飞!

使用特权

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

本版积分规则

4

主题

19

帖子

0

粉丝