Страница 1 из 1

Часики на attiny2313, нужна помощь

Добавлено: Пт мар 22, 2013 01:51:40
aligator33
Здравствуйте, собрал часики http://licrym.org/index.php/Простые_часы
Теперь не могу откомпилировать исходник, что я делаю не так?

Сообщение компилятора:
Спойлер-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C: main.c
avr-gcc -c -mmcu=attiny2313 -I. -gdwarf-2 -DF_CPU=1600000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c:27: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'button_pressed1'
main.c:31: error: 'TIM1_COMPA' undeclared here (not in a function)
main.c:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
main.c:83: warning: return type of 'main' is not 'int'
main.c:171:2: error: invalid preprocessing directive #asm
main.c: In function 'main':
main.c:177: warning: implicit declaration of function 'delay_ms'
main.c:195: error: 'button_pressed1' undeclared (first use in this function)
main.c:195: error: (Each undeclared identifier is reported only once
main.c:195: error: for each function it appears in.)
main.c:206: error: 'button_pressed2' undeclared (first use in this function)

make.exe: *** [obj/main.o] Error 1
а вот и сам исходник:
Спойлер-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C: main.c
avr-gcc -c -mmcu=attiny2313 -I. -gdwarf-2 -DF_CPU=1600000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c:27: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'button_pressed1'
main.c:31: error: 'TIM1_COMPA' undeclared here (not in a function)
main.c:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
main.c:83: warning: return type of 'main' is not 'int'
main.c:171:2: error: invalid preprocessing directive #asm
main.c: In function 'main':
main.c:177: warning: implicit declaration of function 'delay_ms'
main.c:195: error: 'button_pressed1' undeclared (first use in this function)
main.c:195: error: (Each undeclared identifier is reported only once
main.c:195: error: for each function it appears in.)
main.c:206: error: 'button_pressed2' undeclared (first use in this function)
make.exe: *** [obj/main.o] Error 1

Заранее благодарен!

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт мар 22, 2013 06:28:57
pyzhman
Вы не тем компилятором пользуетесь. Программа написана из-под CodeVision. И с исходником в вашем сообщении намудрили :)) . И не забудьте прошить фузы микроконтроллера на генератор от внешнего кристалла. Обратите внимание на то, что переменная milliseconds на самом деле - десятки миллисекунд(если вдруг будете разбираться с программой).

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт мар 22, 2013 22:24:27
aligator33
Большое спасибо с прошивкой. Получилось откомпилировать в CodeVision .
Вопрос в следующем - в наличии были только индикаторы с общим катодом. вот и собрал часики по следующей схеме:
Хочу разобраться и написать программу в WinAVR с чего начать?

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт мар 22, 2013 23:25:43
Vov123
С книги Шпака (1 - издание).

Re: Часики на attiny2313, нужна помощь

Добавлено: Вт апр 02, 2013 22:38:47
aligator33
Вот скачал книгу, переписал код - часы показывают что-то не понятное не могу правильно сконфигурировать порты. Господа глянте где ошибка?

