П3.1.4. Управляющая программа и Proteus-модель прибора МагЦвет

 

При составлении программы в качестве исходного образца была использована программа на Ассемблере «Музыкальная шкатулка» [15, 16]. Программа начинается директивой INCLUDE (строка 1), выполняющей функции присоединения к текущему тексту программы файлов с фрагментами программ-сателитов. В данном случае это файл tn2313def.inc, содержащий описание регистров и параметров микроконтроллера ATtiny2313.

Директива LIST (строка 2) — генерация листинга, повторяющего текст программы с учетом присоединенных фрагментов и отражающего ход трансляции программы с преобразованием ее каждой строки (команды) в машинные коды и с фиксацией ошибок при трансляции. Если такой листинг не требуется, то эту директиву из программы можно исключить. В этом случае можно использовать также директиву NOLIST [17]. При компиляции программы в AVR Studio для генерации ее листинга необходимо установить опцию Creat List File в окне команды Project/Assembler Options.

В строках 3—9 размещаются макроопределения DEF, присваивающие используемым регистрам смысловые имена, упрощаю­щие чтение и понимание текста программы. Так, регистрам R16 и R17 присваиваются имена temp и temp1 (от англ. temporaryвременный) для временного хранения промежуточных данных. В регистрах R18, R19, R20, R21, R22 будут храниться соответственно номер процедуры (count), код текущей частоты (freq) и длительность ее воспроизведения (dfreq), данных задержки (loop) и количества повторов процедуры (countp). Заметим, что при отладке программы в AVR Studio все-таки более удобно пользоваться «официальными» именами регистров (R16, R17 и т. д.).

Псевдооператор CSEG (строка 10) определяет программный сегмент Flash- памяти, в котором будет храниться код программы. Если используется сегмент ОЗУ, то указывается директива DSEG, если EEPROM, — то ESEG.

После объявления каждого такого сегмента он становится текущим. Это означает, что все последующие операторы относятся исключитель­но к объявленному сегменту и что он будет текущим до тех пор, пока не будет объявлен какой-либо другой сегмент.

Команды в программной памяти располагаются одна за другой, и их размещением в памяти занимается транслятор с использованием директивы

ORG, принудительно позиционирующей указатель текущего адреса на заданную ячейку памяти. В данном случае директива ORG (строка 11) имеет чисто декларативное значение, так как в начале программы указатель и так на нуле.

Строки 12—30 занимает таблица переопределения векторов прерываний, содержащая несколько специально зарезервированных адресов в начале программной памяти, предназначенных для обслуживания прерываний.

Таблица векторов прерываний МК ATtiny2313 состоит из 19 адресов (с 0x0000 по 0x0012), каждый из которых является адресом начала процедуры об­работки одного из видов прерываний. Переопределение векторов состоит в том, что в каждую такую ячейку помещается команда безусловного перехода RJMP, передающая управление на адрес в программной памяти, где уже начинается соответ­ствующая процедура обработки прерываний. По адресу 0x0000 (вектор начального сброса МК, строка 12) помешается команда RJMP по метке init, где начинается выполнение программы после системного сброса. Безусловный переход с нулевого адреса позволяет «перескочить» таблицу векторов прерываний и разместить основную программу за ее пределами. Для перестраховки в программу включена также команда CLI общего запрета прерываний (строка 31).

По всем остальным адресам таблицы принято ставить команды-заглушки в виде команды завер­шения процедуры обработки прерывания RETI (строки 13—30), что повышает надежность работы программы: если ненужное прерывание все же возникнет, то оно тут же завершится, не нанося урона.

Строки 32—62 занимает модуль инициализации. Начинается он с установки требуемого значения тактовой частоты. Для встроенного RC-генератора значение частоты при содержимом калибровочного регистра OSCCAL = 0х00 составляет 50% от номинальной, при OSCCAL = 0x3F — 75% и при OSCCAL = 0x7F — 100%. Как показал опыт работы с МК, он поставляется с настройкой OSCCAL = 0х00 — 50%. Как будет показано ниже, нам потребуется максимальное значение тактовой частоты (8 МГц). Поэтому в строках 32, 33 в регистр OSCCAL загружается число 0x7F.

Инициализации стека производится в строке 34, в которой командой LDI в регистр temp (R16) записывается числовая константа RAMEND, описанная в файле tn2313def.inc и равная максимальному адресу ОЗУ (для МК ATtiny2313 — $7F). Затем в строке 35 командой out эта константа переписывается в регистр стека SPL, определяя тем самым его вершину.

Команды инициализации портов ввода/вывода занимают строки 36—43. Записью в регистр DDRB кода 0x0Е (двоичный код 0000 1110) выводы РВ.0, РВ.4—РВ.7 настраиваются на ввод данных (нули в младшем и 4-х старших разрядах), а РВ.(1—3) — на вывод (единицы в 1-ом, 2-ом и 3-ем разрядах). Записью в регистр PORTВ кода 0xF1 (двоичный 1111 0001) к выводам РВ.(0, 4—7) подключаются внутренние резисторы нагрузки (подтяжки). Все семь разрядов порта PD настраиваются на ввод путем записи в его регистр управления DDRD нулевого кода, а в регистр PORTD — кода 0x7F для подключения внутренних ре­зисторов подтяжки, что соответствует уровню логической единицы на его семи выводах при разомкнутых ключах S1—S7 (см. рис. П3.1.12).

Строки 44 и 45 включены в программу для перестраховки. Дело в том, что встроенный аналоговый компаратор МК после системного сброса остается включенным. Для уменьшения энергопотребления и исключения всяких случайностей он отключается  путем записи в его регистр управления ACSR константы 0x80.

Настройка таймера Т0 производится в строках 46—51. При этом загрузкой кода 0х0В в регистр управления TCCR0B записывается код 0x0В (строки 46, 47), двоичным эквивалентом которого является код 0х00001011. Четвертый (с именем WGM12 = 0) и третий (с именем WGM11 = 1) биты этого кода переводят таймер в режим СТС (сброс по переполнению), а второй, первый и нулевой (с именами CS12 = 0, CS11 = 1, CS10 = 1 соответственно) устанавливают коэффициент предварительного деления частоты равным 64. В строках 48, 49 в регистр совпадения OCR0A записывается значение коэффициента деления КД0 = 0х3D (десятичное 61), обеспечивающего заданное значение частоты сигнала на выходе 14, к которому подключается выход Т0 командами в строках 50 и 51.

Частота сигнала на выходах микроконтроллера ОС0А (вывод 14) и ОС1А (вывод 15) определяется по формуле [15]:

F = Fo/2×Кд(1 + КД),                                                                           (П3.1.1)

