Помогите найти ошибку в коде

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Аватара пользователя
Сообщения: 3
Зарегистрирован: Вс мар 11, 2012 20:07:57
Откуда: Тамбов

Сообщение nlozet »

Написал небольшой код для Atmega16, который должен считать импульсы с T1. Код не работает, проблема в зациклевинии while функции Mesure, как выйти из этой ситуации не соображу. В программировании под МК новичок, так что сильно не пинайте.

Код: Выделить всё

#include <avr/io.h>
#define F_CPU	16000000UL
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdlib.h>
#include <stdio.h>
#include "n3310.h"
#include "picture.h"
typedef _Bool         bool;
#define false 0
#define true  1

//---------------Глобальные переменные--------------
double Value;
double f1,f2,f3;
char Buffer[200];

unsigned long CountLow = 0;
unsigned long CountHigh = 0;
unsigned long Count = 0;
unsigned long CountT0 = 0;
unsigned long Test = 0;
bool StatusCount = false;

//-------Обработка прерывания на переполнение счетчика T0-------
ISR(TIMER0_OVF_vect)
{
	if(CountT0 >= 62500) // Через 1 секунду
	{
		TCCR1B = 0;	// Выключить счётчик T1
		TCCR0 = 0;	// Выключить счетчик T0
		CountLow = TCNT1;
		Count = CountLow + (CountHigh << 16);
		StatusCount = true;	
	}
	CountT0++;
}

//-------Обработка прерывания на совпадение счетчика T1-------
ISR(TIMER1_COMPA_vect)
{
	CountHigh++;
}

//------------Инициализация счетчиков---------------
void TIMER_Init(void)
{
//------Настройка счётчика T1 (подсчет импульсов)----------
	TIMSK |= (1<<OCIE1A);	// Совпадение TCNT1 и OCR1A
	OCR1A = 65535;		// Значение для сравнения 0xffff
	TCCR1B = 0;		// Выключить счетчик
	
//------Настройка счётчика T0 (подсчет времени)------------
	TIMSK |= (1<<TOIE0);	// Прерывание по переполнению
	TCCR0 = 0;		// Выключить счетчик
}

unsigned long Mesure(void)
{
	CountHigh = 0;		// Инкремент по переполнению счетчика T1 (65535)
	CountT0 = 0;		// Инкремент по переполнению счетчика T0 (256)
	TCNT1 = 0;		// Счетчик T1 в ноль
	TCNT0 = 0;		// Счетчик T0 в ноль
	TCCR1B |= TCCR1B = (1<<CS12)|(1<<CS11)|(1<<CS10); // Внешнее тактирование по выводу T1
	TCCR0 |= (1<<CS00)|(0<<CS01)|(0<<CS02); // Делитель счетчика T0
	while(!StatusCount); // Не выходит из цикла
	return Count;
}

int main(void)
{
	TIMER_Init();

	LcdInit();

	asm("sei");	// Разрешить внешние прерывания
	
	StatusCount = false;
	
	Test = Mesure();	// Тут зависает
	
	LcdClear();
	LcdGotoXYFont(1,1);
	dtostrf(Test, 0, 2, Buffer);
	LcdStr(1,Buffer);
	LcdUpdate();
	_delay_ms(2000);

    while(1)
    {
    }
}

Реклама
Родился
Сообщения: 8
Зарегистрирован: Ср янв 18, 2012 07:36:07

Сообщение LeXSS »

Оператор StatusCount = true выполнится всего 1 раз, т.к. Вы останавливаете таймеры после переполнения.
Реклама
Родился
Аватара пользователя
Сообщения: 3
Зарегистрирован: Вс мар 11, 2012 20:07:57
Откуда: Тамбов

Сообщение nlozet »

проблема решена добавлением volatile

Код: Выделить всё

volatile bool StatusCount = false;
Родился
Сообщения: 8
Зарегистрирован: Ср янв 18, 2012 07:36:07

Сообщение LeXSS »

Решил-молодец. Теперь расскажи всем как и почему, приведи исправленный код-поделись опытом.
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «AVR»