Necesito ayuda con un MSP430F2272. Estoy trabajando en una tarea para la clase donde se supone que debo hacer un generador de funciones. Pongo el código que he escrito hasta aquí abajo. La mayoría de las partes individuales del código funcionan bien, excepto por una cosa: el TimerA, que se supone que controla la frecuencia de la salida, no se dispara correctamente. Después de iniciar el programa, el depurador llega hasta P1DIR = 0x00
en main()
antes de ingresar al ISR TimerA0. El problema es inmediatamente después de que se realiza el ISR, salta de nuevo a P1DIR = 0x00
, y luego entra nuevamente en el ISR. El contador del temporizador solo está en 0x0005
y el registro de comparación contiene 0x0064
, por lo que no debería activarse, pero sigue haciéndolo. Si pudiera hacer que eso parara, estoy bastante seguro de que el resto del programa funciona exactamente como lo deseo. ¿Alguien puede ayudar?
#include <msp430.h>
#include "msp430x22x2.h"
/* P4 - Digital Input
* P2 - DAC Output
* P3 - ADC Input
*
*/
char sine[50] = {0x80,0x90,0xA0,0xB0,0xBE,0xCC,0xD9,0xE4,0xED,0xF5,0xFA,0xFE,0xFF,0xFF,0xFC,0xF8,0xF1,0xE8,0xDE,0xD2,0xC5,0xB7,0xA8,0x98,0x88,0x77,0x67,0x57,0x48,0x3A,0x2D,0x21,0x17,0x0E,0x07,0x03,0x00,0x00,0x01,0x05,0x0A,0x12,0x1B,0x26,0x33,0x41,0x4F,0x5F,0x6F,0x7F};
char squr[50] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
char trgl[50] = {0x00,0x0A,0x15,0x20,0x2A,0x35,0x40,0x4A,0x55,0x60,0x6A,0x75,0x80,0x8A,0x95,0xA0,0xAA,0xB5,0xC0,0xCA,0xD5,0xE0,0xEA,0xF5,0xFF,0xFF,0xF5,0xEA,0xE0,0xD5,0xCA,0xC0,0xB5,0xAA,0xA0,0x95,0x8A,0x80,0x75,0x6A,0x60,0x55,0x4A,0x40,0x35,0x2A,0x20,0x15,0x0A,0x00};
char swth[50] = {0x00,0x05,0x0A,0x0F,0x14,0x1A,0x1F,0x24,0x29,0x2F,0x34,0x39,0x3E,0x43,0x49,0x4E,0x53,0x58,0x5E,0x63,0x68,0x6D,0x72,0x78,0x7D,0x82,0x87,0x8D,0x92,0x97,0x9C,0xA1,0xA7,0xAC,0xB1,0xB6,0xBC,0xC1,0xC6,0xCB,0xD0,0xD6,0xDB,0xE0,0xE5,0xEB,0xF0,0xF5,0xFA,0xFF};
int i = 0;
int wave_sel = 0;
char dout = 0x00;
void dac_write(char data){
int output = 0x0000;
char temp;
signed char x;
P2SEL &= 0xF8; //select digital I/0
P2DIR |= 0x07; //set directon register P2.0 - P2.2
P2OUT &= 0xF8; // clear data, clock, and enable
P2OUT |= 0x04; // set enable high
temp = data; // format data
data = data >> 4;
data &= 0x0F;
data |= 0xF0;
output = data;
output <<= 8;
data = temp;
data <<= 4;
data &= 0xF0;
output |= data;
P2OUT &= 0xFB; //set enable low
for (x = 15; x > -1; x--){ //send out 16 bits of data
P2OUT |= (output >> x) & 0x01;
P2OUT |= 0x02;
P2OUT &= 0xFD;
P2OUT &= 0xFE;
}
P2OUT |= 0x04; // set enable high
}
int main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
TACCTL0 = CCIE;
TACTL = TASSEL_2 + MC_1 + ID_3; //CLK(1MHz) /8
TACCR0 = 100; //25-100 Hz 250-10Hz
TACCR1 = 0xFFFF;
TACCR2 = 0xFFFF;
_BIS_SR(LPM0_bits + GIE);
P1DIR = 0x00;
P2DIR = 0xFF; //DAC Ouptut
P3DIR = 0x00; //ADC Input
P4DIR = 0x00; //Digital Input
P3SEL |= BIT6 + BIT7;
ADC10CTL0 = SREF_0 + ADC10SHT_3 + MSC + ADC10ON + ADC10IE;
ADC10CTL1 = INCH_7 + ADC10DIV_3 + CONSEQ_1;
ADC10AE0 |= 0xC0; //Turn on ADC of 3.6 and 3.7
ADC10DTC1 = 2;
double amp = 0;
double freq = 0;
unsigned int ADC[2];
for(;;)
{
wave_sel =P4IN;
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY);
ADC10SA = (unsigned int)ADC;
ADC10CTL0 |= ENC + ADC10SC;
freq = (double)ADC[0]/1023;
amp = (double)ADC[1]/1023;
TACCR0 = 25 + (freq*225);
dout *= amp;
dac_write(dout);
}
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1(void)
{}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
if (wave_sel == 0)
{
dout = sine[i];
}else if (wave_sel == 1)
{
dout = squr[i];
}else if (wave_sel == 2)
{
dout = trgl[i];
}else if (wave_sel == 3)
{
dout = swth[i];
}
if (i<49){
i += 1;
}else{
i = 0;
}
}