请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:MSP430FR5994 主题中讨论的其他部件: MSP430WARE
我在MSP430FR5994上有一些将数字相乘的代码。 在本例中,我将80乘以1159,尽管在我的应用中,voltage_differation_range通常在1000左右。
int voltage_difference_range; long int range_um; voltage_difference_range = 80; range_um = voltage_difference_range * 1159;
80*1159=92720。9.272万。 但是,我显示的是2.7184万。 鉴于9.272万 - 6.5536万 = 2.7184万,我认为这是一个溢出问题是安全的。 问题是,我不明白为什么range_um会溢出。 根据MSP430Ware的调试器,range_um的值如下所示。
在我看来,还有2个字节可以包含数据,因为我将它声明为长。
请告诉我是否需要更多信息来解决此问题,或者是否有明显的解决方案来解决此问题。
我的完整代码,以防它有帮助。 问题代码本身位于代码底部附近的一个标志上。 我已经离开了初始化程序,以防它们提供帮助。
#include <msp430.h> #include <stdio.h> #include <stdlib.h> #define PWM_16HZ 2048 #define PWM_32HZ 1024 char printkeeper; int memval3_old = 0, memval4_old = 0, memval3_new = 0, memval4_new = 0, i = 0; //Old is for storing old ADC values int voltage_difference_new, voltage_difference_old, voltage_difference_range, voltage_difference_doppler; //Remove float whenever possible! long int range_um, speed_um; int range, speed; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop WDT // GPIO Setup P1OUT &= ~BIT0; // 16Hz Clock Pin Setup P1DIR |= BIT0 | BIT1 | BIT2 | BIT5; // Bits 1.2, 1.5 set to clock (TA1.1, TB0.2) (p88_s, p91_s) P1SEL0 |= BIT0 | BIT1 | BIT2 | BIT5; // See p88-90_s PJSEL0 = BIT4 | BIT5; // For XT1 Oscillator (p118_s) P1SEL1 |= BIT3 | BIT4 ; // ADC Pin Setup P1SEL0 |= BIT3 | BIT4 ; // 1.3 and 1.4 set to ADC input (A3, A4) from p90_s P3DIR |= BIT0; // Set Pin 3.0 as output, for permanent 3.3V. // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; //P1OUT |= BIT0; // Clock System Setup CSCTL0_H = CSKEY_H; // Unlock CS registers CSCTL1 = DCOFSEL_3; // Set DCO to 4MHz (p105) CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK; // Set clock source CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers, clock speed 1MHz CSCTL4 &= ~LFXTOFF; // Something related to the 32kHz oscillator do { CSCTL5 &= ~LFXTOFFG; // Clear XT1 fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag CSCTL0_H = 0; // Lock clock registers //ADC Setup ADC12CTL0 = ADC12SHT0_0 | ADC12ON; // Sampling time, S&H=4, ADC12 on [p893, CTL0 = control 0, SHT0_0 = sample & hold time, knowledge of register value from p88_s] ADC12CTL1 = ADC12SHP | ADC12SHS_4 | ADC12CONSEQ_1; // Use TA1.1 to trigger, (SHP means using sample timer (p897), SHS means "sample-and-hold source select" (p895, p84_s) // which selects which source is used to activate sampling (4 being TA1.1 because of p84_s), CONSEQ_1 = Conversion sequence select, // 1 means multiple-channel which means multiple channels are converted and sampled, memory gets overriden everytime (p881) ADC12CTL2 |= ADC12RES_2; // 12-bit conversion results, p897 ADC12CTL3 |= ADC12CSTARTADD_3; // Use MEM3/MCTL3 as first, p898 ADC12MCTL3 = ADC12INCH_3 ; // A3 ADC input select from Input Channel 3 (p901), output to MEM3 ADC12MCTL4 = ADC12INCH_4 | ADC12EOS; // A4 ADC input select, also setting EOS bit at A4 ADC12IER0 |= ADC12IE3 | ADC12IE4; // Enable ADC interrupt [IER = interrupt enable, for IFG0 bit, which tells us when the sequence is complete] // Configure TimerA1.1 to periodically trigger ADC12 at a rate of 32Hz TA1CCR0 = PWM_32HZ - 1; // PWM Period for TA1, 1024/32768 = /32 TA1CCTL1 = OUTMOD_3; // TACCR1 set/reset (Shape of set/reset in p652) TA1CCR1 = PWM_32HZ / 2; // TACCR1 PWM Duty Cycle TA1CTL = TASSEL__ACLK | MC__UP; // ACLK, up mode // Configure TimerA0.0 to generate a 16Hz Square Wave TB0CCR0 = PWM_16HZ - 1; // PWM Period for TB0, 2048/32768 = /16 TB0CCTL2 = OUTMOD_7; // TBCCR1 set/reset (Shape of set/reset in p652) TB0CCR2 = PWM_16HZ /2; // TB0CCR2 PWM Duty Cycle TB0CTL = TASSEL__ACLK | MC__UP; // ACLK, up mode ADC12CTL0 |= ADC12ENC | ADC12SC; // Start sampling/conversion printf("135\n"); __bis_SR_register(LPM0_bits | GIE); // Enter LPM0, enable interrupts __no_operation(); } // ADC12 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC12_B_VECTOR __interrupt void ADC12ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC12_B_VECTOR))) ADC12ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(ADC12IV, ADC12IV__ADC12RDYIFG)) { case ADC12IV__ADC12IFG3: // Vector 18: ADC12MEM3 memval3_old = memval3_new; memval3_new = ADC12MEM3; ADC12IFGR0 &= ~ADC12IFG3; break; case ADC12IV__ADC12IFG4: // Vector 20: ADC12MEM4 memval4_old = memval4_new; memval4_new = ADC12MEM4; voltage_difference_new = abs((memval3_new - memval4_new)); // These values are both +ve, rising edge voltage_difference_old = abs((memval3_old - memval4_old)); // These values are both +ve, falling edge voltage_difference_range = ((voltage_difference_new + voltage_difference_old)); voltage_difference_doppler = ((voltage_difference_new - voltage_difference_old)); //Lower frequency means moving away //printf("%d\n", voltage_difference_range); voltage_difference_range = 80; range_um = voltage_difference_range * 1159; //Check notebook math, this is in micrometers to avoid floats speed_um = voltage_difference_doppler * 15766; //Check notebook math, also in micrometers if (printkeeper == 31){ printkeeper = 0; printf("VD: %d\n", voltage_difference_range); printf("R: %d\n", range_um); i++; } else { printkeeper = printkeeper + 1; } ADC12MCTL4 |= ADC12EOS; ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 |= ADC12ENC; break; default: break; } }