где Fo— тактовая частота (в нашем случае 8 МГц); Кд— коэффициент предделения (в нашем случае 1 или 64); КД — коэффициент пересчета, равный числу, заносимому в регистр совпадения OCR0A или OCR1A и обеспечивающего заданное значение частоты сигнала F. Из (П3.2.1) получаем расчетное значение КД:

КД = Fo/2F×Кд – 1.                                                                              (П3.1.2)

Для таймера Т0 при Кд = 64 коэффициент пересчета КД0 = 8×106/2×103×64 – 1 = 62,5 – 1 = 61,5. Округляем его до значения 61 (шестнадцатеричное 3D), которое и заносится в регистр OCR0A. Заметим, что поскольку таймеры Т0 и Т1 имеют общий предделитель частоты, то на выходе Т0 (вывод 14) не удается получить расчетное значение частоты: оно находится на уровне 1 кГц.

Настройка таймера Т1 производится в строках 52—62. Сначала определяется состояние ключа S8, подключенного к выводу 12 порта РВ.0. Для этого считывается состояние сигналов на его входах (строка 52) и командой логического И маской 0х01 определяется состояние входа РВ.0 (строка 53): если РВ.0 = 1 (ключ S8 разомкнут), то переходом на метку m10 последовательно выполняются строки 59—62. При этом в регистр управления TCCR1B записывается код 0x0В (строки 59, 60), в результате чего таймер переводится в режим СТС с коэффициентом предделения частоты Кд = 64, т. е. при тактовой частоте 8 МГц на входе таймера Т1 будет сигнал с частотой 125 кГц. Заключительным для рассматриваемого случая (РВ.0 = 1) этапом настройки таймера является запись нуля в регистр TCCR1A (строки 52, 53), одной из функций которого является управление подключением/отключением выхода таймера к внешнему выходу ОС1А (вывод 15 МК). Для этого используется шестой бит TCCR1A с именем COM1A0: при COM1A0 = 1 (код 0х40) выход таймера подключается к выводу 15, а при COM1A0 = 0 (код 0х00) — отключается.

Если РВ.0 = 0 (ключ S8 замкнут), то выполняются строки 56—58, в результате чего загрузкой кода 0х09 в регистр TCCR1B таймер Т1 переводится в режим СТС с коэффициентом предделения 1. Этот режим используется в основном для процедуры «Антипаразит», а также при экспериментах с другими процедурами.

Основной цикл программы начинается со сброса  второго бита порта В (вывод 13) (строка 63), чем обеспечивается закрытое состояние транзистора Т2 и прохождение сигналов с выхода 15 МК на исполнительные устройства. Затем производится обнуление регистра count (строка 64), позволяющего определить номер выбранной процедуры одним из ключей S1— S7, подключенных к порту PD (см. рис. 12). Если процедура выбрана (один из ключей замкнут), то соответствующий разряд порта PD будет иметь уровень логического ноля. Для определения этого разряда и, следовательно, номера процедуры командой IN содержимое порта считывается в регистр temp (строка 65) и затем сдвигается на один разряд вправо (строка 66) командой LSR, при выполнении которой 7-ой разряд регистра temp сбрасывается в 0, а нулевой переводит флаг переноса С в 1 или 0. Состояние флага С проверяется командой BRCC.  Если С = 1, то содержимое регистра count увеличивается на 1 (строка 68) и командой CPI проверяется на равенство константе 7, равной числу ключей (и общему числу процедур). Команда CPI выполняется путем вычитания константы из регистра с сохранением его содержимого и изменения флага нуля Z, состояние которого проверяется (строка 70) командой BRNE: если Z ¹ 0, то переходом на метку m2 сканирование продолжается до тех пор, пока Z не станет равным нулю, а это значит, что ни одна процедура не выбрана (ключи S1— S7 разомкнуты). В этом случае управление передается на метку m1 (строка 61) и описанный процесс сканирования ключей S1— S7 будет продолжаться до тех пор, пока один из них не будет замкнут, что обнаруживается при очередном сдвиге (строка 66) и проверке командой BRCC в строке 67. В этом случае управление передается на метку m3 (строка 72) блока вычисления адреса процедуры, а в регистре count фиксируется номер замкнутого ключа (выбранного номера процедуры): для ключа S1, подключенного ко входу PD.0 (вывод 2), этот код будет равен 0х00000000, для ключа S2 (PD.1, вывод 3) — 0х00000010 и так далее.

В блоке вычисления адреса процедуры (строки 72—77) содержимое регистра count переносится  в младшую часть YL (R28) (строка 72) регистровой пары Y (R29, R28).

Теперь сделаем отступление и проведем расчет частот для лечебных процедур. Частота сигнала на выходе ОС1А (вывод 15), как и на выходе ОС0А (вывод 14), определяется по формуле (П3.1.1), из которой определяется коэффициент пересчета КД, равный числу, заносимому в регистр совпадения OCR1A таймера Т1 и обеспечивающего требуемое значение частоты терапевтической сигнала F при выбранном Кд, т. е. КД = Fo/2F×Кд – 1, значения которых приведены в табл. 1.

В левом столбце таблицы перечислены процедуры, коэффициенты предделения Кд1 = 64 и Кд2 = 1, задаваемые ключом S8 или программно, а в строках для каждой из них — набор частот в герцах (верхние числа; для процедуры «Антипаразит» — в килогерцах) и требуемые для них КД (нижние числа) с использованием стандартных правил округления до целого числа. При этом погрешность установки частоты не превышает 5%, что находится в пределах нестабильности встроенного в МК RC-генератора. Кроме того, трудно согласиться с автором работы [14] в том, что терапевтические частоты должны быть точно равны найденным немецкими исследователями, поскольку их значения (в самом грубом приближении) зависят от размеров и массы соответствующих органов, а также от жесткости (упругости) их мускульных мышц. А эти параметры у каждого человека различны и, что касается упругости мышц, то этот параметр зависит от возраста и состояния здоровья пациента. Заметим, в связи с этим, что в работах [12, 13] для биорезонансного электролечения тех же органов используются совершенно другие частоты.

В отличие от приборов серии DETA, в нашем случае лечебные процедуры являются комплексными, объединяющими несколько DETA-процедур для одной и той же болезни. Выглядит это следующим образом:

1. Процедура «Варикоз» состоит из трех частей (в табл. 1 разделены пробельными строками): а) обострение болезни; б) регенерация вен (снимает воспаление, улучшает кровообра­щение в капиллярах и предупреждает тромбозы варикозных узлов, укрепляет и повышает тонус венозной стенки, положительно влияет на работу сердца); в) регенерация мышц (восстанавливает эластичность мышц голеней ног и предотвращает их преждевременное старение).  Процедуру целесообразно сочетать с физическими упражнениями, например, типа «велосипед» лежа на спине, поочередно закрепляя прибор на голенях ног.

