Using interrupt timer diasbles my uart

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,i have an application where i send some data to uart every "n" seconds. But i also wish to enable me to request data from the application by writing 0x71 to UART. The software works great when it is just the interupt timer, or onyl UART part but when i  put it together (like in attached code), the data is being periodcly transmited to uart (i read on pc), but at the moment i send any type of data to application, the porgram hangs up and stop transmitting data peridoacly, and there is also no asnwer to my request. But if i disable sei(); in the interrupr set up part of code, then the uart response works fine, so i assume it points to a clash whit interrupts or someting.

 

Any help will be appreciated.

#define F_CPU 2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "i2c_master.h"

#define BAUD 9600UL
#define THRESHOLD 20

#define tmp_w	0b00110010				//Write
#define tmp_r	0b00110011				//Read

uint16_t ReadADC(uint8_t ADCchannel);
void InitADC(void);
void uart_init(void);
void receive(void);

void Init_pins(void);
int ice_read(void);
int temp_read(void);
int Print_uart (int pl);
int level_read(void);

char recieved_byte;
int count=0;
int flag = 0;
volatile uint8_t total_overflow = 0;

int main(void){
	Init_pins();
	uart_init();
	i2c_init();
	InitADC();

	// Setting the 1024 prescaler
	TCCR0B |= (1 << CS00) | (1 << CS02);
	// Initialize Timer0
	TCNT0 = 0;
	// Initialize the overflow interrupt for TIMER0
	TIMSK0 |= (1 << TOIE0);
	sei();

	while(1)
	{


                          ///UART response part
		      if ( UCSR0A & ( 1 << RXC0 )){
			while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){}
				recieved_byte = UDR0;

			 	if (UDR0 == 0x71)
			 	{
			 		Print_uart(temp_read());
			 		Print_uart(ice_read());
			 		Print_uart(level_read());
			 	}
			}





                //Periodacly data senidn part
		if(total_overflow >= 23)
		{
			if(TCNT0 >= 12){
				Print_uart(temp_read());
				Print_uart(level_read());
				Print_uart(ice_read());
				TCNT0 = 0;
				total_overflow = 0;
			}
		}

	}
}

ISR(TIMER0_OVF_vect)
{
	total_overflow++;
}

void Init_pins(void){
	// Nastavi ICE  multiplex naslovne pine kot izhode
	DDRB  |= (1 << 1);
	DDRD  |= (1 << 7)|(1 << 6)|(1 << 5);
	PORTB &= ~(1 << 1); //High izklopi multiplex out

	// Nastavi Water multiplex naslovne pine kot izhode
	DDRB  |= (1 << 0);
	DDRD  |= (1 << 2)|(1 << 3)|(1 << 4);
	PORTD &= ~(1 << 4); //High izklopi multiplex out

	//Nastavi OUT pin kot output
	DDRC |= (1 << 2);
	PORTC  |= (0 << 2);

}

void InitADC(void)
{

	//adc init
}

uint16_t ReadADC(uint8_t ADCchannel)
{
	//adc read
}

void uart_init (void){
	int UBRRn = 12;

	UBRR0H = (UBRRn >> 8);
	UBRR0L = UBRRn;
	UCSR0B = (1 << TXEN0)| (1 << TXCIE0) | (1 << RXEN0) | (1 << RXCIE0);
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
	UCSR0A = (0 << U2X0);
}

void receive(void){
	while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){}
	recieved_byte = UDR0;

	if (UDR0 == 0x71)
	{
		Print_uart(temp_read());
		Print_uart(ice_read());
		Print_uart(level_read());
	}
}

int Print_uart (int pl){

	while (( UCSR0A & (1<<UDRE0))  == 0){};
	UDR0 = pl;

	return 0;
}

int temp_read(void){
	//i2c read
	return Temp;
}

int ice_read(void){
	//Analog pins read
	return debelina;
}

int level_read(void){
	//Analog pins read
	return level;
}

 

This topic has a solution.

Last Edited: Fri. Sep 8, 2017 - 05:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if (UDR0 == 0x71)    ->   if (recieved_byte == 0x71)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thks, but i tried and program still hangs when i send data from pc to uart.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 if ( UCSR0A & ( 1 << RXC0 )){
			while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){}
				........
			}
}

When will the IF statement and WHILE statement both be true? 

 

Instead of using inline register testing, why not use conventional I/O functions like getchar() and kbhit()?

 

 

also instead of using magic numbers isn't this much more readable:

if (UDR0 == 'G')

 

Jim

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Your basic problem is that you enable the UART interrupts without actually using them (no ISRs).

Stefan Ernst

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your basic problem is that you enable the UART interrupts without actually using them (no ISRs).

Which means every time the USART Rx's a char, it vectors to 0x0000 (the RESET vector).

 

 

EDIT:

 

I see two solutions: 1) Disable USART interrupts and remove the if {} that Jim points out above, or 2) write ISRs for the USART RXC and TXC interrupts.

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

Last Edited: Thu. Sep 7, 2017 - 02:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks to everyone, i used all infos and got it working :D