Прошу строго не судить - учусь я :?
/*
1. С помощью прерывания получаем точные временные интервалы - например 1сек
2. Считаем эти интервалы. из них слаживаем минуты, часы.
3. Загружаем значение текущего времени в некий буфер, откуда оно будет выводится на индикаторы с помощью динамической индикации.
4. кнопки для управления часами - это уже по вкусу.

Микроконтроллер тактируется кварцем с частотой 16 МГц.
В качестве счетчика времени, внутри микроконтроллера запущен 16 битный таймер с предделителем 256 (т.е. частота отсчетов таймера 62500 Гц),
настроенный на создание прерывания по достижении счетчиком значения 625. Таким образом, мы получаем прерывания ровно 100 раз в секунду (тоесть получаем временный интервал 10 милисекунд).
Значение времени хранится в глобальных переменных, и каждое прерывание мы увеличиваем значение миллисекунд на 1.
Если количество миллисекунд достигает 100, то мы увеличиваем на 1 значение секунд, а значением миллисекунд сбрасываем.
И так далее вплоть до десятков часов, которые сбрасываются по достижении 24 без увеличения следующего разряда.
Часы предельно простые, поэтому не считают ни дату, ни перевод на зимнее/летнее время и т.д.
Данные функции можно реализовать программно, без изменения аппаратной части, поэтому остаются для реализации желающим.
Разобравшись с таймером и прерываниями мы получаем значение текущего времени в глобальных переменных. Теперь займемся выводом этих значений.
Так как количество портов микроконтроллера ограничено, то будем эксплуатировать инерционность зрения.
Катоды всех 4 индикаторов соединены параллельно, а аноды коммутируются отдельно, что позволяет нам в любой момент
времени вывести любую цифру на любой индикатор. Быстро переключая порт B, к которому подключены катоды и быстро переключая
аноды мы можем создать видимость, что у нас работают все 4 цифры, хотя единовременно работает только одна. Иными словами,
если текущее время 12:51, то мы выводим цифру 1 на первый индикатор, спустя малый промежуток времени (у меня 1 мс)
выводим цифру 2 на второй индикатор, спустя 1 мс выводим 5 на 3 индикатор, спустя 1 мс выводим 1 на 4 индикатор и так далее по кругу.

Кнопки опрашиваются после каждого цикла отображения (примерно 40 раз в сек), обработка нажатия снабжена антидребезгом и «защелкой» в виде флага,
что позволяет считать именно нажатия не отвлекаясь на удержание.
*/





#include <avr/io.h> //Тут названия регистров и основные макросы
#include <util/delay.h> //Библиотека обработки задержек
#include <avr/interrupt.h> //Библиотека прерываний
#define digit_display_time 1 //Частота обновления индикации

//частота тактирования микроконтроллера
//#define F_CPU 1600000

//Обьявляем переменные
volatile unsigned char ten_milliseconds, seconds, ten_seconds, minutes, ten_minutes, hours, ten_hours;
volatile unsigned char button_set_minutes, button_set_hours;

//обработчик прерывания таймера Т0
ISR(TIMER0_OVF_vect)
{
ten_milliseconds++;
TCNT0=96; // выставляем начальное значение таймера/счетчика T0
if (ten_milliseconds >= 100 )
{
ten_milliseconds = 0;
seconds++;
};

if (seconds >= 10)
{
seconds = 0;
ten_seconds++;
};

if (ten_seconds >= 6)
{
ten_seconds = 0;
minutes++;
};

if (minutes >= 10)
{
minutes = 0;
ten_minutes++;
};

if (ten_minutes >= 6)
{
ten_minutes = 0;
hours++;
};

if (hours >= 10)
{
hours = 0;
ten_hours++;
};

if (ten_hours >= 2 && hours == 4)
{
ten_hours = 0;
hours = 0;
};
}


