ISR for Timer Compare Match not running - c

so basically I'm trying set up a ISR(Interrupt subroutine) to simply turn a light on, but the ISR doesn't seem to run. I've looked through the microcontroller datasheet a lot to see if I'm doing something wrong but I couldn't find anything.
Heres my code.
#include <asf.h>
int main (void) {
DDRD = 0b10000000;
cli(); // turn off global interrupts
//Timer
TCCR2A |=_BV(WGM21); //CTC mode
TCCR2B |=_BV(CS22)|_BV(CS21); //clk pre-scale 1/256
OCR2A = 0x7d; //125clk cycles = 2ms
TIMSK2 |=_BV(OCIE2A); //enable interrupt on compare matchA
TIFR2 |= _BV(OCF2A); //clear flag
TCNT2 = 0x00; // reset counter
sei(); // enable global interrupts
}
ISR(TIMER2_COMPA_vect) {
PORTD = 0b10000000;
}

You should have an endless loop at the end of your main() function:
#include <asf.h>
int main (void) {
DDRD = 0b10000000;
cli(); // turn off global interrupts
//Timer
TCCR2A |=_BV(WGM21); //CTC mode
TCCR2B |=_BV(CS22)|_BV(CS21); //clk pre-scale 1/256
OCR2A = 0x7d; //125clk cycles = 2ms
TIMSK2 |=_BV(OCIE2A); //enable interrupt on compare matchA
TIFR2 |= _BV(OCF2A); //clear flag
TCNT2 = 0x00; // reset counter
sei(); // enable global interrupts
while(1);
}
ISR(TIMER2_COMPA_vect) {
PORTD = 0b10000000;
}
Without endless loop your AVR reaches an undefined state!

Related

ATmega32's TIMER1 isn't giving an interrupt when matching

