This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

数组有时不能赋值

Other Parts Discussed in Thread: MSP430F427A

我使用MSP430F427A芯片在IAR平台下面做一个电子称系统,主要包括SD16AD转换、12864显示和4*3键盘输入。工作正常后发现

键盘第一行'0'、‘1’、‘2’三个按键开始输入正常,几轮输入以后按下'0'、‘1’都显示为'0',有时按‘2’也显示为'0',其他9

个按键工作一直正常。排除了硬件问题后单步跟踪键盘程序,最终发现问题出在下面:
按下'1' 第一行第2列 运行到
 Key_Val = keymap[row*3 + col];  // 获取键值
此时 row = 0  col = 1  Key_Val 应该 = 1 , 但是Key_Val = 0 ? 不能赋值,为什么?敬请各位老师赐教!

keymap[]定义如下:

 unsigned char keymap[] = {0,1,2,3,4,5,6,7,8,9,10,11};//设置键盘逻辑键值


键盘程序如下:
#include "jp.h" 
#include "12864.h" 
 unsigned char Key_Val;          //存放键值
  unsigned char keymap[] = {0,1,2,3,4,5,6,7,8,9,10,11};//设置键盘逻辑键值
 // unsigned char *p2;


/*******************************************
函数名称:Init_Keypad
功    能:初始化扫描键盘的IO端口
参    数:无
返回值  :无
********************************************/
void Init_Keypad(void)
{    
  P1DIR = 0x8f;       //P1.0~P1.3设置为输出状态,P1.4~P1.6输入 状态(上拉H)
                     //P1.7 方向为输出,连接蜂鸣器的信号输入脚
   
  P1IES =0x70;    //P1.4~P1.6允许中断
  P1IE  =0x70;   //P1.4~P1.6下降沿触发中断
  P1IFG=0;      //中断标志清0
 
  Key_Val = 0;
}

/*******************************************
函数名称:Check_Key
功    能:扫描键盘的IO端口,获得键值
参    数:无
返回值  :无
********************************************/
//p14\5\6 接上拉电阻
/***************************************
            Key_Val 对应键值
        列:[p14]  [p15]  [p16]  
             ↓     ↓     ↓    
 行:
[p13]→      0      1      2        
[p12]→      3      4      5               
[p11]→      6      7      8          
[p10]→      9     10     11      
***************************************/
void Check_Key(void)
{
  unsigned char row ,col,tmp1,tmp2;
 // unsigned char keymap[] = {0,1,2,3,4,5,6,7,8,9,10,11};//设置键盘逻辑键值
 // unsigned char *p2;
 // p2=keymap;
//与程序计算键值的映射
 
  tmp1 = 0x08;                            // 0000 1000
  for(row = 0;row < 4;row++)              //行扫描
  {
    P1OUT = 0x0f;                       //P1.0~P1.3输出全1
    P1OUT -= tmp1;                      //P1.4~p1.6输出四位中有一个为0
    tmp1 >>=1;                           //0000 0100  0000 0010  0000 0001  
    if((P1IN & 0x70)<0x70)              //是否P1IN的P1.0~P1.3中有一位为0
    {                      
      tmp2 = 0x10;                        // tmp2用于检测出哪一列为0 
      for(col = 0;col < 3;col++)          // 列检测
      {         
        if((P1IN & tmp2) == 0x00)       // 是否是该列,等于0为是
        {          
          Key_Val = keymap[row*3 + col];  // 获取键值 问题出在此行,有时不能赋值
          return;                         // 退出循环
        }
        tmp2 <<= 1;                       //0001 0000  0010 0000  0100 0000
      }
    }
  }     
}

/*******************************************
函数名称:delay
功    能:延时约15ms,完成消抖功能
参    数:无
返回值  :t= tmp*5*clk 根据使用时钟调整tmp值
********************************************/

void delay(void)
{
    unsigned int tmp;
    
    for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功    能:检测按键,并获取键值
参    数:无
返回值  :无
********************************************/
void Key_Event(void)
{    
    unsigned char tmp;
    
    P1OUT =0;                  // 设置P1OUT全为0,等待按键输入
    tmp = P1IN;                // 获取 p1IN
    if((tmp & 0x70) < 0x70)      //如果有键按下
    {                    
        delay();                 //消除抖动
        Check_Key();             // 调用check_Key(),获取键值
    }    
}


/*********************************************************************
控制打开或者关闭键盘中断
SW= 0:关闭;   ELSE:打开
*********************************************************************/
/*
void CtrlKey(unsigned char sw)
{
 if(sw==0)
   P1IE =0;     //关闭端口中断
 else
           P1IE =0xf0; //打开端口中断
}*/


/*******************************************
函数名称:*IntToStr
功    能:整数转化成字符串
参    数:int num, char str[]
返回值  :str
********************************************/
/**/ 
char *IntToStr(int num, unsigned char str[]) 

    int i = 0, j = 0; 
    char temp[100];
  
    while(num) 
    { 
        temp[i] = num % 10 + '0';   //取模运算得到从后往前的每一个数字变成字符  
        num = num / 10; 
        i++; 
    } 
    temp[i] = 0;    //字符串结束标志  
     
    i = i - 1;     //回到temp最后一个有意义的数字  
    while(i >= 0) 
    { 
        str[j] = temp[i]; 
        i--; 
        j++; 
    } 
    str[j] = 0;   //字符串结束标志  
    return str; 

/*端口1按键中断*/
#pragma vector=PORT1_VECTOR  /*端口1按键中断*/
__interrupt void Port1(void)
{
   Key_Event();   //
     if(Key_Val<10)  //处理0~9按键,前一次键值*10+本次键值
     {
      tmp=tmp+Key_Val; //tmp=键入饲料数量
      
      LCD_SetTextPos(2,5);   //第三行右边位置
      IntToStr(tmp, h0);   //整数转换为字符串函数
      LCD_Print(h0);     //显示键入值
    
      tmp=tmp*10;
      if(tmp>10000)tmp=0;  //防止键入值过大超界
       
     }
     else if(Key_Val==10)   //显示下一个饲料和数量
     {
      Next(p,p1);
     }
     else if(Key_Val==11)
     {
       repl(p,p1);   //用键入值替换slsl[]表值               
 

     }
 
  KEY_IFG=0;
  KEY_OUT=0;   //清中断标志
}

void main( void )
{
  p=slmc[0];
  p1=slsl;
  tmp=0;
  i=0;
  szxb=0;
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  Init_Sys();
  Init_Keypad();    //初始化键盘

  LCD_Clear();     //清屏
 
  KEY_DIR&=~fmq;       //关闭蜂鸣器
 
  cshpm(p,p1);         //初始化平屏幕

      KEY_IE =0x70; //打开P1端口中断
 __enable_interrupt(); //开启总中断,这一步没有的话,所有的中断都不能触发
 
 while(1);

  }

  •   Key_Val = keymap[row*3 + col];  // 获取键值 问题出在此行,有时不能赋值

    这里是没有问题的,应该程序没有运行到这里,返回的键值0是初始化的值。你可以在这设置个断点,检查是否每次按键按下都能停在此处。

    你的按键扫描中没有去抖,会不会这里影响了。