int main(void)
{
// 0 1 2 3 4 5 6 7 8 9
const unsigned char digits[10]={0x3F,0xC,0x5B,0x5E,0x6C,0x76,0x77,0x1C,0x7F,0x7E}; //массив для генерации цифр. Какой элемент массива будет отправлен в порт, такая цифра и загорится.

DDRB = 0xff; // все выводы порта B сконфигурировать как выходы
PORTB = 0x00; // установить "0" на всех линиях порта B

DDRD = (1<<6)|(1<<5)(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0); //конфигурация порта D
PORTD = 0x78; // устанавливаем уровни на линиях порта B


TCCR0A = (1<<CS02)|(0<<CS01)|(0<<CS00); // настраиваем делитель на 256
TIMSK |= (1<<TOIE1); // разрешаем прерывание по переполнению таймера
TCNT0=96; // выставляем начальное значение таймера/счетчика T0
sei(); // Разрешение прерываний

while (1)
{
PORTD |=1<<5; //включаем первый индикатор
PORTB = digits[ten_hours]; //выводим на него десятки часов
_delay_ms(digit_display_time); //ждем, время индикации одного разряда задается в заголовке программы
PORTD &=~(1<<5); //выключаем первый индикатор и переходим дальше и так в цикле для каждого из 4 разрядов
PORTD |=1<<4;
PORTB = digits[hours];
if (ten_milliseconds >= 50) PORTB &=~(1<<4); else PORTB|=1<<4; //моргание точки
_delay_ms(digit_display_time);
PORTD &=~(1<<4);
PORTD |=1<<3;
PORTB = digits[ten_minutes];
_delay_ms(digit_display_time);
PORTD &=~(1<<3);
PORTD |=1<<6;
PORTB = digits[minutes];
_delay_ms(digit_display_time);
PORTD &=~(1<<6);

//а вот теперь проверим кнопочки в стиле часов Электроника 13

if ((PIND & 1<<0) == 0 && button_set_hours == 0) //Если нажата кнопка 1
{
_delay_ms(1);
hours++;
button_set_hours = 1;
};

if ((PIND & 1<<0) == 1) button_set_hours=0; //Если отпущена то сбрасываем флаг



if ((PIND & 1<<1) == 0 && button_set_minutes == 0) //Если нажата кнопка 2
{
_delay_ms(1);
minutes++;
button_set_minutes = 1;
};

if (PIND & 1<<1) button_set_minutes=0;




};
}



main.c:1: error: stray '\357' in program
main.c:1: error: stray '\273' in program
main.c:1: error: stray '\277' in program
main.c: In function 'main':
main.c:100: error: called object '32' is not a function

Re: Часики на attiny2313, нужна помощь

Добавлено: Вт апр 09, 2013 11:50:17
aligator33
Все программа компилируется (наставил символов кирилицы)
Но все равно не работает так как задумано.
Помогите пожалуйста.....

Re: Часики на attiny2313, нужна помощь

Добавлено: Ср апр 10, 2013 09:28:56
shads
Прошивка была ну ооочень кривоватая, многое поправил, вроде работает....
Спойлер

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

/*
1. С помощью прерывания получаем точные временные интервалы - например 1сек
2. Считаем эти интервалы. из них слаживаем минуты, часы.
3. Загружаем значение текущего времени в некий буфер, откуда оно будет выводится на индикаторы с помощью динамической индикации.
4. кнопки для управления часами - это уже по вкусу.

Микроконтроллер тактируется кварцем с частотой 16 МГц.
В качестве счетчика времени, внутри микроконтроллера запущен 16 битный таймер с предделителем 256 (т.е. частота отсчетов таймера 62500 Гц),
настроенный на создание прерывания по достижении счетчиком значения 625. Таким образом, мы получаем прерывания ровно 100 раз в секунду 
(тоесть получаем временный интервал 10 милисекунд).
Значение времени хранится в глобальных переменных, и каждое прерывание мы увеличиваем значение миллисекунд на 1.
Если количество миллисекунд достигает 100, то мы увеличиваем на 1 значение секунд, а значением миллисекунд сбрасываем.
И так далее вплоть до десятков часов, которые сбрасываются по достижении 24 без увеличения следующего разряда.
Часы предельно простые, поэтому не считают ни дату, ни перевод на зимнее/летнее время и т.д.
Данные функции можно реализовать программно, без изменения аппаратной части, поэтому остаются для реализации желающим.
Разобравшись с таймером и прерываниями мы получаем значение текущего времени в глобальных переменных. Теперь займемся выводом этих значений.
Так как количество портов микроконтроллера ограничено, то будем эксплуатировать инерционность зрения.
Катоды всех 4 индикаторов соединены параллельно, а аноды коммутируются отдельно, что позволяет нам в любой момент
времени вывести любую цифру на любой индикатор. Быстро переключая порт B, к которому подключены катоды и быстро переключая
аноды мы можем создать видимость, что у нас работают все 4 цифры, хотя единовременно работает только одна. Иными словами,
если текущее время 12:51, то мы выводим цифру 1 на первый индикатор, спустя малый промежуток времени (у меня 1 мс)
выводим цифру 2 на второй индикатор, спустя 1 мс выводим 5 на 3 индикатор, спустя 1 мс выводим 1 на 4 индикатор и так далее по кругу.
Кнопки опрашиваются после каждого цикла отображения (примерно 40 раз в сек), обработка нажатия снабжена антидребезгом и «защелкой» в виде флага,
что позволяет считать именно нажатия не отвлекаясь на удержание.
*/


