реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Помогите с кодом новичку, пожалуйста
Alex Nebrituy
сообщение Dec 13 2012, 19:40
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 13-12-12
Пользователь №: 74 841



Я студент 5-го курса. Надо было бы начать заниматся подобным раньше. Сейчас уже время поджимает и препод тоже. Нужно разобрать код, который я практически не понимаю. Там есть некие обьяснения предыдущего автора, но их маловато. А препод в программировании не шарит.
В общем код написан для секундомера для лабораторной установки в универе.

Заранее извиняюсь, что такой большой код кинул на страницу, но файл не загрузило

CODE
/************ ПРИМЕЧАНИЕ К ПРОГРАММЕ *****************
**
** Последнее изменение: 12.02.2010
** Микроконтроллер: ATtiny2313
** Частота: Кварц внешний, 4.0 МГц
**
*******************************************************/

#include "common.h" ;присоединение файла common.h
#include "cntr.h" ;присоединение файла cntr.h
#include "iotiny2313.h" ;присоединение файла iotiny2313.h файл описания для микроконтроллера

#define DOUT PORTB_Bit6 // определение переменных PB6 (PORT - сконфигурировать порт на вывод)
#define SCK PORTB_Bit5 // для портов PB5 вывод
#define STR PORTB_Bit7 // вывода информации PB7 вывод
#define OE PORTB_Bit4 // на индикаторы PB4 вывод

#define REL1 PORTB_Bit2 // опредление переменных для магнита №1 PB2 вывод
#define REL2 PORTB_Bit3 // -||- PB3 вывод

#define IN1 PINB_Bit0 // опредление переменной для запуска счетчика PB0 (PIN-сконфигурировать порт на ввод)
#define IN2 PINB_Bit1 // опредление переменной для стопа счетчика PB1 ввод

#define BUZER PORTD_Bit1 // опредление переменной для пищалки PD1 вывод

#define RELAY PIND_Bit2 // опредление переменной для кнопки ЭМ PD2 ввод
#define START PIND_Bit3 // опредление переменной для кнопки пуск PD3 ввод
#define STOP PIND_Bit4 // опредление переменной для кнопки стоп PD4 ввод
#define RESET PIND_Bit5 // опредление переменной для кнопки сброс PD5 ввод

#define Relay_Start_Time 6000 // 60 сек (6000 * 10 мс)
#define Relay_Pause_Time 20 // 0.2 сек (20 * 0.01 с)
#define Relay_Stop_Time 200 // 2 сек (200 * 0.01 с)
#define Buzer_Time 60 // 60 мс (60 * 1 мс)
#define Relay_Poll_Time 200 // 2 сек (300 * 0.01 с)

__no_init __regvar struct // объявление бит
{
unsigned char dynamic : 1; // флаг динамической индикации
unsigned char timer : 1; // unsigned char 0...255 (только полож. числа)
unsigned char start : 1; //
unsigned char parity : 1;
unsigned char reseted : 1;
unsigned char relay : 1;
unsigned char result : 1;
}@15;

__no_init __regvar struct // объявление бит
{
unsigned char relay_keep : 1;
unsigned char relay_repeat : 1;
}@14;

union
{
struct
{
unsigned char millisecond[5];
unsigned char period[2];
};
unsigned char digit[7];
};

__no_init __regvar unsigned char dynamic_cntr@13;
__no_init __regvar unsigned char relay_pause_tmr@12;
__no_init __regvar unsigned char timer_cntr@11;
__no_init __regvar unsigned char buzer_tmr@10;

unsigned char segment;
unsigned char segment_register;
unsigned char anode_register;
unsigned int relay_tmr;
unsigned int relay_poll_cntr;