2. Процедура «Бронхит» состоит из двух частей: а) лечение ОРЗ; б) снятие бронхоспазма при остром воспалении бронхиального дерева, нормализация кровоснабжения и кислородного обмена.

3. Процедура «Ясные глаза» включает: а) совмещенный режим лечения близорукости и тренировки мышц глаз; б) совмещенный режим регенерации сетчатки глаз, зрительного нерва (снятие воспаления) и лечения глаукомы.

4. Процедура «ЖКТ» включает: а) нормализацию работы желудочно-кишечного тракта (в том числе устранение запоров) и б) нормализацию работы поджелудочной железы.

                                  Табл. П3.1

1. Варикоз

Кд1 = 64

 

2,5     

24999

99,5        

627

 

2,5     

24999

94

664

 

2,5     

24999

99

630

9,4

6648

85  

734

 

9,4

6648

89

701

 

9,4

6648

85

734

10 

6249

84,5      

739

 

10  

6249 

50

1249

 

10 

6249 

84,5

739

33,5      

1865

46,5      

1343

 

28,5

2192

47,5

1315

 

45,5

1373

84

743

46,5       1343

33,5      

1865

 

47,5

1315

28,5

2192

 

84

743

45,5

1373

84,5      

739

10 

6249

 

50

1249

10 

6249

 

84,5

739

10 

6249

85  

734

9,4

6648

 

89

701

9,4

6648

 

85

734

9,4

6648

99,5        

627

2,5     

24999

 

94

664

2,5     

24999

 

99

630

2,5     

24999

2. Бронхит

Кд1 = 64

 

1       

62499

46       1358

 

3,8

16446

9,4

6648

4     

15624

9,45   

6613

 

5,9

11573

7,7

8116  

8       

7812

9,4

6648

 

7,7

8116

5,9

11573   

9,4

6648

8       

7812

 

9,4

6648

3,8

16446 

9,45    6613

4     

15624

 

50

1249

 

 

46       1358

1       

62499

 

55

1135

 

86          726

 

 

 

55

1135

 

 

86          726

 

 

 

50

1249

 

 

3. Ясные глаза

Кд1 = 64

 

 

 

 

 

 

 

 

3,6    

17360

4,9

12754

 

3,6    

17360

72,5      

861

80

780

23

2716

4,9     

12754

3,6

17360

 

4,9     

12754

70

892

94,5

660

70

892

31,5   

1983

19,5

3204

 

19,5

3204

65,5

953

94,5

660

72,5      

861

64    976

45

1388

 

65,5

953

19,5

3204

80

780

98,5

634

72,5      

861

88,5

705

 

70

892

4,9     

12754

72,5      

861

98,5

634

72,5     

861

88,5

705

 

72,5      

861

3,6     17360

20

3124

23

2716

64     

976

45

1388

 

94,5

660

20

3124

12,5

4999

18,5

3377

31,5      

1983

19,5

3204

 

94,5

660

72,5      

861

18,5

3377

12,5

4999

4. ЖКТ

Кд1 = 64

 

 

3,5      

17856

10     

6249

10     

6249

 

3,3

18938

26,5

2357

3,8       

16446

9,4         6648

63,5

983

 

4

15624

26

2403

8,1

7715      

8,6       

7266

64,5

968

 

9,2

6792

9,7

6442             

8,6       

7266

8,1

7715

64,5

968

 

9,7

6442

9,2

6792    

9,4        

6648

3,8       

16446

63,5

983

 

26

2403

4

15624

10     

6249

3,5      

17856

10     

6249

 

26,5

2357

3,3

18938

11,5     

5434

3,8       

16446

4

15624

 

52

1200

11,5

5434

4

15624

3,8       

16446

 

52

1200

     

5. Антипа-разит, кГц

Кд2 = 1

 

28

142

32

124

30

132

30

132

28

142

32

124

32

124

30

132

28

142

28

142

32

124

30

132

30

132

28

142

32

124

32

124

30

132

28

142

28

142

32

124

30

132

30

132

28

142

32

124

6. Сердце-регуляция

Кд1 = 64

 

1,2     

52082

97         

643

 

1,7

36764

99,5

627

3,8       16446

43,5     

1436

 

47,5

1315

52,5

1189

8     

7812

43        1452

 

48,5

1288

50

1249

9,45     

6613

41       

1523

 

49

1275

49,5

1262

41        1523

9,45     

6613

 

49,5

1262

49

1275

43       

1452

8,0      7812

 

50

1249

48,5

1288

43,5      1436

3,8      

16446

 

52,5

1189

47,5

1315

97         

643

1,2     

52082

 

99,5

627

1,7

36764

7. Анти-артрит

Кд1 = 64

 

1,6

39062

88

709

 

1,2

52082

9,7

6442

 

1,2

52082

100

624

 

9,2

6792

78

800

 

1,6

39062

9,6

6509

 

8,1

7715

69

905

9,6

6510

64,6

966

 

2,65

23584

9,4

6648

 

9,2

6792

46

1358

56

1115

64

976

 

6,8

9190

9,2

6792

 

9,6

6509

9,7

6442

64

976

56

1115

 

9,2

6792

6,8

9190

 

9,7

6442

9,6

6509

 

64,6

966

9,6

6509

 

9,4

6648

2,65

23584

 

46

1358

9,2

6792

 

78

800

9,2

6792

 

9,6

6509

1,6

39062

 

69

905

8,1

7715

 

88

709

1,6

39062

 

9,7

6442

1,2

52082

 

100

624

1,2

52082

 

 

5. Процедура «Антипаразит» предназначена для уничтожения паразитов по методике американского врача Хильды Кларк с использованием частоты 30±2 кГц. Такая же частота используется и в приборе ГОМЕОТОН, хотя его разработчики и не признаются, откуда они взяли такую частоту и аналогичную Кларк методику (см. материалы сайта antparazit.ru или gomeoton.ru). В антипаразитарном варианте прибора DETA используется сигналы частотой около 10 кГц.

6. Процедура «Сердцерегуляция» состоит из двух частей: а) нормализация работы сердца и б) нормализация давления (при гипотонии).

7. Процедура «Антиартрит»  состоит из трех программ (артроз 1, артроз 2, артроз 3), которые содержат, в частности, следующие характерные частоты [14]: 1,2 Гц — при болях в суставах; 6,8 Гц — при болях в мышцах вокруг сустава; 9,2 Гц — при нарушении выделительных процессов в почках; 9,4 Гц — при болях в суставах, вызванных подагрой; 9,6 Гц — при артрите или артрозе; 9,7 Гц — при заболеваниях ревматического и ревматоидного характера.