#define F_CPU 16000000//частота тактирования микроконтроллера
#include <avr/io.h> //Тут названия регистров и основные макросы
#include <util/delay.h> //Библиотека обработки задержек
#include <avr/interrupt.h> //Библиотека прерываний


#define digit_display_time 1 //Частота обновления индикации


//Обьявляем переменные
volatile unsigned char 	ten_milliseconds, seconds, ten_seconds, minutes, ten_minutes, hours, ten_hours;
volatile unsigned char 	button_set_minutes, button_set_hours;  
const unsigned char digits[10]={0x3F,0x0C,0x5B,0x5E,0x6C,0x76,0x77,0x1C,0x7F,0x7E}; //массив для генерации цифр.
  

int main(void)
{
	DDRB  = 0xff;   // все выводы порта B сконфигурировать как выходы
	PORTB = 0x00;  // установить "0" на всех линиях порта B
	DDRD  = 0x78; //конфигурация порта D
	PORTD = 0x7b; // устанавливаем уровни  на линиях порта B

	OCR1A = 625;								//число сравнения для таймера T1 для формирования прерываний с частотой 100Гц
	TIMSK = (1<<OCIE1A);	 					//разрешить прерывание по совпадению T1
	TCCR1A =(0<<WGM11)| (0<<WGM10);				//режим таймера T1 = CTC сброс при совпадении
	TCCR1B =(0<<WGM13)| (1<<WGM12)|				//режим таймера T1 = CTC сброс при совпадении
			(1<<CS12)| (0<<CS11)| (0<<CS10);	//предделитель на 256	

	sei(); // Разрешение прерываний
	while (1)
	{
		PORTD |=1<<5; //включаем первый индикатор
		PORTB = digits[ten_hours]; //выводим на него десятки часов
		_delay_ms(digit_display_time); //ждем, время индикации одного разряда задается в заголовке программы
		PORTD &=~(1<<5); //выключаем первый индикатор и переходим дальше и так в цикле для каждого из 4 разрядов
	
		PORTD |=1<<4;
		PORTB = digits[hours];
		if (ten_milliseconds >= 50) PORTB &= ~(1<<7); 
		else 						PORTB |= 1<<7; //моргание точки	
		_delay_ms(digit_display_time);
		PORTD &=~(1<<4);
	
		PORTD |=1<<3;
		PORTB = digits[ten_minutes];
		_delay_ms(digit_display_time);
		PORTD &=~(1<<3);
		
		PORTD |=1<<6;
		PORTB = digits[minutes];
		_delay_ms(digit_display_time);
		PORTD &=~(1<<6);


		//а вот теперь проверим кнопочки в стиле часов Электроника 13
		if ((PIND & 1<<0) == 0 && button_set_hours == 0){ //Если нажата кнопка 1
			_delay_ms(1);
			if ((++hours == 4)&&(ten_hours == 2)){
				hours = 0;
				ten_hours = 0;
			}
			if (hours == 10){
				hours = 0;
				++ten_hours;		
			}
				
			button_set_hours = 1;
		}
		if ((PIND & 1<<0) == 1) 
			button_set_hours=0; //Если отпущена то сбрасываем флаг


		if ((PIND & 1<<1) == 0 && button_set_minutes == 0){ //Если нажата кнопка 2
			_delay_ms(1);
			if (++minutes == 10){
				minutes = 0;
				if (++ten_minutes == 6)
					ten_minutes = 0;
				seconds = 0;	
			}
			button_set_minutes = 1;
		}
		if (PIND & 1<<1) 
			button_set_minutes=0;
	}
}


