I have the following program to generate a train of modulated voltage pulses from P1.0 based on the values of a sequence stored in an array.
If it is 1, then the pin output is low for 750ns before changing to high. If it is 0, then output is low for 250ns before changing to high. The pulses must occur at a rate of 128kHz. P1.0 output is automatically controlled by TimerA0 whenever CCR0 or CCR1 is reached.
However, when tested using breakpoints, elements in the array are skipped when TA0CCR0 < approx. 100. When its value is increased, the sequence is read properly, but an oscilloscope shows that the length of each pulse is almost completely random, sometimes pulses are just skipped out all together. The elements skipped seems to change depending on minor changes e.g. whether 'position' or the array type is an integer or a character
This is a section of a larger program where 4 timers are being used simultaneously. Is it an issue with stack overflow, or am I just trying to change the values of TA0CCR1 in too short a space of time?
I can't see any reason for it to be doing this, is it possible that the MCU has been damaged at some point?
--------------------------------------------------
char ElectrodeSequence[32] = {1,1,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0};
char position;
void main (void)
{
CSCTL0_H = 0xA5; // Unlock register
CSCTL1 = DCOFSEL_3; // Set DCO = 8MHz
CSCTL2 = SELA_1 + SELS_3 + SELM_3; // ACLK = vlo; SMCLK and MCLK = DCO
CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // No Divider
CSCTL0_H = 0x01; // Lock Register
//Set P1.0 to be controlled by TimerA
P1DIR |= BIT0;
P1OUT &= ~BIT0;
P1SEL1 &= ~BIT0;
P1SEL0 |= BIT0;
TA0CTL = TACLR; //Reset TimerA
TA0CCTL0 = CCIE; //Enable interrupt
TA0CCTL1 = OUTMOD_3 + CCIE; //output mode set/reset and compare capture interrupt enable
TA0CCR0 = 63; //Read sequence at approx. 128kHz
TA0CCR1 = 6; //First character is always 1 = 750ns
position = 0; //Start with first element in array
//Start timer//
TA0CTL = TASSEL_2 + MC_1; //SMCLK, count up to TA0CCR0
//Electrode pulse sequence//
while (position < 32); //Repeat until every digit has been read
TA0CTL = MC_0; //Stop timer
position = 0; //Reset position to 0
}
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A1_ISR (void)
{
switch(TA0IV){
case 2:
{
if (ElectrodeSequence[position+1] == 1) //Read next digit in Sequence
{
TA0CCR1 = 6;
}
else if (ElectrodeSequence[position+1] == 0)
{
TA0CCR1 = 2; //Define interval for next digit depending on whether it is 1 or 0
}
TA0CCTL1 &= ~CCIFG; //Manually reset flag to prevent stack overflow
}
break;
}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0_ISR (void)
{
position++; //Move along Sequence
TA0CCTL0 &= ~CCIFG; //Manually reset to prevent stack overflow
}