__flash unsigned char anode_code[] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF};
__flash unsigned char segment_code[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

void main(void) // основная программа (главная функция)
{
_WDR();
WDTCR = (1 << WDCE) | (1 << WDE); // начать изменения WDT
WDTCR = (1 << WDE); // программирование WDT на 16ms
DDRD = 0x02;
PORTD = 0xFD;
DDRB = 0xFC;
PORTB = 0x03;

dynamic_cntr = 0;
relay_pause_tmr = 0;
timer_cntr = 0;
buzer_tmr = 0;
dynamic = timer = start = parity = reseted = result = relay = 0;
#ifdef CNTR_01 // если счетчик СЭ-01
relay_repeat = 0;
#else
relay_repeat = 1;
#endif
relay_keep = 0;

OCR1A = 499; // период таймера 1 мс
TCCR1A = 0x00;
TCCR1B = (1 << WGM12) | (1 << CS11); // очищать таймер 1 по переполнению, делитель на 8
TIMSK = (1 << OCIE1A); // разрешить прерывание по сравнению таймера 1
wait_pcint0();
GIMSK = (1 << PCIE);
buzer_on();
_SEI();
while(1)
{
if(dynamic)
{
dynamic = 0;
if(segment == 0)
{
#ifdef CNTR_02 // если счетчик СЭ-02
segment = 5;
#else
segment = 7;
#endif
}
segment--;

segment_register = segment_code[digit[segment]];
#ifdef CNTR_02 // если счетчик СЭ-02
if(segment == 1)
segment_register &= 0x7F;
#else
if(segment == 2)
segment_register &= 0x7F;
#endif
anode_register = anode_code[segment];
write_register(((signed int)anode_register << 8) | segment_register);
}
}
}

#pragma vector=PCIN1_vect
__interrupt void PCIN1_interrupt(void)
{
#ifdef CNTR_02
if(start) // если запущен счетчик
{
if(!timer)
{
timer = 1;
buzer_on(); // пищит пищалка
wait_pcint1();
}
else
{
timer = 0; // остановить миллисекундомер
start = 0;
buzer_on(); // пищит пищалка
wait_pcint0();
if(relay_repeat)
relay_pause_tmr = 20; // запустить паузу на 200 ms и повторное включение реле
relay_repeat = 1;
}
}
#else // иначе счетчик СЭ-01
if(IN1) // если положительный фронт
{
parity = ~parity;
if(timer)
{
if(!parity)
{
inc_period();
buzer_on(); // пищит пищалка
}
}
if(start)
{
if(!timer)
{
parity = 0;
timer = 1;
buzer_on(); // пищит пищалка
}
}
else
{
if(timer)
{
if(!parity)
{
timer = 0;
result = 1;
buzer_on(); // пищит пищалка
if(relay_repeat)
{
relay_pause_tmr = Relay_Pause_Time; // запустить паузу и потом включить реле
//relay_repeat = 0;
}
}
}
}
}
#endif
}

#pragma vector=TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_interrupt(void)
{
if(++dynamic_cntr > 2)
{
dynamic_cntr = 0;
dynamic = 1;
}

if(buzer_tmr > 0)
if(!--buzer_tmr)
BUZER = 0;

#ifdef CNTR_02
if(timer) // если запущен таймер
inc_tmr();
#endif

if(++timer_cntr > 9) // период 10 мс
{
timer_cntr = 0;
_WDR();

#ifdef CNTR_01 // если счетчик СЭ-01
if(timer) // если запущен таймер
inc_tmr();
#endif

if(relay_tmr > 0)
{
if(!--relay_tmr)
{
relay = 0;
REL1 = 0;
REL2 = 0; // выключить реле 1 и 2
}
}

if(relay_pause_tmr > 0)
{
if(!--relay_pause_tmr)
{
relay_on(); // включить реле для торможения
relay_tmr = Relay_Stop_Time;
}
}

if(!RELAY) // нажата кнопка магнит
{
if(++relay_poll_cntr > Relay_Poll_Time)
{
if(!relay_keep)
{
relay_keep = 1;
#ifdef CNTR_01
relay_repeat = 1;
#else
relay_repeat = 0;
#endif
buzer_on(); // пищит пищалка
}
}
if(!result)
{
if(!relay)
{
if(!start)
{
buzer_on(); // пищит пищалка
relay_on();
relay_tmr = Relay_Start_Time; // запустить таймер
relay = 1;
reseted = 0;
}
}
}
}
else
{
relay_poll_cntr = 0;
relay_keep = 0;

if(!START) // нажата кнопка старт
{
if(!result)
{
if(!start)
{
start = 1;
reseted = 0;
#ifdef CNTR_01
timer = 0;
null_cntr();
#endif
buzer_on(); // пищит пищалка
relay_off();
relay = 0;
wait_pcint0(); // ожидание прерывания со входа 0
}
}
}
else if(!STOP) // нажата кнопка стоп
{
if(start)
{
start = 0;
buzer_on(); // пищит пищалка
}
}
else if(!RESET) // нажата кнопка сброс
{
if(!reseted)
{
start = 0;
reseted = 1;
result = 0;
timer = 0;
relay_off();
relay = 0;
#ifdef CNTR_01
relay_repeat = 0;
#else
relay_repeat = 1;
#endif
buzer_on(); // пищит пищалка
null_cntr();
wait_pcint0(); // ожидание прерывания со входа 0
}
}
}
}
}

void inc_tmr(void)
{
if(++millisecond[4] > 9)
{
millisecond[4] = 0;
if(++millisecond[3] > 9)
{
millisecond[3] = 0;
if(++millisecond[2] > 9)
{
millisecond[2] = 0;
if(++millisecond[1] > 9)
{
millisecond[1] = 0;
if(++millisecond[0] > 9)
millisecond[0] = 0;
}
}
}
}
}

void inc_period(void)
{
if(++period[1] > 9)
{
period[1] = 0;
if(++period[0] > 9)
period[0] = 0;
}
}

void wait_pcint0(void)
{
PCMSK = (1 << PCINT0); // ожидание прерывания со входа 0
EIFR = (1 << PCIF); // сбросить прерывание от фотодатчика
}

void wait_pcint1(void)
{
PCMSK = (1 << PCINT1); // ожидание прерывания со входа 2
EIFR = (1 << PCIF); // сбросить прерывание от фотодатчика
}

void null_cntr(void)
{
period[0] = 0;
period[1] = 0;
millisecond[0] = 0;
millisecond[1] = 0;
millisecond[2] = 0;
millisecond[3] = 0;
millisecond[4] = 0;
}

void relay_off(void) // программа для выключения реле (магнита)
{
REL1 = 0; // выключить реле 1 (магнита)
REL2 = 0; // выключить реле 2 (магнита)
relay_tmr = 0; // обнуление соответствующего таймера
}

void relay_on(void) // программа для включения реле (магнита)
{
REL1 = 1; // включить реле 1
#ifdef CNTR_02 // если счетчик СЭ-02
REL2 = 1; // включить реле 2
#endif
}

void buzer_on(void) // программа для включения пищалки
{
BUZER = 1;
buzer_tmr = Buzer_Time; // включит бузер
}

void write_register(signed int data) // программа для вывода информации на индикаторы
{
unsigned char bit;
for(bit = 0; bit < 16; bit++)
{
SCK = 0;
if(BIT(data, 15))
DOUT = 1;
else
DOUT = 0;
data = data << 1;
SCK = 1;
}
SCK = 0;
DOUT = 0;
STR = 1;
__delay_cycles(4);
STR = 0; // стробирование регистра
OE = 1; // разрешить регистр
}

Go to the top of the page
 
+Quote Post
=AK=
сообщение Dec 13 2012, 23:36
Сообщение #2


pontificator
******

Группа: Свой
Сообщений: 3 055
Регистрация: 8-02-05
Из: страны Оз
Пользователь №: 2 483



Цитата(Alex Nebrituy @ Dec 14 2012, 06:10) *
Нужно разобрать код, который я практически не понимаю.

Установите себе редактор Дракон и рисуйте блок-диаграммы для всех функций, начиная с main() . Когда все нарисуете, тогда и "разберете", то есть, поймете как работает.
Go to the top of the page
 
+Quote Post
Alex Nebrituy
сообщение Dec 14 2012, 02:28
Сообщение #3





Группа: Новичок
Сообщений: 4
Регистрация: 13-12-12
Пользователь №: 74 841



Цитата(=AK= @ Dec 14 2012, 02:36) *
Установите себе редактор Дракон и рисуйте блок-диаграммы для всех функций, начиная с main() . Когда все нарисуете, тогда и "разберете", то есть, поймете как работает.



Прикольненько... a14.gif Огромное спасибо от нуба. Если есть ещё какие советы очень прошу
Go to the top of the page
 
+Quote Post
Alex Nebrituy
сообщение Dec 14 2012, 13:35
Сообщение #4





Группа: Новичок
Сообщений: 4
Регистрация: 13-12-12
Пользователь №: 74 841



А в драконе можно просто вкинуть код, чтоб он схему составил?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2012, 15:22
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(Alex Nebrituy @ Dec 14 2012, 17:35) *
А в драконе можно просто вкинуть код, чтоб он схему составил?

Да хоть в драконе, хоть где угодно, выкидывание вам ничего не даст. В этой программе задействованы аппаратные ресурсы МК, так что ни один дракон не растолкует вам, как их использовать и программировать. Начать надо с чтения даташита на МК, а не с неизвестно каких программ ...
Go to the top of the page
 
+Quote Post
Alex Nebrituy
сообщение Dec 17 2012, 08:55
Сообщение #6





Группа: Новичок
Сообщений: 4
Регистрация: 13-12-12
Пользователь №: 74 841



Цитата(kovigor @ Dec 14 2012, 18:22) *
Да хоть в драконе, хоть где угодно, выкидывание вам ничего не даст. В этой программе задействованы аппаратные ресурсы МК, так что ни один дракон не растолкует вам, как их использовать и программировать. Начать надо с чтения даташита на МК, а не с неизвестно каких программ ...


Я начал учить по книге Белова "Создаем устройства на микроконтролерах", но такое впечатление, что код отличается от того, что написано в книге.

З.Ы. И ещё, я конечно понимаю, что вопрос глупый, но что такое "даташит"

Сообщение отредактировал Alex Nebrituy - Dec 17 2012, 08:58
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Dec 17 2012, 09:39
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(Alex Nebrituy @ Dec 17 2012, 11:55) *
что такое "даташит"

это вот это:
http://myrobot.ru/downloads/datasheets/tiny2313.pdf
Go to the top of the page
 
+Quote Post
ae_
сообщение Dec 17 2012, 15:51
Сообщение #8


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Желательно всегда скачивать Datasheet только с сайта производителя, во избежание. В данном случае, с сайта Atmel - ATtiny2313
По ссылке MaxiMuz - datasheet не полный (Summary за 2006 г.)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 13:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.03551 секунд с 7
ELECTRONIX ©2004-2016