Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекция - Си

.pdf
Скачиваний:
67
Добавлен:
18.05.2014
Размер:
431.24 Кб
Скачать

Структуры

Структура — комплексный тип данных, содержащий внутри набор типов

-используется для работы с группой переменных как с единой переменной;

-переменная, созданная с использованием структурного типа называется переменной-структурой, объектом структуры, либо экземпляром структуры;

-элементы структуры хранятся в памяти последовательно;

typedef struct

{

// Члены (элементы) структуры unsigned char channel;

float value; } Result;

// Объявление нового имени для указателя на структуру typedef Result* ResultPtr;

Result res1; // Создание экземпляра структуры Result; 41

Структуры

Операторы доступа к членам структуры:

. (точка) — для обычных переменных (не указателей); -> (стрелка) – для указателей на структуры;

typedef struct

{

unsigned char channel; float value;

} Result;

typedef Result* ResultPtr;

Result res1;

ResultPtr resPtr1 = &res1;

res1.channel = 5;

resPtr1->value = 2.5; // Доступ через указатель

42

Регистры ввод-вывода, отражённые в память

Часть адресного пространства «подключена» к регистрам ввода-вывода периферийных устройств; Группы регистров → объекты структуры;

0xFFFD8000

ADC

ADC

ADC

...

Control

Mode

Channel

 

Register

Register

Enable

 

typedef struct

Register

 

 

 

{

 

 

 

volatile unsigned int ADC_CR;

 

 

volatile unsigned int ADC_MR;

 

 

volatile unsigned int reserved;

 

volatile unsigned int ADC_CHER;

 

...

 

 

 

} AT91S_ADC;

 

 

 

typedef AT91S_ADC * AT91PS_ADC;

 

 

AT91PS_ADC adc = (AT91PS_ADC)0xFFFD8000;

43

adc->ADC_CR = 0x02; // Запуск АЦП

 

Volatile

Компилятор оптимизирует код для увеличения скорости работы программы, для уменьшения занимаемого объёма памяти. Иногда это нежелательно.

volatile — модификатор типа, выборочно отключающий оптимизацию.

Применение volatile:

-при работе с регистрами ввода-вывода (регистры периферийных устройств);

-для глобальных переменных, изменения которых возможны из прерываний

typedef struct

{

volatile unsigned int ADC_CR; volatile unsigned int ADC_MR;

...

volatile unsigned int ADC_SR; // Status register

} AT91S_ADC;

 

AT91PS_ADC adc = AT91C_BASE_ADC;

 

// Ожидание готовности

44

while (! (adc->ADC_SR & AT91C_ADC_EOC4));

 

Препроцессор

Препроцессор — "предварительный обработчик" (исходного кода).

-текстовые подстановки:

-макроопределения;

-макрофункции;

-подстановка файла;

-условная компиляция;

#include "Board.h" // подстановка файла

#define ARRAY_SIZE 20 // макроопределение

int main (void)

{

double array[ARRAY_SIZE];

...

}

45

Обработка прерываний от АЦП (введение)

ADC

CPU

(АЦП)

(Процессор)

AIC

... (Контроллер Другие прерываний) устройства

...

Источники

прерываний

Контроллер прерываний:

Хранит адреса подпрограмм обработки прерываний для каждого источника; Обеспечивает приоритезацию обработки прерываний;

Уведомляет процессор о прерывании → прерывание на уровне процессора;

46

Процесс обработки прерывания

Устройствоисточник прерывания

Сигнализирует о событии

Контроллер

прерываний

Контроллер

прерываний

реагирует на сигнал

Передача вектора прерывания в процессор

Обработка

прерывания

подтверждена

Процессор

Процессор прерывает выполнение программы

Начало обработки прерывания. Чтение вектора прерывания

Переход по вектору — обработка прерывания

Уведомление об окончании прерывания

Процессор продолжает выполнение прерванной

программы

Пример.

Работа с АЦП с использованием прерываний (1) Настроить контроллер прерываний:

-настроить источник прерываний:

-приоритет;

-по фронту/по уровню;

-задать подпрограмму обработки прерывания;

-включить приём сигн. прерываний от источн.

Настроить АЦП:

-разрядность преобразования;

-время выборки;

-частота тактирования;

-включить генерацию прерывания по

завершению преобразования;

48

- и др.

 

Пример.

Работа с АЦП с использованием прерываний (2)

#include "Board.h"

//Указатель на область регистров АЦП

//static AT91S_ADC *adc = (AT91S_ADC *)0xFFFD8000; static AT91PS_ADC adc = AT91C_BASE_ADC;

//Указатель на группу регистров AIC

//(контроллер прерываний)

static AT91PS_AIC aic = AT91C_BASE_AIC;

//Объявление функции-обработчика прерывания static void adcInterruptHandler(void);

//Флаг, свидетельствующий о том, что выполняется преобразование static volatile unsigned char adcIsRunning = false;

49

Пример.

Работа с АЦП с использованием прерываний (3)

//Настройка контроллера прерываний для обслуживания

//сигналов прерываний от АЦП

void setUpAic(void)

{

// Маска для настройки обработки прерываний от АЦП

const unsigned int intMask = (1 << AT91C_ID_ADC); // 1 lsl 4

//Настройка "источника" прерывания. AIC Source Mode Register.

//Будем регистрировать прерывание по перепаду,

//приоритет — максимальный. Source Mode Register.

aic->AIC_SMR[AT91C_ID_ADC] = AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED | AT91C_AIC_PRIOR_HIGHEST;

//Установка функции-обработчика прерывания. Source Vect. Reg. aic->AIC_SVR[AT91C_ID_ADC] = (unsigned int)&adcInterruptHandler;

//Включаем обработку прерываний от АЦП. Inter. Enable Cont. Reg aic->AIC_IECR = intMask; // AIC Interrupt Enable Command Reg

}

50