当我输入't'两次时,为什么会得到垃圾值?

时间:2017-03-21 01:11:24

标签: c uart interrupt-handling msp430 microprocessors

我正在尝试在MSP430G2553上实现一个温度传感器,用于读取和输出温度读数以及时间戳。基本要求如下:

•t:显示系统的当前时间。使用hhmmss格式输出到串行终端系统的当前时间,其中hh是24小时格式的两位数小时,mm是小时内的两位数分钟,ss是分钟内的两位数秒。

•s:设置系统的当前时间。将系统的当前时间设置为提供的参数。命令与其参数之间不会有空格。参数将在hhmmss表格中,其中hh是24小时格式的两位数小时,mm是小时内的两位数分钟,ss是分钟内的两位数秒。

•o:显示最旧的温度读数及其时间戳。向串行终端输出最旧的温度读数及其时间戳。输出必须具有hhmmss:T形式,其中hh是24小时格式的两位数小时,mm是小时内的两位数分钟,ss是分钟内的两位数秒,T是测量的温度。必须从列表中删除显示的条目。如果未执行读数,则必须显示“未记录温度”消息。

•l:显示所有温度读数及其时间戳。将所有温度读数及其时间戳输出到串行终端。输出应按时间顺序排列,最早的是。输出必须具有hhmmss:T形式,其中hh是24小时格式的两位数小时,mm是小时内的两位数分钟,ss是分钟内的两位数秒,T是测量的温度。必须从列表中删除所有条目。如果未执行读数,则必须显示“未记录温度”消息。 您的系统还必须满足以下要求:

•您必须每隔五(5)分钟捕获一个新的温度读数,并至少存储32个温度读数。如果已达到最大温度读数,请在存储新温度之前丢弃最旧的温度读数。

输入't'2次后发生错误。下次输入't'时,它输出3或4个垃圾值。当我注释掉's'的情况或者将's'更改为另一个变量时,我在switch语句中的't'情况运行得非常好,但是对于赋值的情况需要在情况's'输入到uart中。到目前为止我所尝试的内容包括:更改变量,注释掉第二种情况,更改S案例的值以确保垃圾值是由于这种情况导致的,使用包围某些代码部分,修改了t的整个第一部分效率更高,但仍然出现相同的错误等。任何建议都会非常有帮助。 Picture of Garbage Values

#include "msp430g2553.h"

volatile short unsigned int i=0,j=0,k=0;//This the integer that track the number of cycles
volatile short unsigned int timercount=0;//This the integer that track the number of cycles
volatile unsigned int GT=2600;//variable that sets the global time in seconds of the system
volatile char inputcharacters[16];//Input character storage array
volatile unsigned int tempature[32];//
volatile unsigned int tempaturetime[32];
volatile unsigned int d[6]={0,0,0,0,0,0},test[7];
volatile unsigned int h=0;
volatile unsigned int m=0;
volatile unsigned int ss=0;
int temp=0;

void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;//Disabling watchdogtimer

    P1DIR |= BIT0;//setting p1 bit 1 to outy
    P1OUT &= ~BIT0;//Shutting off the LED

    /* UART config for 9600 baud with SMCLK*/
    IE2 = 0x00;//interrupts off on UART
    UCA0CTL1 = 0x81;//using SMCLK(1Mhz) and software reset enable
    UCA0CTL0 = 0x00;//eight data bits, no parity, one stop bit
    UCA0MCTL = 0x02;//Setting UCBRSx to 1 to set clock rate to 9600
    UCA0BR0 = 0x68;//set clock rate to 9600 from 1Mhz
    UCA0BR1 = 0x00;//set clock rate to 9600
    UCA0STAT = 0x00;//error check and parity, and frame error check all off

    TACTL = 0x1D0;// sets timer a to use the 32.768kh clock with 8 divisor and in up mode
    TACCR0 = 0x1001;// setting the timer to count up to 4097 to get a 1hz(1s) oscillation
    TACCTL0 &= 0xFFEF;// disable capture compare interrupts

    P1SEL|=0X06;// According to slas735j both p1.1(0X02) and p1.2(0X04) need to be set on to receive and send on the UART
    P1SEL2|=0X06;

    ADC10CTL0 &= ENC;
    ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON;
    ADC10CTL1 = INCH_10 | ADC10DIV_2 | ADC10SSEL_3;
    //ADC10CTL0 = 0x3030;
    //ADC10CTL1 = 0xA038;
    ADC10CTL0 &= 0xFFFC;

    /* Enable USCI logic and Enable interrupts */
    UCA0CTL1 &= 0xFE;//turning on USCI logic
    IE2 = 0x01;// Sets UART to receive interrupt
    TACCTL0 = CCIE;// set timerA interupts on done last
    __bis_SR_register(LPM3_bits + GIE);//found on TI wiki
}