На основании данных табл. П3.1.1 составляем набор коэффициентов деления (КД) и помещаем ее в таблицу с меткой tabf (строка 171), в которой нулевой КД  соответствует паузе. Для удобства кодирования процедур целесообразно эту таблицу выписать отдельно и пронумеровать каждое значении КД (в данном случае от 0 до 79). Из tabf видно, что КД расположены в ней по возрастащей степени за исключением последних двух значений под номерами 78 и 79. Это вызвано тем, что эти КД были пропущены при составлении пронумерованной таблицы, что непринципиально, поскольку при кодировании процедур учитываются их истинные номера, т. е. 78 и 79.

Зададимся двумя значениями длительности воспроизведения частоты и паузы и поместим ее в таблицу коэффициентов задержки (КЗ) с меткой tabd (строка 170). Для кодирования частот и их длительностей выберем однобайтное число, в котором старший бит будет использоваться для кодирования длительности, а остальные семь — для кодирования частот, что позволяет закодировать две длительности и 127 частот.

Адреса начала рассмотренных таблиц соответствуют меткам tabf и tabkd. Для описания данных, содержащихся в этих таблицах, используется оператор .DW (оператор двухбайтных данных). Этот оператор используется также для описания данных таблицы начала процедур tabp (строка 172). Особенностью этой таблицы является то, что она адресует однобайтные данные процедур, используя двухбайтную ячейку памяти программ (в МК используется двухбайтная структура Flash-памяти). Поэтому в таблице tabp метки процедур умножаются на 2, а это означает, что адреса начала процедур размещаются в младшем байте двухбайтной ячейки памяти. Применение удвоенных значений обусловлено также необходимостью перевода адресов из основной адресации двухбайтных ячеек в альтер­нативную, при которой количество ячеек памяти для однобайтных данных удваивается.

Заметим, что при использовании оператора .DB количество записей целесообразно делать четным, поскольку указатель текущего адреса в сегменте cseg работает с основной адресацией и должен перемещаться на целое количество двухбайтных ячеек памяти. В случае нечетного количества записей оператор DB в конце (во второй ячейке) припишет еще нулевой байт. Поэтому при многострочных записях только последняя строка с оператором DB может содержать нечетное число записей.

В качестве примера рассмотрим порядок составления кода для первой частоты процедуры №1 «Варикоз» (строка 154, метка р1:). Предварительно выберем из tabd первую (с номером 0) длительность воспроизведения частоты и паузы (КЗ = 43636), т. е. ее код будет 0х0000 0000, что соответствует десятичному числу 0. Для первой частоты 2,5 Гц коэффициент деления 6400 в tabf будет 73-м от ее начала, т. е. ее код будет 0х0100 1001 и останется таковым для суммарного кода, поскольку код длительности нулевой. Таким образом, код для первой частоты будет равен коду КД.  Если выбрать вторую (с номером 1) длительность (КЗ = 9741 с кодом 0х1000 0000), то суммарный код будет равен 0х1100 1001, что соответствует десятичному 201, т. е. в этом случае в таблице процедуры «Варикоз» вместо первого кода 73 нам пришлось бы поставить код 224. Приведенные в листинге программы коды процедур составлены для первого значения длительности задержки (КЗ = 43636). Каждая процедура заканчивается кодом 255 (0xFF), являющимся признаком ее окончания и, следовательно, его нельзя использовать при кодировании частот, что было учтено при выборе числа частот и длительности их воспроизведения.

Теперь вернемся к блоку вычисления адреса процедуры. После записи содержимого регистра count с кодом процедуры в регистр YL (R28) (строка 72) в регистровую пару Z (R31, R30) записывается адрес таблицы начала процедуры tabp (строки 73, 74). При этом используются специальные функции Ассемблера low и high. Если, например, tabp*2 = 0х040В, то в младшую часть  ZL (R30) будет загружен младший байт адреса low(tabp*2) = 0x0В, а в старшую ZH (R31) — старший high(tabp*2) = 0x04.  После этого вызывается подпрограмма 16-разрядного сложения addw (строка 75), где командой PUSH в стеке сохраняется содержимое регистра YН (R29) (строка 112). Затем в строке 113 путем сдвига влево командой LSL производится умножение содержимого YL на два, а YН обнуляется, после чего командой ADD суммируется содержимое регистров ZL (R30) и  YL (R28), а командой ADC — регистров ZH (R31) и YН (R29) с учетом переноса из ZL (R30) (строки 115, 116). Подпрограмма заканчивается восстановлением командой POP содержимого регистра YН (R29) и возвратом из подпрограммы командой RET (строки 117, 118). После выхода из подпрограммы в регистровой паре Z находится адрес нужного нам элемента таблицы tabр.

Следующие две команды блока вычисления адреса процедуры (строки 76, 77) извлекают адрес начала выбранной процедуры и помещают его в регистровую пару X (R27, R26), где он будет храниться в течение выполнения всей процедуры и ее повторов. Команда LPM чтения байта данных из программной памяти имеет три модификации:

1. LPM — чтение содержимого ячейки программной памяти по адресу в регистровой паре Z и размещение прочитанного в регистре R0.

2. LPM     Rd, Z  аналогично п. 1, но с размещением прочитанного в регистре Rd (в нашем случае в XL (R26)).

3. LPM     Rd, Z+ — аналогично п. 2, но с размещением прочитанного в регистре XН (R27) и автоматическим увеличением содержимого регистровой пары Z на единицу после чтения байта, что представляется весьма удобным средством для последовательного чтения данных из программной памяти (в нашем случае — данных из рассмотренных выше таблиц).

В модуле выполнения процедур первыми двумя командами обнуляются счетчики процедур (R22) и опроса ключей S1—S7 (R18) (строки 78, 79). Затем содержимое счетчика процедур увеличивается на 1 (фиксируется первый сеанс процедуры) и командой CPI сравнивается с константой 0х1Е, определяющей максимальное число повторов одной и той же процедуры. Если флаг Z = 1 (проверяется командой BREQ в строке 82), то в регистровую пару Z записывается адрес начала процедуры (строки 83, 44).

В строках 85—87 производится дополнительная проверка выбранной процедуры. В строке 88 из памяти программ извлекается код первой частоты и ее длительности, который в строке 89 сравнивается с константой 0xFF (255), являющейся признаком конца процедуры, и командой BREQ проверяется состояние флага нулевого результата Z: если Z = 0, то процедура повторяется с переходом на метку m4 и увеличением содержимого счетчика процедур (R22) на 1. Если Z ¹ 0, то в строке 91 из суммарного кода частоты и длительности, который находится в регистре temp (R16) (см. строку 88), производится выделение кода частоты с помощью операции ANDIогическое И) между содержимым регистра temp и константой (маской) 0х7F = 0x01111111. Очевидно, что в этом случае в регистре temp останутся только значащие биты кода частоты, поскольку 7-ой бит (код длительности) при логическом И всегда будет равен нулю. После этой операции содержимое регистра temp переносится в регистр кода частоты freg (R19) (строка 92).

