Главная  Микроконтроллеры 

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [ 37 ] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90] [91] [92] [93]


Рис. 4.10. Окно, появляющееся после успешной трансляции программы

Примеры программ для компилятора CodeVision AVR С

Процедуры работы со встроенным АЦП AT90S8535 без прерываний

Текст программы:

в данном примере определяются две функции для работы с АЦП: void InitADC(void) инициализация АЦП

int fieadADC(unsigned char) чтение значения напряжения на заданном входе Binclude <ioB535.h> void InitADC(void)

ADHUX = 0; выбрать вход номер О

ADCSfi = OxCO; включить АЦП и запустить первое "пустое" преобразование

int ReadADC(unsigned char channel) «

int i;

ADHUX = channel; ADCSR 1= 0x40;

Выбрать номер входа Начать преобразование



Itasm

Idd гЗО,y+3

;R30=LSB a

Idd r31,y+4

;R31=HSB a

Idd r26,y+1

;R26=LSB b

Idd r27,y+2

;R27=HSB b

add гЗО,г26

;(R31,R30)=a+b

adc Г31.Г27

Id Г26.У

;R26=C

clr r27

.Преобразование с типа unsigned char в тип int

add гЗО, г26

;(R31.R30)=(R31,R30)+C

adc г31,г27

Kendasm

Itpragma warn-i Разрешить предупреждения

void main(void) { int r;

Теперь вызовем функцию и сохраним результат в г

r=sum abc(2,4,6);

while (KADCSR & 0x10)); Проверка завершения преобразования

ADCSR 1= 0x10; Очистка бита "Преобразование завершено" при

помощи записи в него "1"

1 = ADCL; Чтение младших В битов ПЕРВЫМИ

1 += (int)ADCH « В; Чтение старших 2 битов, умножение их на 256

и сложение с младшим байтом

return i;

void main(void) «

unsigned int temp;

InitADCO; Инициализация АЦП

temp=ReadADC(0); Измерить напряжение на нулевом входе АЦП (линия РАО порта А)

Пример вызова написанных на ассемблере функций из С программы

Материал взят из демонстрационной версии компилятора Code-VisionAVR С Compiler, автором которого является Pavel Haiduc, HP InfoTech S.R.L.

Текст программы:

Определение функции на ассемблере. Эта функция возвращает а+Ь+с «ргадпа warn- Запретить предупреждения int sum abc(int а, int b. unsigned char с) {



Некоторые пояснения.

Компилятор передает параметры функции с помощью стека данных. Первым он передаст целый параметр а, затем b и в заверщение с типа unsigned char. При каждой передаче регистровая пара Y увеличивается на размер параметра (4 для типа long, 2 для int, 1 для char).

В случае параметров, состоящих из нескольких байтов, первым передается старщий байт. Как вы видите, стек растет вниз. После того как все параметры функции были записаны в стек (pushed), регистр Y указывает на последний параметр с, поэтому мы можем прочитать его значение в R26, воспользовавшись командой Id г26,у.

Параметр b бьш записан в стек перед с, поэтому он находится по более высокому адресу в стеке данных. Мы можем прочитать его значение, воспользовавшись командами Idd г27,у+2 (старший байт) и Idd г26,у+1 (младший байт).

Старший байт был записан в стек первым, поэтому он находится по более высокому адресу.

Параметр а был записан в стек перед Ь, поэтому он находится по более высокому адресу в стеке данных. Мы можем прочитать его значение, воспользовавшись командами Idd г27,у+4 (старший байт) и Idd г26,у+3 (младший байт).

Старший байт был записан в стек первым, поэтому он находится по более высокому адресу.

Функции возвращают свои значения в следующих регистрах:

R30 для типов char & unsigned char;

R30, R31 для типов int & unsigned int;

R30, R31, R22, R23 для типов long & unsigned long.

Поэтому наша функция должна вернуть ее результат в регистрах R30,R31.

После возвращения из функции компилятор автоматически генерирует код, освобождающий стек от параметров функции, поэтому можно не задумываться об этом.

Директива #pragma warn запрещает компилятору генерировать предупреждения о том, что функция не возвращает результат.

Это необходимо, потому что компилятору не известно, что мы делаем в нашей написанной на ассемблере функции.



[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [ 37 ] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90] [91] [92] [93]

0.0011