I am working on a project and I have two external interrupts (push buttons) and using TIMER1 compare match mode, I want the timer to reach the top value twice (here I have it one time only because I was trying to see where's the problem) then turn off a dc motor but it doesn't seem to fire the interrupt, the external interrupts work btw, I even tried to toggle a led in the ISR and it won't do anything. Here's the code:
uint8 volatile flag=0; //for stopping the motor
void INT0_init(void)
{
MCUCR = MCUCR | (1<ISC01) ; /*interrupt with rising edge */
MCUCR = MCUCR | (1<<ISC00);
GICR |= (1<<INT0);
DDRD = DDRD & (~(1<<PD2)); /* setting PD2 as input pin */
}
ISR (INT0_vect)
{
SET_BIT(PORTB, PB3); //when the interrupt happens the motor moves in anti clockwise direction
CLEAR_BIT(PORTB, PB4);
TIMER1_ctcMode(0x0000, 0xFFFF);
while( PIND & (1<<PD2) ) {} /*to stay in this state as long as it got pressed once */
}
void INT1_init(void)
{
MCUCR = MCUCR | (1<ISC11) ; /*interrupt with rising edge */
MCUCR = MCUCR | (1<<ISC10);
GICR |= (1<<INT1);
DDRD = DDRD & (~(1<<PD3)); /* setting PD3 as input pin */
}
ISR (INT1_vect)
{
SET_BIT(PORTB, PB3); //when the interrupt happens the motor moves in clockwise directio
CLEAR_BIT(PORTB, PB4);
TIMER1_ctcMode(0x0000, 0xFFFF); //call the timer for 8-ish seconds
while( PIND & (1<<PD3) ) {} /*to stay in this state as long as it got pressed once */
}
ISR (TIMER1_COMPA_vect) //timer isr
{
flag++;
PORTA ^=(1<<0);
_delay_ms(500);
}
int main()
{
SET_BIT(SREG,7); /* setting the i-bit */
SET_BIT(DDRB, PB3); //setting the pins as output pins of the H-bridge
SET_BIT(DDRB, PB4);
TIMER1_initCtcMode();
INT0_init(); /* initializing interrupt0 */
INT1_init(); /*initializing interrupt1 */
while (1)
{
if(flag==1)
{
TIMER1_deinit(); // to stop the timer
CLEAR_BIT(PORTB, PB3); //when the timer finishes counting stop the motor
CLEAR_BIT(PORTB, PB4);
flag=0; //set the flag to zero for the next time the timer is used
}
}
}
and here's the timer configuration:
void TIMER1_initCtcMode(void)
{
SREG= SREG | (1<<7); //setting the i-bit
TIMSK |=(1<<OCIE1A); //setting interrupt enable for timer1
TIFR &=~(1<<OCF1A);
TCCR1A |=(1<<FOC1A) ;
TCCR1A |= (1<<FOC1B); //setting the non-pwm bits
TCCR1B |=(1<<WGM12);
TCCR1B |= (1<<CS12);
TCCR1B |= (1<<CS10); //setting prescalar at 1024
TCCR1B = TCCR1B &( ~(1<<CS11));
TCCR1A &= ~(1<<COM1A0); //clearing them for non-pwm mode
TCCR1A &= ~(1<<COM1A1);
}
void TIMER1_ctcMode(volatile uint16 initialValue, volatile uint16 topValue)
{
TCNT1=initialValue; //initial value
OCR1A=topValue; //top value to reach 8.3sec
}
void TIMER1_deinit(void)
{
CLEAR_BIT(TCCR1B, CS12);
CLEAR_BIT(TCCR1B, CS10);
CLEAR_BIT(TCCR1B, CS11);
TCNT1=0;
OCR1A=0;
TIMSK &=~(1<<OCIE1A);
}

Why a led in arduino uno is not toggling and is always in the "on" state?

An Arduino Uno LED is not toggling and is always in the "on" state, what could be wrong?
#include <avr/io.h>
void delay_timer0(){
TCNT0 = 0x00;
TCCR0A = 0x00;
TCCR0B = 0x01;
while((TIFR0 & 0x01) == 0);
TCCR0A = 0x00;
TCCR0B = 0x00;
TIFR0 = 0x01;
}
This is the infinite loop of toggling under the main method...
int main(void){
DDRB = DDRB | (1<<5); //output pb5
while(1){
PORTB = PORTB ^ (1<<5); //toggle bit
delay_timer0();
}
}
I bet it is a delay function problem
try
#include <util/delay.h>
/* .... */
while(1){
PORTB = PORTB ^ (1<<5); //toggle bit
delay_ms(500);
}
I found the error. I have worked with tinkercad and in that simulator the timer doesn't work. But I have configured this in real environment and it worked fine.

msp430 timer interrupts and port interrupts

I have written the following C code to trigger two port interrupts in order to blink a LED at different rates, I have used _delay_cycles(900000); instead I want to use a method delayMS(125); using timer interrpts, I tried as shown but Does not work , please help...
#include <msp430.h>
void initTimer_A(void);
void delayMS(int msecs);
unsigned int ofCount;
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1Mhz
DCOCTL = CALDCO_1MHZ;
P1OUT=0X00;
P1DIR=0x01; //P1.0 (LED) as output)
P1IES |= 0x08; // high -> low is selected with IESx = 1.
P1IFG &= ~0x08; // To prevent an immediate interrupt, clear the flag for
P1IE |= 0x08; // Enable interrupts for P1.3
P1DIR &= ~0b00001000; // p1.3 as in
P2OUT=0X00;
P2DIR=0x01; //P2.0 (LED) as output)
P2IES |= 0x08; // high -> low is selected with IESx = 1.
P2IFG &= ~0x08; // To prevent an immediate interrupt, clear the flag for
// P2.3 before enabling the interrupt.
P2IE |= 0x08; // Enable interrupts for P1.3
P2DIR &= ~0b00001000; // p2.3 as in
_enable_interrupt();
// initTimer_A();
ofCount = 0;
P1OUT |= 0x01; //Initially the led will glow
P2OUT |= 0x01; //Initially the led will glow
while(1)
{
}
return 0;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//configure timer
void initTimer_A(void){
TACCR0 = 0;
TACCTL0 |= CCIE;
TACTL = TASSEL_2 + ID_0 + MC_1;
}
void delayMS(int msecs){
ofCount= 0;
TACCR0 = 1000-1;
while(ofCount<=msecs);
TACCR0 = 0;//stp timer
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A_CCR0_ISR(void)
{
ofCount++;
}
//+++++++++++++++++ port vectors ++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#pragma vector = PORT1_VECTOR //PORT1 interupt vecotr name
__interrupt void P1_ISR(void) {
while(P1IN == 1){
P1OUT ^= BIT0;
This is the place where I want to change with delayMS() function using timer interrupts ….
_delay_cycles(900000);
//delayMS(125);
P1OUT ^= BIT0;
// delayMS(125);
_delay_cycles(900000);
P1IFG &= ~BIT3; } // clear the interupt flag
}
#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR(void) {
while(P2IN == 1){
P1OUT ^= BIT0;
_delay_cycles(9000);
//delayMS(125);
P1OUT ^= BIT0;
_delay_cycles(9000);
//P2OUT ^= BIT0;
P2IFG &= ~BIT3; } // clear the interupt flag
}

receiving and sending data from arduino to stml476RG

I am looking to receive serial data from an arduino, and then transmit the data received back to the arduino, however I am having trouble receiving the correct data. Below is my code, I am not sure on where I have gone wrong, can anyone see any problems?
I am using register level programming and using USART 3 on the STM32L476RG development board, an I am using ADM485 chip to transfer the data between each serial port.
#include "stm32L476XX.h"
#include "stdio.h"
int T ;
int R ;
uint8_t z;
void USART3_init(void)
{
USART3->BRR |= 26UL<<4; //BAUD RATE MANTISSA 234UL<<4
USART3->BRR |= 1UL<<0; // BAUD RATE FRACTION 6UL<<0
USART3->CR1 |= 1UL<<0; //enable USART
USART3->CR1 ^= 0UL<<28; //1 start bit, 8 data bits, n stop bit
USART3->CR1 ^= 0UL<<12; //also sets word length to 8 data bits
USART3->CR1 ^= 0UL<<10; //no parity control
USART3->CR1 |= 1UL<<6; //Transmission complete interrupt enabled
USART3->CR1 |= 1UL<<7; //TXE interrupt enable
USART3->CR1 |= 1UL<<5; //RXNEIE interrupt enable
USART3->CR2 ^=00UL<<12; //1 stop bit
USART3->CR1 |= 1UL<<3; // enable transmitter
USART3->CR1 |= 1UL<<2; // enable receiver
NVIC_EnableIRQ(USART3_IRQn); //enable USART interrupts
}
void Delay(void)
{
uint32_t i=0;
for (i=0; i<50000; i++){}
}
void USART3_IRQHandler(void)
{
//Delay();
if ((USART3->ISR>>5)&1UL) //Check if RXNE interrupt is high
{
z = USART3->RDR; //put what is on RDR into Z (also clears RXNE flag)
GPIOB->ODR |= 1UL<<5; //set transceiver into transmit mode USART3->TDR = z; // Clears TXIE flag and outputs z on TX
}
if ((USART3->ISR>>7)&1UL) //Check if TXIE interrupt is high
{
GPIOB->ODR &= 0UL<<5; //sets transceiver in receive mode
}
if ((USART3->ISR>>6)&1UL) //Check if TC interrupt is high
{
USART3->ICR |= 1UL<<6; //Clear TC flag
GPIOB->ODR &= 0UL<<5; //Set transceiver in receive mode
}
}
void RCC_GPIO_init(void)
{
RCC->APB1ENR1 |= 1UL<<18; //Enable USART 3 clock
RCC->AHB2ENR |= 1UL<<1; //Enable GPIOB clock
GPIOB->MODER = 0; //reset all register bits
GPIOB->MODER |= 2UL<<20; //enable GPIOB pin 10 as alternate function
GPIOB->MODER |= 2UL<<22; //enable GPIOB pin 11 as alternate function
GPIOB->MODER |= 1UL<<10; //enable GPIOB pin 5 as output
GPIOB->AFR[1] = 0; //reset all register bits
GPIOB->AFR[1] |= 7UL<<8; //enable GPIOB pin 10 as TX
GPIOB->AFR[1] |= 7UL<<12; //enable GPIOB pin 10 as RX
GPIOB->ODR ^= 0UL<<5; //GPIOB pin 5 as low (to put ADM485 transceiver in receive mode)
}
int main (void)
{
RCC_GPIO_init();
USART3_init();
while(1)
{
}
}

init External Interrupt on LPC213x/4x

Hi I write code below for initial External Interrupt for LPC2138 in KEIL 4.7 Compiler and when run code in proteus software , code dosent Work. I double check VIC and EXTINT registers seems correct. thanks
Project Picture on Proteus
one Switch on EXTINT2 (P0.15) and one LED on P1.25
#include <LPC213x.h>
void delay(int count);
void init_ext_interrupt(void);
__irq void Ext_ISR(void);
int main (void)
{
init_ext_interrupt(); // initialize the external interrupt
while (1)
{
}
}
void init_ext_interrupt(void) //Initialize Interrupt
{
EXTMODE = (1<<2); //Edge sensitive mode on EINT2
EXTPOLAR &= ~(1<<2); //Falling Edge Sensitive
PINSEL0 = 0x80000000; //Select Pin function P0.15 as EINT2
/* initialize the interrupt vector */
VICIntSelect &= ~(1<<16); // EINT2 selected as IRQ 16
VICVectAddr5 = (unsigned)Ext_ISR; // address of the ISR
VICVectCntl5 = (1<<5) | 16;
VICIntEnable = (1<<16); // EINT2 interrupt enabled
EXTINT &= ~(1<<2); //Set interrupt
}
__irq void Ext_ISR(void) // Interrupt Service Routine-ISR
{
IO1DIR |= (1<<25);
IO1SET |= (1<<25); // Turn ON LED
delay(100000);
IO1CLR |= (1<<25); // Turn OFF LED
EXTINT |= (1<<2); //clear interrupt
VICVectAddr = 0; // End of interrupt execution
}
void delay(int count)
{
int j=0,i=0;
for(j=0;j<count;j++)
{
for(i=0;i<35;i++);
}
}
You should correct the line:
(VICVectCntl5 = (1<<5) | 16;)
to:
(VICVectCntl5 = 0x20 | 16;)
as datasheet said.

Resources