//обработчик прерывания таймера Т0
ISR (TIMER1_COMPA_vect)
{
	if (++ten_milliseconds >= 100 ){
		ten_milliseconds = 0;
		seconds++;
	}
	if (seconds >= 10){
		seconds = 0;
		ten_seconds++;
	}
	if (ten_seconds >= 6){
		ten_seconds = 0;
		minutes++;
	}
	if (minutes >= 10){
		minutes = 0;
		ten_minutes++;
	}
	if (ten_minutes >= 6){
		ten_minutes = 0;
		hours++;
	}
	if (hours >= 10){
		hours = 0;
		ten_hours++;
	}
	if (ten_hours >= 2 && hours == 4){
		ten_hours = 0;
		hours = 0;
	}
}
ЗЫ Кстати, я умудрился еще проще часики сделать - с одной кнопкой.....
Правда там DS1307 еще стоит.... зато время не сбивается при пропадании напруги.....
Т.е. можно сказать - простые..... НО, уже и не игрушка.....
http://asis-kbr.ru/forum/viewtopic.php?f=11&t=159

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт апр 12, 2013 11:19:49
aligator33
Спасибо, откомпилировал залил - работает , только индикаторы мерцают (задержка на обновление индикаторов и так стоит 1 милисекунда)

???

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт апр 12, 2013 14:18:31
shads
Может вы не переключили фузы на внешний кварц 16000000, и контроллер работает на внутреннем 1000000 ???
Частота тогда в 16 раз ниже будет.....

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт апр 12, 2013 16:09:12
aligator33
ТОчно фьюзы не переключал, я их пока боюсь. Подскажите какие выставить чтобы не запороть контроллер :shock:

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт апр 12, 2013 16:27:21
pyzhman
Сделайте все CKSEL незапрограммированными. Т.е.
CKSEL0= 1
CKSEL1= 1
CKSEL2= 1
CKSEL3= 1
Ну и до кучи
SUT0= 1
SUT1= 1

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт апр 12, 2013 20:42:28
shads
aligator33 писал(а):ТОчно фьюзы не переключал, я их пока боюсь. Подскажите какие выставить чтобы не запороть контроллер :shock:
http://avr.roboforum.ru/calc.html?part=ATtiny2313
Вот калькуляторчик, можно наглядно конфигурировать.
Смотри на 3 байта слева, это и есть то что надо прошить в контроллер.
Тока надо помнить что установленная галочка в таблице, соответствует сброшенному биту в фузах.

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт ноя 01, 2013 21:17:57
aligator33
Извините за долгое молчание.

Вот в SinaProg выставидл фузы и похоже убил тиньку и при попытке поиска контроллера пишет Progaming failed. Можно что-то сделать? :shock:
Фузы ставил следующие:
low 7F
High DF
Extended FF

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт ноя 01, 2013 21:32:31
Martin76
А кварц то стоит?

Re: Часики на attiny2313, нужна помощь

Добавлено: Пт ноя 01, 2013 21:38:40
aligator33
да на 16 MHz

Re: Часики на attiny2313, нужна помощь

Добавлено: Вс ноя 10, 2013 19:37:44
Xatrix
Выкладываю свои часы с первой моей прогой для 2313... :)
как можно сделать, чтобы точка моргала только во втором сегменте и включение/выключение точки за 1 секунду?
где можно сделать опрос кнопок? чтобы за одно нажатие не инкрементировало по 5-10 раз... если делать с задержкой, по это влияет на отображение, т.к. опрос в основном цикле...
Бипер будет ЗП-1. Может перед ним поставить транзистор, чтобы не перегружать порт?