#pragma vector=USCIAB0RX_VECTOR// This vector name was pulled from the webcources code
__interrupt void uartinput(void)//this form found on TI's wiki
{
    inputcharacters[i] = UCA0RXBUF;
            UCA0TXBUF = UCA0RXBUF;
            if((i>14)||(inputcharacters[i]=='\r'))
                    {if(inputcharacters[i]=='\r'){inputcharacters[i]=0;}//to reduce i, the number of inputs so that we dont count the \r
                      for(j=0;j<i;j++){switch(inputcharacters[j]) {//switch statement that check the input characters and outputs the correct morse
                      case 't' :

                          h=GT/3600;
                          m=(GT-h*3600)/60;
                          ss=GT-h*3600-m*60;

                          d[0]=(h/10);
                          d[1]=(h-(d[0]*10));
                          d[2]=(m/10);
                          d[3]=(m-(d[2]*10));
                          d[4]=(ss/10);
                          d[5]=(ss-(d[4]*10));
                          for(k=0;k<6;k++)
                          {while((IFG2 & 0x02)==0)
                          {;}
                          UCA0TXBUF=d[k]+48;
                          test[k]=d[k]+48;}
                          while((IFG2 & 0x02)==0)
                                {;}
                          UCA0TXBUF='\r';
                          break;
                      case 'x' ://If this break case is not set to 's' it will not cause the error in the 't' case, no idea why
                          GT=0;
                          temp=(inputcharacters[j+1]-0x30)*10;//
                          temp+=(inputcharacters[j+2]-0x30);
                          GT+=(temp*3600);
                          temp=(inputcharacters[j+3]-0x30)*10;
                          temp+=(inputcharacters[j+4]-0x30);
                          GT+=(temp*60);
                          temp=(inputcharacters[j+5]-0x30)*10;
                          temp+=(inputcharacters[j+6]-0x30);
                          GT+=temp;
                          j+=7;
                         break;
                      case 'o' :
                          {;}
                          break;
                      case 'l' :
                          {;}
                          break;
                      case '\r' :
                          {;}
                          break;
                      default :
                          {i++;}
                          }}
                      i=0;
                      j=0;
                      }
            else{i++;}}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_interupt(void)
{
    if(GT<86459)//24:00:59 in seconds
        {GT++;}//add a second
    else
        {GT=60;}//00:01:00
    if(timercount<299)//300s=5min
    {timercount++;}
    else{timercount=0;
         ADC10CTL0 |= 0x3;// turn on ADC
         while(ADC10CTL1 & ADC10BUSY)//loop to alow for ADC to finish sampeling
                 {;;}
         ADC10CTL0 & 0xFFFE;//Shuting off the ADC after sampeling
         tempature[i]=ADC10MEM;//Storing the tempature
         tempaturetime[i]=GT;// storing the time
         if(i<31)
             {i++;}
         else
             {i=0;}
        }
}

1 个答案:

答案 0 :(得分:0)

发布代码的一个非常明显的问题是,当发现当前正在检查的输入字符为x时,必须在用户输入{{1}后输入新的日期戳(作为6位数)但是在用户输入x之前,这可以使用,但是没有代码强制执行该输入序列。

一般来说,uart输入函数应该包含几个状态和子状态&#39;其中命令char导致代码切换到“状态”状态。那将有实际时间戳的子状态。所以当用户输入一个命令时,如\r一个模式被设置,输入的下一个6位是新的时间戳。

建议设计一个对语境敏感的&#39;状态图然后实现该图。

除此之外,输入缓冲区的大小将减少到1个字节

在许多排序问题中,有一个事实是,当积累一些数字时,说出像

这样的事情
x

不会产生预期的结果。

将产生预期结果的是:

int temp = 0;
temp += inputchar[x] - 0x30;
temp += inputchar[x+1] - 0x30;
...

当然,在尝试将该输入应用于int temp = 0; temp += inputchar[x] - 0x30; temp = temp*10 + (inputchar[x+1] - 0x30); .... temp = temp*10 + (inputchar[x+5] - 0x30); GT = temp;

的计算之前,使用if(isdigit(inputchar [x])测试每个inputchar

为了便于开发,强烈建议一次只尝试实现一个命令以及该命令何时正常工作(大量使用调试器使测试变得容易。例​​如temp调试器芯片。)然后转到下一个要执行的命令。

在两个中断处理程序中都修改了变量jtag。因此,当一个中断处理程序修改i时,另一个中断的值就会被破坏。

一整天(24小时)是878400秒,因此值86459不正确。此外,这是一个魔术&#39;代码中的数字。神奇的数字没有基础。 &#39;魔术&#39;数字使代码更难以理解,调试和维护。建议使用i声明或enum声明来提供“魔法”#39;编号一个有意义的名称,然后在整个代码中使用有意义的名称。注意:将#define计数器重置为60是不正确的,在发布的代码中应将其重置为0.

“魔法”也存在类似的考虑因素。 300号。

当输入命令为GT时,发布的代码没有动作,因此我们无法分析此类(不存在的)代码以确定它有什么问题。

处理l命令:

t变量可能会在访问之间进行修改。建议保存到新的&#39;变量并从该新变量中进行所有计算。

GThm的计算正在对相同的中间变量进行大量重新计算。建议:

s

数组int myGT = GT; h = myGT / 3600; myGT %= 3600; m = myGT / 60; s = myGT % 60; 已设置但未使用。这是生产代码中的资源浪费。建议其&#39;存在和设置由一些test[]编译器参数确定。