打印
[应用相关]

STM32 程序进入硬件失效中断的问题

[复制链接]
6173|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
芯行天下|  楼主 | 2009-2-6 09:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序片段:
相关宏定义:
#define ABC_SCK    GPIO_Pin_5
#define ABC_MI     GPIO_Pin_6
#define ABC_CS     GPIO_Pin_4
#define ABC_MO     GPIO_Pin_7

#define SCK_Port   GPIOA
#define MI_Port    GPIOA
#define MO_Port    GPIOA
#define CS_Port    GPIOA

#define BaseAddress_ASC    0x1DFF00       //12*24点阵ASCII码起始地址
#define BaseAddress_GT     0x68190        //24*24点阵国标码起始地址

#define HZ11_12            0X00
#define HZ15_16            0X01
#define HZ24_24            0X02
#define HZ32_32            0X03
#define ASC5_7             0X04
#define ASC7_8             0X05
#define ASC6_12            0X06
#define ASC8_16            0X07
#define ASC12_24           0X08
#define ASC16_32           0X09


#define SCK_H()  (GPIO_SetBits(SCK_Port,ABC_SCK))
#define SCK_L()  (GPIO_ResetBits(SCK_Port,ABC_SCK))
#define MO_H()   (GPIO_SetBits(MO_Port,ABC_MO))
#define MO_L()   (GPIO_ResetBits(MO_Port,ABC_MO))
#define CS_H()   (GPIO_SetBits(CS_Port,ABC_CS))
#define CS_L()   (GPIO_ResetBits(CS_Port,ABC_CS))

SPI操作部分,用IO口线模拟。
void ABC_init(void)
{
  
  //管脚初始化
  GPIO_InitTypeDef GPIO_InitStructure;
  //定义输入SI
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
  GPIO_InitStructure.GPIO_Pin =  ABC_MI; 
  GPIO_Init(MI_Port,&GPIO_InitStructure);   
  //定义输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_InitStructure.GPIO_Pin =  ABC_SCK; 
  GPIO_Init(SCK_Port, &GPIO_InitStructure);  
  GPIO_ResetBits(SCK_Port,ABC_SCK);
  
  GPIO_InitStructure.GPIO_Pin =  ABC_MO; 
  GPIO_Init(MO_Port, &GPIO_InitStructure);  
  GPIO_SetBits(MO_Port,ABC_MO);

  GPIO_InitStructure.GPIO_Pin =  ABC_CS; 
  GPIO_Init(CS_Port, &GPIO_InitStructure);  
  GPIO_SetBits(CS_Port,ABC_CS);   
}

void ABC_Start(void)
{
  CS_L();
  SCK_L();  
}

void ABC_Stop(void)
{
  CS_H();
  SCK_L();
}

void ABC_WriteByte(INT8U Idata)
{
  INT8U i;
  SCK_L();
  for (i=8;i>0;i--)
  {
    if (Idata & 0x80)
      MO_H();
    else
      MO_L();
    Idata <<= 1;
    SCK_H();
    delay(10);
    SCK_L();
  }  
}

INT8U ABC_ReadByte(void)
{
  INT8U i,temp = 0;
  SCK_L();
  for (i=8;i>0;i--)
  {
    
    temp <<= 1;    
    temp |= GPIO_ReadInputDataBit(MI_Port,ABC_MI);    
    SCK_H();    
    delay(10);
    SCK_L();
    delay(10);
    
  }
  return  temp;  
}