В строке 93 вновь извлекается суммарный код, но с переводом указателя адреса на следующую ячейку памяти, где хранится очередной код частоты. Затем командой циклического сдвига влево ROL, при которой 7-й бит копируется в флаг С, а содержимое флага С за­гружается в 0-й бит регистра,  производится два сдвига (строки 94, 95), в результате чего код длительности оказывается в самом младшем разряде регистра temp (R16), из которого он выделяется с помощью маски 0х01, переносится в регистр кода длительности dfreg (R20) и вызывается подпрограмма pfreq формирования частоты (строки 96—98).

Подпрограмма pfreq начинается с сохранения в стеке содержимого регистров (строки 119—122). Затем код частоты проверяется на его нулевое значение (на паузу) (строки 123, 124). Если пауза, то производится переход к подпрограмме формирования длительности wait по метке nt1, в противном случае — загрузка в YL (R28) кода частоты и определение адреса для ее КД в таблице tabpf (строки 125—128), после чего из памяти по этому адресу, находящемуся в регистровой паре Z (R31,R30), в регистры temp (R16) и temp1 (R17) загружаются младший и старший байты КД (строки 126, 127). Затем эти данные перезагружаются в старшую и младшую часть регистра совпадения OCR1A таймера Т1 (строки 131, 132) и его выход подключается к выводу 15 МК (строки 133, 134) на время, определяемое подпрограммой формирования длительности wait, с последующим отключением таймера (строки 136, 137), сбросом регистра dfreg (R20) и формированием паузы между частотами с помощью той же подпрограммы wait (строки 138, 139). Подпрограмма pfreq заканчивается восстановлением сохраненных в стеке содержимого регистров (строки 140—144) и возвратом на строку 99 с последующим выбором и воспроизведением очередной частоты. Строка 139 в листинге выключена (закомментирована), поскольку нулевой код в регистре dfreg (R20) означает, что пауза между частотами будет определяться первым (нулевым) КЗ, т. е. она будет равна длительности воспроизведения частоты.

Подпрограмма формирования длительности wait начинается с сохранения в стеке содержимого регистров (строки 145—148). Затем код длительности загружается в YL (R28) и определяется адрес КЗ в таблице tabd (строки 149—152), после чего из памяти по этому адресу, находящемуся в регистровой паре Z (R31, R30), в регистры YL (R28) и YH (R29) загружаются младший и старший байты КЗ и обнуляется регистровая пара Z (строки 153—156).

Процесс формирования длительности происходит без участия таймера. В строке 157 в регистр loop (R21) заносится заданное число 255, а затем командой DEC в цикле оно уменьшается до тех пор, пока регистр loop не обнулится (проверяется командой BRNE в строке 159), т. е. на вход регистровой пары Z (R31, R30) поступают импульсы с частотой около 32 кГц (8000/255). По мере заполнения Z (команда ADIW в строке 160, выполняющая роль команды инкремента для регистровой пары) в каждом проходе цикла командой CP сравнивается содержимое младшего и старшего байта регистров Z и Н, в котором хранится значение КЗ (в данном случае 43636 или 9741). Работа подпрограммы заканчивается при заполнении регистровой пары Z до значения КЗ (строки 161—164) с последующим стандартным завершением (строки 165—169).

После выполнения подпрограмм wait и pfreq управление передается на строку 99 и по команде безусловного перехода rjmp — на метку m5 для формирования очередной частоты. В конце процедуры (строки 89, 90) управление передается на метку m4 и процедура повторяется. Когда количество процедур, фиксируемое в регистре countp, достигнет заданного значения (в данном случае 30-ти), управление передается на метку clark (строка 100), в которой считывается содержимое порта В. Если выполняется процедура «Антипаразит» (ключ S8 замкнут), то РВ.0 = 0 (проверяется в строках 101 и 102) и выполняются строки 104—107, в результате чего таймер переключается в режим СТС с предделением 64 (строки 104, 105), выход порта РВ.1 (вывод 13) переводится в 1 (строка 106), после чего транзистор Т2 открывается, шунтируя базу Т1 и прекращая тем самым подачу импульсов на пациента. При этом внеочередной повтор процедуры (переход в строке 107) выполняется с пониженной в 64 раза частотой, что является аудио признаком окончания процедуры (контролируется пьезоизлучателем В). Если выполняется любая другая процедура (ключ S8 разомкнут и РВ.0 = 1),  то управление передается на метку m6 (строка 108), где таймер Т1 перенастраивается на единичный коэффициент предделения тактовой частоты и текущая процедура повторяется, но с выходными частотами, в 64 раза выше лечебных, что и является аудио признаком окончания процедуры. Одновременно выход порта РВ.1 переводится в 1 (строка 110), транзистор Т2 открывается, шунтируя базу Т1 и прекращая тем самым подачу импульсов на пациента.

Теперь приступим к расчету продолжительности процедур. Начнем с DETA-процедур, содержащих в среднем около 40 частот. Если принять длительность воспроизведения каждой частоты 2 с, то на один повтор (сеанс) процедуры потребуется 80 с, т. е. при усредненной  длительности процедуры в 40 мин (2400 с) количество повторов составит 30 или 0х1Е (это число задано в строке 81). Поскольку на вход формирователя длительности (строки 160—164), как отмечалось ранее, подается сигнал частотой 32000 Гц, то без учета длительности других команд и при задержке 2 с требуемое значение КЗ составляет 2×32000 = 64000. Проверка длительности процедур по секундомеру показала, что она превышает расчетное значение почти в 1,5 раза. Поэтому действительное значение первого КЗ было уменьшено до 43636. Для процедуры «Антипаразит» расчетное значение длительности оказалось в три раза больше требуемого (7 мин). Поэтому запланированное количество частот (в строке 177) пришлось уменьшить в два раза.

Заметим, что, согласно рекомендациям Кларк, после первого приема процедуры «Антипаразит» следует перерыв на 20 мин с дальнейшим повторением по схеме 7-20-7-20-7. Трехкратное включение с перерывами является обязательным; процедура выполняется минимум 2-3 раза в день через 2-4 часа. В случае хронических инфекционных и паразитарных заболеваний, а также при наличии или подозрении на присутствие скрытых инфекций процедура «Антипаразит» проводится ежедневно по схеме 7-20-7-20-7. Длительность курса лечения зависит от тяжести и давности заболевания и составляет от 7 до 14 дней с ежедневным проведением процедуры по этой же схеме. Рекомендуется повторять курс каждые полгода. Более подробные рекомендации по применению методики Хильды Кларк можно найти в статье «Паразиты. Диагностика и терапия. Правда и заблуждения», размещенной на сайте www.activita.ru.

 

Листинг программы

 

;###############################

;##                                                               ##

;##          Программа лечебных частот           ##

;##                                                               ##

