Лекция - Си
.pdfСтруктуры
Структура — комплексный тип данных, содержащий внутри набор типов
-используется для работы с группой переменных как с единой переменной;
-переменная, созданная с использованием структурного типа называется переменной-структурой, объектом структуры, либо экземпляром структуры;
-элементы структуры хранятся в памяти последовательно;
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 |
|