/***********************************************************************
** 函数功能:从字库芯片中读取数据
** 函数参数:
**          hz: 待取的汉字
**          hzformat--待读取汉字的格式
** 返回值: 
***********************************************************************/
void getDataFromMCU(uint8 *hz,uint8 hzformat)
{
  INT8U i;
  uint32 addr;
  
  switch(hzformat)
  {
  case HZ11_12:
    if(*hz >=0xA1 && *hz <= 0Xa9 && *(hz+1) >=0xA1)
      addr =( (*hz - 0xA1) * 94 + (*(hz+1) - 0xA1))*24+ 0;
    else if(*hz >=0xB0 && *hz <= 0xF7 && *(hz+1) >=0xA1)
      addr = ((*hz - 0xB0) * 94 + (*(hz+1) - 0xA1)+ 846)*24+ 0;  
    hzcode[0] = 24;
    break;
  case ASC6_12:
    if ((*hz >= 0x20) && (*hz <= 0x7E))
      addr = (*hz - 0x20 ) * 12 + 0x1DBE00;
    hzcode[0] = 12;
    break;
  default:
    break;
  }  

  ABC_Start();
  ABC_WriteByte(0x03);
  ABC_WriteByte((INT8U)((addr & 0x00FF0000) >> 16));
  ABC_WriteByte((INT8U)((addr&0x0000FF00)>>8));
  ABC_WriteByte((INT8U)(addr&0x000000FF));
  for (i=0;i<hz[0];i++)
    hzcode[i+1] = ABC_ReadByte();
  ABC_Stop(); 
}

在任务中调用SPI操作部分:
  while(1)
  {
    disp_weightdata(0);
    disp_lcd_state();           // 显示仪表状态(包括信号强度,时间,电池状态)
    keynum = (uint8)(uint32)OSMboxPend(KeyMbox,100,&err);     // 等待按键,超时退出.
    if (err == OS_NO_ERR)
    {
      if (keynum == KEY_F4)
      {
        skey_num = SKEY_MODE1;
        disp_skey();       // 显示软按键.
        CLRMENUTEXT();     // 清空菜单文字部分
        menu_no = 0;
        disp_menu();       // 显示菜单
        while(1)
        {
          disp_lcd_state();           // 显示仪表状态(包括信号强度,时间,电池状态)
          keynum = (uint8)(uint32)OSMboxPend(KeyMbox,100,&err);     // 等待按键,超时退出.
          if (err == OS_NO_ERR)
          {
            if (keynum == KEY_F4)       // 退出菜单
            {
              CLRMENUTEXT();
              skey_num = SKEY_MODE00;
              disp_skey();
              break;
            }
            else if (keynum == KEY_F3)    // 下移
            {
              menu_no++;
              if (menu_no >= MENUNUM)
                menu_no = 0;
            }
            else if (keynum == KEY_F2)  // 上移
            {
              if (menu_no == 0)
                menu_no = MENUNUM -1;
              else
                menu_no --;
            }
            else if (keynum == KEY_F1)  // 确定
            {
              tabfuncaddr = (void(*)(void))menufunaddr[menu_no];
              tabfuncaddr();             // 根据菜单号进入相应的功能调用.
              skey_num = SKEY_MODE1;
              disp_skey();
            }
            disp_menu();
          }
        }
      }
      else if (keynum == KEY_F3)
      {
        
      }
      else if (keynum == KEY_F2)            // 累加
      {
        weightflag |= ADDFLAG;      //设置累加标志位.
        CLRDISP();
      }
    }
  } 
沙发
芯行天下|  楼主 | 2009-2-6 09:17 | 只看该作者

问题解释

在上面任务调用中,显示相关菜单,在这执行过程中每个菜单中所执行相应的功能,其它的都没有问题,当执行以下程序时
 else if (keynum == KEY_F2)            // 累加
      {
        weightflag |= ADDFLAG;      //设置累加标志位.
        CLRDISP();
      }
后会设置一个标志位。

然后在任务中会执行disp_weightdata(0);这个程序。以下为该程序的内容,该程序会根据刚才的标志位进行相应的功能选择。这时会执行SPI的相关操作,执行完成后回到任务中,然后执行
keynum = (uint8)(uint32)OSMboxPend(KeyMbox,100,&err);     // 等待按键,超时退出.