;###############################

 

;------------------------- Псевдокоманды управления

 

1. .include "tn2313def.inc"      ; Присоединяем файл описаний

2. .list                                   ; Включение листинга

 

3. .def   temp = R16               ; Вспомогательный регистр

4. .def   temp1 = R17             ; Второй вспомогат. регистр

5. .def   count = R18              ; Номер процедуры

6. .def   freq = R19                ; Регистр текущей частоты

7. .def   dfreq = R20              ; Регистр ее длительности

8. .def   loop = R21                ; Регистр формиров. задержки

9. .def   countp = R22            ; Счетчик повтора процедуры

 

;------------------------- Начало программного кода

 

10.       .cseg                ; Выбор сегмента программного кода

11.       .org  0              ; Установка текущего адреса на ноль

 

12. start:       rjmp init    ; Переход на начало программы

13.               reti           ; Внешнее прерывание 0

14.               reti           ; Внешнее прерывание 1

15.               reti           ; Прерывание по захвату таймера T1

16.               reti           ; Прерывание по совпадению T1

17.               reti           ; Прерывание по переполнению T1

18.               reti           ; Прерывание по переполнению T0

19.               reti           ; UART - прием завершен

20.               reti           ; UART - регистр данных пуст

21.               reti           ; UART - передача завершена

22.               reti           ; Прерывание от компаратора

23.               reti           ; Измен. состояния любого вывода

24.               reti           ; Таймер/счетчик 1. Совпадение B

25.               reti           ; Таймер/счетчик 0. Совпадение B

26.               reti           ; Таймер/счетчик 0. Совпадение A

27.               reti           ; USI - стартовая готовность

28.               reti           ; USI - переполнение

29.               reti           ; EEPROM - готовность

30.               reti           ; Переполнение охранного таймера

31.                      cli             ; Общий запрет прерываний

 

;***********************************

;*             Модуль инициализации       *

;***********************************

init:

 

32. ldi   temp, 0x7F          ; Настройка внутреннего RC-генератора

33. out  OSCCAL, temp     ; на максимальную частоту (8 МГц)

 

;-------------------- Инициализация стека

 

34. ldi   temp, RAMEND  ; Выбор адреса вершины стека

35. out  SPL, temp         ; Запись его в регистр стека

 

;-------------------- Инициализация портов В

 

36. ldi     temp, 0x0E                  ;настройка РВ.(0,4-7) на

37. out   DDRB, temp                 ;вводВ.(1-3) на вывод

38. ldi     temp, 0xF1                  ;подключение резисторов

39. out   PORTB, temp                ;нагрузки к РВ.(0,4-7)

 

40.  ldi temp, 0x7F                      ; Инициализация порта PD

41. out  PORTD, temp                 ; на ввод с подключением

42. ldi   temp, 0x00                     ; резисторов нагрузки

43. out  DDRD, temp                   ; ко всем выводам PD

 

;--------------------- Инициализация (выкл.) компаратора

 

44. ldi   temp, 0x80

45. out  ACSR, temp

 

;--------------------- Инициализация таймера T0

                                             

46. ldi  temp, 0x0B         ; Включаем режим CTC

47. out TCCR0B, temp    ; с предделением 64

48. ldi  temp, 0x3D         ; Загружаем КД0=61 для 

49. out  OCR0A, temp     ; частоты 1 кГц

50. ldi temp, 0x40          ; Подключаем выход таймера 

51. out  TCCR0A, temp    ;  к выводу 14 микроконтроллера (МК)

 

;--------------------- Инициализация таймера T1

 

52.    in temp, PINB                ;читаем содержимое порта В

53.    andi temp, 0x01             ;выделяем код нулевого бита

54.    cpi temp, 0x01               ;если 1 (ключ S8 разомкнут)

55.    breq m10                      ;переход на m10

56.   ldi temp, 0x09                 ; иначе включаем режим CTC

57.   out TCCR1B, temp           ; с предделением 1

58.   rjmp      m1                    ; и перескакиваем через m10

 

59. m10: ldi  temp, 0x0В          ; Включаем режим CTC

60.         out TCCR1B, temp      ; с предделением 64

 

61. m1:  ldi temp, 0x00            ; Отключаем выход таймера от

62.        out  TCCR1A, temp      ;  вывода 15 МК 

 

;**************************************

;*           Начало основной программы       *

;**************************************

main:

 

63. cbi PORTB, 1               ;сброс второго бита порта В (вывод 13)

                                       ;(для процедуры «Антипаразит»)

 

;--------------------- Вычисление номера процедуры

 

64.       clr     count               ; Обнуление счетчика count

65.       in     temp, PIND       ; Чтение порта D             

66. m2: lsr     temp               ; Сдвигаем входной байт влево

67.       brcc m3                   ; Если текущий разряд равен 0

68.       inc    count               ; Увеличиваем показание счетчика

69.       cpi    count, 7           ; Сравнение (7 - конец сканирования)

70.       brne m2                   ; Если не конец, продолжить

71.       rjmp m1                   ; Если ни один ключ не замкнут

 

;---------------------- Вычисление адреса процедуры

 

72. m3: mov  YL, count                ; Вычисляем адрес, где

73.       ldi     ZL, low(tabp*2)       ; хранится начало процедур

74 ldi     ZH, high(tabp*2)

75.       rcall  addw                      ; К п/п 16-разрядного сложения

 

76.       lpm   XL, Z+                   ; Извлекаем адреса из таблицы

77.       lpm   XH, Z                     ; процедур и помещаем в X

 

;---------------------- Выполнение процедур

           

78.         clr       countp       ; Обнуление счетчика процедур

79. m4:  clr       count         ; Обнуление счетчика опроса ключей

80.         inc       countp      ; Инкремент счетчика процедур

81.         cpi  countp, 0x1E   ; Проверяем количество повторов

82.         breq    clark           ; Если конец, процедуру заканчиваем

       

83.         mov ZH, XH           ; Записываем в Z начало процедуры

84.         mov ZL, XL

 

85. m5:    in temp, PIND        ; Читаем содержимое порта D          

86.              cpi temp, 0x7F   ; Проверяем на равенство 7FH

87.              breq  m1           ; Если ключи разомкн. - в начало

88.           lpm temp, Z          ; Извлекаем суммарный код частоты

89.              cpi  temp, 0xFF   ; Проверяем не конец ли процедуры

90.              breq  m4           ; Если конец, процедуру повторяем

 

91.       andi  temp, 0x7F        ; Выделяем код частоты

92.       mov  freq, temp         ; Записываем его в регистр freq

93.       lpm   temp, Z+          ; Еще раз берем суммарный код

94.       rol    temp                 ; Сдвигаем его так, чтобы

95.       rol    temp                 ; старший разряд стал младшим

                

