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.

MSP430F4152: MSP430F4152使用定时器、系统时钟、及调用math.h文件疑问

Part Number: MSP430F4152
Other Parts Discussed in Thread: ADS1118

目前我用这款单片机写了一个定时器,对ADS1118持续检测温度的持续。但现在使用中遇到下列问题:

1.我在用定时器的时候,如果不打断点看数据,都能正常跑,而一旦需要打断点的时候,定时器就莫名奇妙的跑飞了,中断就进不去了,代码如下

void initTIMERA(void)
{
    CCTL0 = CCIE;                            // CCR0 interrupt enabled
    CCR0 = 409-1;
    TACTL = TASSEL_1 + ID_2 + MC_1 + TACLR;          // ACLK/4, T=409/(32768/4) 约  50ms, Up to CCR0
    TAR = 0;                               
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
//    P3OUT ^= BIT4;
   Status.TimerFlag = 1;
   Status.CNT++;
   TA0CTL = 0x0190;
}

2.我在程序中调用了log() 函数,我把这个函数屏蔽的时候,程序都正常,但是一旦使用,发现程序就会把我前面的数据都清空掉;

3.时钟用例程中的代码,我不确定是否与系统时钟有关,低功耗的配置目前还没打开。

SCFI0 |= FN_4;                            // x2 DCO freq, 8MHz nominal DCO
    SCFQCTL = 121;                            // (121+1) x 32768 x 2 = 7.99 Mhz
    FLL_CTL0 |= DCOPLUS + XCAP11PF;           // DCO+ set so freq= xtal x D x N+1  D:2(default)  ;  load capacitance 11pf for xtal

大致就这3个方面。主要是看看能否解决一下。

现在卡在log函数里,导致无法计算温度值。

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	SetSysCLK();
	initTIMERA();
	initUart();
	initSPI();
	SetLEDInit();
	SetRef_IC();
	SetSwitchEN();
	initlcd();
	disp_full();
	__delay_cycles(5000000);
	disp_clr();
	disp_unit();
	_EINT();
//	_BIS_SR(LPM3_bits + GIE);
	while(1)
	{

	 UartTx();

	 //每50 ms 进行写配置/读返回数据 
	 if(Status.TimerFlag == 1)
	 {
	     Status.TimerFlag = 0;
	     switch(Status.CNT)
	    {
	        //1st 热电阻、传感器、热电偶
	        case 1:
	            THR_TEMP_SET(0);
	        break;

	        case 2:
	            THR_TEMP_SET(1);
	            THR_TEMP_RETURN();
	        break;

	        case 3:
	            TEMP_SENSOR_SET(0);
	        break;

	        case 4:
	            TEMP_SENSOR_SET(2);
	            TEMP_SENSOR_RETURN();
	        break;

	        case 5:
	            TC_TEMP_SET(0);
	        break;

	        case 6:
	            TC_TEMP_SET(3);
	            TC_TEMP_RETURN();
	       break;

	       case 7:
	           temp_convert();
	           // Print_Data();
	            Status.CNT = 0;

           if(((Status.TC_CAT/10) >= 0) && ((Status.TC_CAT/10) < 100))
           {
               if(Status.overFlag == 1){
                   Status.overFlag = 0;
                   disp_clr();
               }
               disp_num(Status.TC_CAT/10);
           }
           if((Status.TC_CAT/10) >= 100)
           {
               disp_clr();
               disp_bar();
               Status.overFlag = 1;

           }

	       break;

	        default:

	        break;

	    }
	 }

//	 _BIS_SR(LPM3_bits + GIE);             // Enter LPM3
//	 _NOP();                               // Required only for C-spy
	}
	return 0;
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCIA0TX_ISR (void)
{
    if(IFG2 & UCB0TXIFG)                    //SPI中断
    {
        IFG2 &= ~BIT3;
        // do SPI stuff
        if(Status.SPIFlag == 0 ){}            //热电阻、热电偶、内部传感器配置第1次,把垃圾数据丢掉

        if(Status.SPIFlag == 1 ){            //热电阻配置第2次,把数据取出
            if(UCB0TXBUF == 0xB4){
            Status.THRtemp_H = UCB0RXBUF;
            Status.temp_test = 1;
            }
            if(UCB0TXBUF == 0x8B){
            Status.THRtemp_L = UCB0RXBUF;
            Status.temp_test++;
            }
        }
        if(Status.SPIFlag == 2 ){            //传感器配置第2次,把数据取出
            if(UCB0TXBUF == 0x84)
            Status.SENSOR_H = UCB0RXBUF;
            if(UCB0TXBUF == 0x9B)
            Status.SENSOR_L = UCB0RXBUF;
        }
        if(Status.SPIFlag == 3 ){            //热电偶配置第2次,把数据取出
            if(UCB0TXBUF == 0x84)
            Status.TCtemp_H = UCB0RXBUF;
            if(UCB0TXBUF == 0x8B)
            Status.TCtemp_L = UCB0RXBUF;
        }

    }
}


// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
//    P3OUT ^= BIT4;
   Status.TimerFlag = 1;
   Status.CNT++;
//   TA0CTL = 0x0190;
}

  • 1. 你虽然打了断点,但是计数器并不会暂停计数;

    2. 我没在你的代码中找到log函数。方便指明或说明一下吗?

    3. 方便指一下是哪个例程吗?

  • 刚刚问题已解决了,找到了问题的原因是开了串口打印调试数据,可能是我把调试过程中的buffer空间开的太大了,导致内存空间超出限制范围。

    不过也奇怪,为啥编译就能过了。

    log函数应用的地方

    //计算温度数据
    void temp_convert()
    {
        double tempTHR_CAT = 0;
        double tempImpedance = 0;
    
        Status.TC_CAT = Status.V_TCSample*10/39 + Status.temperatureSENSORSample;
    
        Status.V_THRSample_16Bit = Status.V_THRSample;
        Status.impedance = (10200*Status.V_THRSample + 409600)*1000 / (204800 - Status.V_THRSample*102);
        Status.impedance_16Bit = Status.impedance;
        tempImpedance = Status.impedance_16Bit;
    
        PrintfBufLen = sprintf(PrintfBuf,"1");
        UARTwrite(PrintfBuf,PrintfBufLen);
    
        tempTHR_CAT = 1512.927/(log10(tempImpedance)+0.732)-273.15;
        Status.THR_CAT = tempTHR_CAT;
         
        PrintfBufLen = sprintf(PrintfBuf,"2\r\n");
        UARTwrite(PrintfBuf,PrintfBufLen);
    }
    

    打印的相关设置信息,目前把SIZE都调小了,程序就正常了

    #define RCB_SIZE                32
    #define CB_SIZE                 16
    #define CB_SIZE_MASK            (CB_SIZE - 1)
    
    int UARTwrite(const char *msg, unsigned int len)
    {
        int i;
    
        for (i = 0; i < len; i++)
        {
            if ((wcb_w - wcb_r) != CB_SIZE)
            {
                wcbuffer[wcb_w++ & CB_SIZE_MASK] = msg[i];
            }
            else
            {
                // buffer full, discard remaining characters and return
                break;
            }
        }
    
        return i;
    }
    
    void UartTx(void)
    {
        // Copy to TX BUF
        while ((wcb_w != wcb_r) && (IFG2&UCA0TXIFG))
        {
            UCA0TXBUF = wcbuffer[wcb_r++ & CB_SIZE_MASK];
        }
    }
    
    

    例程是用了msp430x41x2_fll_02.c设置8M的时钟,msp430x41x2_ta_05.c设置定时器,msp430x41x2_uscia0_uart_9600.c设置串口,msp430x41x2_uscib0_spi_09.c设置SPI,另外这个SPI的中断有点坑,例程是通过接收来进入进入中断,结果我在调试中发现16位数据只收到8位,最后把SPI的接收改成发送就正常了,我想吐槽一下。