这一语句,这时CPU会进入硬件失效中断,中断号为-1,中断向量为0x0000000c。
而假如执行了SPI的相关操作,不让CPU执行keynum = (uint8)(uint32)OSMboxPend(KeyMbox,100,&err);     // 等待按键,超时退出.
这一语句,CPU不会进入硬件失效中断。望大家帮忙解决一下问题所在。

void disp_weightdata(uint8 xsno)
{
  if ((weightflag & ADDFLAG) == ADDFLAG)  // 有累加数据
  {
    getDataFromMCU("重",HZ11_12);
    disp_hz(WEIGHT_X2*8,WEIGHT_Y2,hzcode);

//    getDataFromMCU("量",HZ11_12);
//    disp_hz(WEIGHT_X2*8+12,WEIGHT_Y2,hzcode);
//    getDataFromMCU("(",ASC6_12);
//    disp_hz(WEIGHT_X2*8+23,WEIGHT_Y2,hzcode);
//    getDataFromMCU("吨",HZ11_12);
//    disp_hz(WEIGHT_X2*8+28,WEIGHT_Y2,hzcode);
//    getDataFromMCU(")",ASC6_12);
//    disp_hz(WEIGHT_X2*8+39,WEIGHT_Y2,hzcode);
//    
//    getDataFromMCU("单",HZ11_12);
//    disp_hz(WEIGHT_X2*8+50,WEIGHT_Y2,hzcode);
//    getDataFromMCU("价",HZ11_12);
//    disp_hz(WEIGHT_X2*8+62,WEIGHT_Y2,hzcode);
//    getDataFromMCU("(",ASC6_12);
//    disp_hz(WEIGHT_X2*8+73,WEIGHT_Y2,hzcode);
//    getDataFromMCU("元",HZ11_12);
//    disp_hz(WEIGHT_X2*8+78,WEIGHT_Y2,hzcode);
//    getDataFromMCU("/",ASC6_12);
//    disp_hz(WEIGHT_X2*8+90,WEIGHT_Y2,hzcode);
//    getDataFromMCU("吨",HZ11_12);
//    disp_hz(WEIGHT_X2*8+96,WEIGHT_Y2,hzcode);    
//    getDataFromMCU(")",ASC6_12);
//    disp_hz(WEIGHT_X2*8+107,WEIGHT_Y2,hzcode);   

  }
  else                                    // 没有累加数据的显示
  {
    lcdset(WEIGHT_X1,WEIGHT_Y1,FONT11,FONTZC);
    ShowText("重量:");
    lcdset(WEIGHT_X1+6,WEIGHT_Y1,FONT11,FONTZC);
    disp_data(weightdata[0],0x24);
    ShowText("(吨)");
    lcdset(WEIGHT_X1,WEIGHT_Y1+25,FONT11,FONTZC);
    ShowText("单价:");
    lcdset(WEIGHT_X1+6,WEIGHT_Y1+25,FONT11,FONTZC);
    disp_data(unitprice,0x51);
    ShowText("(元/吨)");
    lcdset(WEIGHT_X1,WEIGHT_Y1+50,FONT11,FONTZC);
    ShowText("单价:");
    lcdset(WEIGHT_X1+6,WEIGHT_Y1+50,FONT11,FONTZC);
    disp_data(everyprice[0],0x51);
    ShowText("(元)");
  }
}

使用特权

评论回复
板凳
芯行天下|  楼主 | 2009-2-6 09:18 | 只看该作者

版主及各位大侠们看有什么好的意见说一下

使用特权

评论回复
地板
芯行天下|  楼主 | 2009-2-6 09:27 | 只看该作者

在线等

使用特权

评论回复
5
芯行天下|  楼主 | 2009-2-6 10:07 | 只看该作者

问题找到

问题找到了,原来是程序中写错了,如下
for (i=0;i<hz[0];i++)
    hzcode[i+1] = ABC_ReadByte();
应该改为
for (i=0;i<hzcode[0];i++)
    hzcode[i+1] = ABC_ReadByte();

多读出了数据,以至于填充了其它内存区域。

使用特权

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

本版积分规则

87

主题

660

帖子

0

粉丝