96.       andi  temp, 0x01        ; Извлекаем код длительности

97.       mov  dfreq, temp       ; и помещаем его в регистр dfreq

 

98.       rcall  pfreq                ; К п/п формирования частоты

99.       rjmp m5                   ; Следующая частота

 

100. clark:  in temp, PINB        ;читаем содержимое порта В

101.          andi temp, 0x01      ;выделяем код нулевого бита

102.           cpi temp, 0x01       ;если 1 (ключ S8 разомкнут)

103.           breq m6                ;переход на m6

104.           ldi temp, 0x0B        ; иначе включаем режим CTC

105.           out TCCR1B, temp  ; с предделением 64

106.           sbi PORTB,1           ; прекращаем процедуру (откр2)

107.           rjmp    m5             ; След. частота (сигнал окончания)

 

108. m6:     ldi temp, 0x09        ; Включаем режим CTC

109.         out TCCR1B, temp    ; с предделением 1

110.         sbi PORTB,1             ; прекращаем процедуру (откр2)

111.           rjmp    m5             ; След. частота (сигнал окончания)

 

;***************************************

;*     Вспомогательные подпрограммы         *

;***************************************

 

; ---------------- Подпрограмма 16-ти разрядного сложения

 

112.   addw:  push YH

           

113.      lsl     YL                     ; Умножение первого слагаемого на 2

114.      ldi     YH, 0                ; Второй байт первого слагаемого = 0

115.      add   ZL, YL               ; Складываем младшие байты

116.      adc   ZH, YH              ; Складываем старшие байты

                                            ; с учетом переноса

117.       pop YH                   

118.      ret

 

;------------------ Подпрограмма формирования частоты

 

119. pfreq:    push ZH

120.      push ZL

121.      push YL

122.      push temp

 

123.      cpi    freq, 0x00         ; Проверка на паузу, при паузе

124.      breq nt1                   ; переход  к задержке

  

125.      mov  YL, freq             ; Опред. адрес, где хранится коэфф.

126.      ldi    ZL, low(tabf*2)    ; деления (КД) текущей частоты

127.      ldi    ZH, high(tabf*2)

128.      rcall  addw                 ; К п/п 16-разрядного сложения

 

129.      lpm  temp, Z+            ; Извлек. мл. разр. КД частоты

130.      lpm  temp1, Z             ; Извлек. ст. разр. КД частоты

131.      out   OCR1AH, temp1   ; Запись в ст. регистр совпадения

132.      out   OCR1AL, temp     ; Запись в мл. регистр совпадения

133.     ldi     temp, 0x40          ; Подключаем выход таймера Т1

134.     out  TCCR1A, temp       ; к выводу 15 МК

 

135.     nt1:   rcall  wait            ; К п/п формир. длительности

 

136.     ldi     temp, 0x00           ; Отключаем выход таймера Т1

137.     out TCCR1A, temp         ; от вывода 15 МК

 

138. ldi  dfreq,0                        ; Обнуляем регистр длительности

139. ;rcall      wait                     ; Пауза между частотами

 

140.     pop   temp

141.     pop   YL

142.     pop   ZL

143.     pop   ZH

144.     ret

 

;----------------- Подпрограмма формирования длительности

 

145.   wait:    push ZH

146.                      push ZL

147.              push YH

148.              push YL

 

149.    mov    YL, dfreq                 ; Вычисляем адрес, где хранится

150.    ldi      ZL, low(tabd*2)        ; коэффициент деления для

151.    ldi      ZH, high(tabd*2)      ; длительности КЗ

152.    rcall      addw                    ; К п/п 16-разрядного сложения

 

153.    lpm   YL, Z+                      ; Читаем мл. байт КЗ

154.    lpm   YH, Z                        ; Читаем ст. байт КЗ

 

155.    clr      ZL                           ; Обнуляем регистровую пару Z

156.    clr      ZH

 

            ; Цикл задержки

 

157.  w1:         ldi  loop,255          ; Первый внутренний цикл

158.  w2:         dec loop               ; (предделитель задержки)

159.             brne w2

160.         adiw      R30, 1             ; Увеличение  Z на единицу

161.             cp     YL, ZL              ; Проверка мл. разряда

162.             brne  w1

163.                 cp YH, ZH            ; Проверка ст. разряда

164.             brne  w1

 

165.             pop   YL                   ; Завершение п/п

166.             pop   YH

167.             pop   ZL

168.             pop   ZH

169.             ret

 

;*********************************

;*                Таблица КЗ                    *

;*********************************

 

170. tabd:  

.dw      43636,9741

 

;**********************

;*        Таблица КД         *

;**********************

171. tabf:

.dw  0

.dw 124,132,142,624,627,630,634,643,660,664

.dw 701,705,726,734,739,743,720,800,861,892

.dw 905,953,968,966,976,983,1115,1135,1189,1200

.dw 1249,1262,1275,1288,1315,1343,1358,1373,1388,1436

.dw 1452,1523,1865,1983,2192,2357,2403,2716,3124,3204

.dw 3377,4990,5434,6249,6442,6510,6613,6648,6792,7266

.dw 7715,7812,8116,9190,11573,12754,15624,16446,17360,17856

.dw 18938,23584,24999,36764,39062,52082,62499,709,1373

 

;***********************************

;*         Таблица начала процедур        *

;***********************************

 

172. tabp:     .dw   p1*2,p2*2,p3*2,p4*2,p5*2,p6*2,p7*2

 

;*********************************

;*            Таблица процедур             *

;*********************************

 

;        Варикоз

173. p1:       

.db 73,58,54,43,38,15,14,5,5,14

.db 15,38,43,54,58,73,73,58,54,45

.db 35,31,11,10,10,11,31,35,45,54

.db 58,73,73,58,54,79,16,15,14,6

.db 6,14,15,16,79,54,58,73,73,255

 

;        Бронхит

174. p2:       

.db 77,67,62,58,57,37,13,13,37,57

.db 58,62,67,77,68,65,63,58,31,28

.db 28,31,58,63,65,68,68,255

 

;        Ясные глаза 

175. p3:       

.db 69,66,44,25,19,19,25,44,66,69

.db 69,66,50,39,12,12,39,50,69,66

.db 50,22,20,19,9,9,12,20,22,50

.db 66.69,49,19,17,9,9,17,19,49

.db 52,51,48,20,19,7,7,42,51,52

.db 52,255

 

;       Желудочно-кишечный тракт (ЖКТ)

176. p4:

.db  70,68,61,60,58,54,53,53,54,58

.db  60,61,68,70,68,67,54,26,23,23

.db  26,54,67,68,71,67,59,55,47,46

.db  30,30,46,47,55,59,67,71,71,255

 

;        Антипаразит

177. p5:       

. db  3,2,1,3,2,1,3,255

 

;   Сердцерегуляция    

178. p6:

.db   76,68,62,57,42,41,40,8,8,40

.db   41,42,57,62,68,77,74,35,34,33

.db   32,31,29,5,5,29,31,32,33,34

.db   35,74,74,255

 

;        Антиартрит

179. p7:

.db   75,59,56,27,25,24,18,78,78,18

.db   24,25,27,56,59,75,76,75,72,64

.db   59,58,56,55,55,56,58,59,64,72

.db   75,76,76,61,59,56,55,37,21,4

.db    4,21,37,55,56,59,61,76,76,255

 

Подготовку данных для программирования МК и первоначальную отладку рассмотренной программы проведем с помощью встроенного в AVR Studio программного симулятора. Кратко напомним, как работать с AVR Studio (см. разд. 37.4 в книге [30]).

После запуска AVR Studio вызывается окно выбора параметров проекта, в котором указываются тип компилятора (Project type), название проекта (Project name) и его местоположение (Location) (в данном случае заранее созданная папка MyProg). После нажатия кнопки Next вызывается окно на рис. П3.1.15 для выбора средств отладки (Debug platform), типа МК (Device) и окончательного запуска программы кнопкой Finish.

Текст программы вводится в окне редактора, расположенном в центре главного окна AVR Studio. Легче всего это сделать копированием в это окно файла mag_cvet.asm через буфер обмена (командами (Ctrl +А), (Ctrl + C) и (Ctrl + V)).

 

 

Рис. П3.1.15. Окно выбора типа МК и средств отладки

 

Трансляция программы производится командой Build/Build (F7), результаты выполнения которой отображаются в окне Build (Message) с сообщениями Ассемблера. Если нет сообщений об ошибках, то можно приступать к отладке, в противном случае для их локализации необходимо в указанном окне установить курсор мыши на сообщение об ошибке, отмечаемое красным кружком, и два раза щелкнуть левой кнопкой мыши. При этом в окне редактора курсор будет установлен на вызвавшую сообщение ошибочную строку, выделенную дополнительно цветом.

Запуск отладчика производится командой Build/Build and run, при выполнении которой сначала происходит трансляция с генерацией файла объектного кода, после чего он загружается в отладчик и автоматически открывается окно редактора с исходным текстом программы и желтой стрелкой слева, указывающей на позицию програм­много счетчика МК. Нажимая клавишу F11, в пошаговом режиме можно проследить изменения значений в регистрах устройств ввода/вывода, памяти и регистрового файла, вызывая соответствующие информационные окна из меню View. Если программа оттранслирована, то запуск отладчика можно производить командой Debug/Start Debugging (Ctrl + Shift + Alt + F5). Остановка отладки в любом месте производится командой Debug/Stop Debugging (Ctrl + Shift + F5).

На рис. П3.1.16, а показана раскрытая ветвь PORTD, где после выполнения строки 41 семь квадратиков (битов) закрашиваются в темный цвет, что соответствует логическим единицам на семи выводах порта. Однако это происходит только в случае, когда в строке 65 регистр PIND временно (на время отладки) меняется на PORTD, поскольку регистр PIND в нашей программе не инициализируется. Такую же замену необходимо сделать (тоже временно) и в строке 85. Сразу после строки необходимо левым щелчком мыши «перекрасить» один из черных квадратиков в белый цвет (нулевой бит), имитируя тем самым выбор процедуры (на рис. П3.1.16, а выбрана первая процедура).

На рис. П3.1.16, б показано состояние регистров после выполнения строки 156. Для того, чтобы «перескочить» через цикл задержки, необходимо при подходе к строке 157 курсор мыши перевести на строку 165 и выполнить команду Debug/Run to Cursor (Ctrl + F10), после чего курсор отладчика переместится на строку 165, что позволит исключить утомительный для прохода участок программы. Заметим, что по состоянию содержимого регистров достаточно легко выявляются ошибки, а сам процесс их определения представляется достаточно увлекательным занятием (особенно для начинающих). При этом, как видно из рис. П3.1.16, б, под рукой целесообразно иметь таблицу соответствия между номерами регистров и их смысловыми именами (как это сделано при описании программы).

После отладки для получения в папке проекта Mag_cvet файла для программатора (с расширением .HEX) необходимо выполнить команду File/Save All.

     

   

                  а)                                               б)

Рис. П3.1.16. Окна I/O View и Register

 

Proteus-модель прибора МагЦвет содержит (см. рис. П3.1.17) модель МК U1, стимуляторы (имитаторы ключей S1—S8 на рис. П3.1.12) ввода логических сигналов 1 (стрелка «вверх» в кружочке) или 0 (стрелка «вниз») типа LOGICSTATE из библиотеки Debugging Tools/Logic Stimuli и элементы LOGICPROBE (из библиотеки Debugging Tools/Logic Probes) для отображения состояния выходов END (конец процедуры), FT (выход таймера Т1), а также осциллограф OSC для осциллографических измерений сигналов терапевтических частот. Сигналы таймера Т0 в рассматриваемой модели не формируются.

 

 

Рис. П3.1.17. Модель микроконтроллерной части прибора

 

После создания в среде ISIS/Proteus схемы на рис. П3.1.17 необходимо:

1. Сохранить ее изображение (файл Mag_cvet.DSN) в папке Mag_cvet, созданной в AVR Studio.

2. В окне команды Source/Add/Remove Source Code Files в строке Target Processor выбрать ATtiny2313, в строке Code Generation Tool AVRASM2, а в строке  Source Code Filename указать путь к папке Mag_cvet с файлом mag_cvet.asm.

3. В окне команды Source/Define Code Generation Tools в строке Tool выбрать AVRASM2 и нажать кнопку ОК, в результате чего будут созданы (или обновлены) HEX-файл и листинг программы.

4. Правым щелчком мыши по U1 вызвать контекстное меню и убедиться, что в его пункте Edit Properties в строке Program File имеется ссылка на файл mag_cvet.hex. В строке CKSEL Fuses из списка выбрать (0100) Int. RC Osc. 8 MHz (тактовая частота МК).

5. Повторить п. 3 с тем отличием, что в строке List File Exnt расширение LST меняется на SDI, а кнопкой Browse указывается путь к папке Mag_cvet с файлом AvrBuild.bat, созданным в AVR Studio. В результате выполнения этой операции в папке Mag_cvet будет создан отладочный файл Mag_cvet.SDI, позволяющий в пошаговом режиме с помощью меню Debug вызывать окна AVR Source Code, AVR CPU Register, AVR I/O Register и др.

5.1. Сравнительный анализ файлов Mag_cvet.SDI и Mag_cvet.LST показывает, что они идентичны по объему и содержанию. Поэтому для создания SDI-файла достаточно в копии Mag_cvet.LST заменить расширение .LST на .SDI.

 

Хостинг от uCoz