Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Лабораторная работа 2.6





Тема: таймер 0 CPU, прерывание и 4 светодиода.

Цель: включить использование системы прерывания в проект Lab21. Вместо использования программного цикла задержки для отсчета интервала времени между выходными шагами, теперь будем использовать один из 3 –х таймеров.

Одно из самых простых заданий для таймера – сгенерировать периодический запрос прерывания. Мы можем использовать свою подпрограмму обработки прерываний, чтобы выполнить периодические действия или увеличивать глобальную переменную. Эта переменная затем будет определять число периодов, которые пройдены от начала работы программы.

Таймер 0 использует Peripheral Interrupt Expansion (PIE)–модуль. Это даст нам возможность испытать это устройство. Таймеры 1 и 2 обходят (PIE)–модуль и они обычно резервируются для операционной системы реального времени, называемой «DSP/BIOS». Следовательно, мы применим Таймер 0 как часы ядра для этого упражнения.

Порядок выполнения.

Создайте файл проекта.

Используя Code Composer Studio, создайте новый проект, который назовите Lab24.pjt в C:\DSP2833x\Labs (или в другой папке, которая доступна Вам).

Откройте файл Lab5_1.c из C:\DSP2833x\Labs\Lab5 и сохраните его как Lab6.c в C:\DSP2833x\Labs\Lab6.

Добавьте этот исходный файл программы к вашему новому проекту Lab27.c.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_headers\source добавьте: DSP2833x_GlobalVariableDefs.c.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\source добавьте: DSP2833x_CodeStartBranch.asm.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\cmd добавьте: 28335_RAM_lnk.cmd.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_headers\cmd добавьте: DSP2833x_Headers_nonBIOS.cmd.

Из C:\CCStudio_v3.3\c2000\cgtools\lib добавьте: rts2800_fpu32.lib.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\source добавьте:

– DSP2833x_SysCtrl.c;

– DSP2833x_ADC_cal.asm;

– DSP2833x_usDelay.asm.

Во всех упражнениях Lab21 мы использовали нашу собственную функцию названную «InitSystem()», чтобы проинициализировать ядро устройства. Теперь мы будем использовать предусмотренную функцию «InitSysCtrl()» из файла DSP2833x_SysCtrl.c. Это – всегда хорошая практика, чтобы использовать проверенный код, нет причины изобретать колесо. Два других файла DSP2833x_Adc_cal.asm и DSP2833x_usDelay.asm определяют функции, которые вызываются из функций в файле DSP2833x_SysCtrl.c –, так что мы должны также добавить эти два файла в наш проект.

Компиляция проекта

Мы также должны установить маршрут поиска C–Компилятором файлов include. Нажмите:Project → Build Options.

Выберите в таблице Компилятора категорию «Preprocessor», найдите окно Поиска Маршрута Include и введите следующие две строки в это окно:

– C:\tidcs\C28\dsp2833x\v131\DSP2833x_headers\include;

– C:\tidcs\C28\dsp2833x\v131\DSP2833x_common\include.

Установите поддержку с плавающей запятой для C – компилятора. В выборе опций Build таблицы Компилятора. В «Advanced» категории установите «Floating Point Support» – fpu32.

Установите размер стека. Во вкладке Build выберите таблицу Компоновщика и введите в Size (stack) окно: 400

Закройте меню опций Build нажав <OK>.

Модифицируйте Исходную Программу.

Откройте Lab6.c, чтобы отредактировать: двойное нажатие на «Lab6.c» в окне проекта. В начале вашего кода, добавьте описание функции для внешней функции «InitSysCtrl()»:

 

extern void InitSysCtrl(void);

 

Удалите описание функции для локальной функции «InitSystem()» в начале и вызов функции в конце Lab6.c.

Замените вызов функции «InitSystem()» на «InitSysCtrl()».

«InitSysCtrl()» выводит из строя сторожевой таймер, но мы хотели бы, чтобы сторожевой таймер был активным, мы должны восстановить сторожевой таймер. Добавьте следующие строки после вызова функции «InitSysCtrl()»:

 

EALLOW;

SysCtrlRegs.WDCR = 0x00AF;

EDIS;

Компиляция, загрузка и проверка.

Теперь новый проект готов для компиляции. Программа должна вести себя точно как в Lab21, четыре светодиода LD1–LD4 используются, чтобы проверить двоичный счетчик. Еще раз, вот шаги:

– Project →Build;

– File →Load Program;

– Debug →Reset CPU;

– Debug →Restart;

– Debug →Go main;

– Debug →Run;

Если код не работает как в Lab21, не продолжайте следующие шаги. Возвратитесь и попытайтесь обнаружить, какой шаг процедуры Вы пропустили.

Модификация исходной программы – часть 2.

В начало «Lab6.c» добавьте описание функции для обработки прерываний от таймера 0:

 

interrupt void cpu_timer0_isr(void);

 

В «main()», непосредственно после вызова функции Gpio_select(), добавьте вызов функции:

 

InitPieCtrl().

 

Эта функция предусматривается файлом заголовка примеров header file. Мы используем эту функцию как она есть. Цель этой функции – очистить все PIE–прерывания и запретить все линии прерывания PIE. Это – полезный шаг, если мы хотели бы проинициализировать PIE–модуль. Функция «InitPieCtrl ()» определяется в файле исходной программы «DSP2833x_PieCtrl.c»; мы должны добавить этот файл к нашему проекту:

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\source добавьте к проекту: DSP2833x_PieCtrl.c.

Также, добавьте описание функции в начале Lab6.c:

 

extern void InitPieCtrl(void);

 

В «main()», непосредственно после вызова функции «InitPieCtrl();», добавьте вызов функции:

 

InitPieVectTable();

 

Эта функция проинициализирует PIE –память в начальное состояние. Она использует встроенную таблицу прерываний «PieVectTableInit()» – определенную в файле исходной программы «DSP2833x_PieVect.c» эта таблица находится в глобальной переменной «PieVectTable» – определенной в «DSP2833x_GlobalVariableDefs.c». Переменная «PieVectTable» связывается с физическую память области PIE.

Также, добавьте описание функции в начало Lab6.c:

 

extern void InitPieVectTable(void);

 

Чтобы появилась возможность использовать «InitPieVectTable()», нам нужно добавить два кодовых файла в наш проект:

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\source, добавьте к проекту: DSP2833x_PieVect.c и DSP2833x_DefaultIsr.c.

Кодовый файл «DSP2833x_DefaultIsr.c» добавит комплект программ обработки прерываний в наш проект. Когда Вы откроете и просмотрите этот файл, Вы найдете, что все ISR состоят из бесконечного цикла и специфической инструкции ассемблера «ESTOP0». Эта инструкция ведется себя подобно программной контрольной точке. Это – мера безопасности. Запомните, в этой точке мы запретили все прерывания PIE. Если бы мы начали теперь выполнять программу, мы никогда не увидели бы запрос прерывания. Если, по некоторой причине, например сбой блока питания, влияние шума или просто программный дефект, DSP вызывает программу обработки прерываний, тогда, мы можем поймать это событие прерыванием «ESTOP0».

Теперь мы должны отразить обработку прерываний от CPU–Timer0 из функции «ESTOP0» на реальную обработку прерываний. Чтобы сделать это, необходимо редактировать исходную программу кода «DSP2833x_DefaultIsr.c». Конечно, это не было бы мудрым решением, из–за того, что мы должны модифицировать исходный код для этого единственного лабораторного упражнения. Так это не делают. Значительно лучший путь – модифицировать запрос для обработки прерываний CPU–Timer0 непосредственно в PIE–памяти. Это сделаем, добавив 3 строки после вызова функции «InitPieVectTable();»:

 

EALLOW;

PieVectTable.TINT0 = &cpu_timer0_isr;

EDIS;

 

EALLOW и EDIS – два макроопределения, позволяющие разрешить и запретить доступ к группе защищенных регистров; PIE является частью этой области. Имя нашей собственной подпрограммы обработки прерываний для Timer0 – «cpu_timer0_isr()». Мы создали описание прототипа раннее в процедуре для этой лабораторной работы. Пожалуйста, используйте то же имя, что Вы использовали в описании прототипа.

В «main()», непосредственно после инструкций описания, добавьте вызов функции «InitCpuTimers();». Эта функция установит Timer0 в начальное состояние и она остановит этот таймер.

InitCpuTimers();

 

Также, добавьте описание функции в начало Lab6.c:

 

extern void InitCpuTimers(void);

Кроме того, мы используем встроенную функцию. Чтобы сделать так, мы должны добавить исходный файл программы «DSP2833x_CpuTimers.c» в наш проект.

Из C:\tidcs\c28\dsp2833x\v131\DSP2833x_common\source добавьте к проекту: DSP2833x_CpuTimers.c.

Теперь мы должны проинициализировать Timer0, чтобы сгенерировать период 100ms. TI предусмотрели функцию «ConfigCpuTimer». Все что мы должны сделать, это передать 3 аргумента в эту функцию. Параметр 1 – адрес структуры таймера, например, «CpuTimer0»; Параметр 2 является внутренней частотой DSP в MHz, например, 150 для 150MHz; Параметр 3 является временем периода переполнения таймера в микросекундах, например, 100000 в течение 100 миллисекунд. Следующий вызов функции установит Timer0 в период 100ms:

 

ConfigCpuTimer(&CpuTimer0, 150, 100000);

 

Добавьте этот вызов функции в «main()» непосредственно после строки InitCpuTimers();

Кроме того, добавьте описание функции в начало Lab6.c:

 

extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);

 

Прежде, чем запустить timer0, мы должны установить маску прерывания. Мы должны позаботиться о 3–х уровнях, чтобы позволить индивидуальный источник прерывания. Уровень 1 – модуль PIE. Чтобы разрешить его работу, мы должны установить бит 7 PIEIER1 в 1. Почему? Потому что прерывание Timer0 непосредственно подключается к групповому INT1, Bit7. Добавьте следующую строку к вашему коду после вызова «ConfigCpuTimer()» на этапе 26:

 

PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

 

Далее, разрешим прерывание от линии 1 (INT1). Модифицируйте IER– регистр соответственно.

 

IER |= 1;

 

Далее, разрешим управляющие прерывания (EINT) и отладочные прерывания (ERTM) глобально. Это сделано посредством добавления двух кодовых макроопределений: EINT; и ERTM;

Наконец, мы должны запустить Таймер 0. Бит TSS в регистре TCR сделает эту работу. Добавим:

CpuTimer0Regs.TCR.bit.TSS = 0;

После конца «main()», мы должны добавить нашу новую подпрограмму обработки прерываний «cpu_timer0_isr()». Вспомните, мы определили эту функцию в начале наших модификаций. Теперь мы должны добавить её тело. В этой функции мы должны выполнить две операции:

– приращение счетчика прерывания «CpuTimer0.InterruptCount», это позволит нам иметь глобальную информацию о том, сколько раз по 100 миллисекунд прошло;

– внести последнюю строку в подпрограмму обработки прерывания перед возвратом. Этот шаг необходим, чтобы восстановить Таймер 0 для следующей обработки прерываний. Это сделано посредством:

 

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

 

Теперь мы уже всё почти сделали. В бесконечном цикле while(1) в «main()» мы должны удалить вызов функции: «delay_loop(1000000);». Нам больше не нужна эта функция; мы можем также удалить её описание в начале нашего кода и функциональное тело, которое все еще представлено после кода «main()».

В бесконечном цикле «while(1)», после «if–else»–конструкции, мы должны вставить оператор для ожидания пока глобальная переменная «CpuTimer0.InterruptCount» не увеличится на 1, что соответствует интервалу 100 миллисекунд. Не забывайте восстанавливать переменную «CpuTimer0.InterruptCount» в нуль, если Вы продолжаете ожидание.

Примечание. Глобальная переменная «CpuTimer0.InterruptCount» определена в файле «DSP2833x_CpuTimers.c» как глобальная переменная, которая также проинициализирована в нуль, когда мы вызвали функцию «ConfigCpuTimer()».

Не забываем о сторожевом таймере. Мы удалили его обслуживание вместе с функцией «delay_loop()». Итак, мы должны добавить восстанавливающую последовательность сторожевого таймера где–нибудь в нашу модифицированную исходную программу. Где? Хорошая стратегия – обслуживание таймера не в единственной части нашего кода. Наш код теперь состоит из двух независимых заданий:

While– цикл основы и программа обработки прерываний таймера 0. Установите одну из двух восстановительных инструкций для WDKEY в ISR и другую в while(1)–цикл основы.

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

Скомпилируйте, загрузите и протестируйте.

Теперь новый проект готов для финала. Код должен вести себя снова точно как в Lab2.1, четыре светодиода LD1 – LD4 должны повторять двоичный счетчик, но теперь базирующиеся на аппаратной базе времени и рабочей системе прерывания. Вот шаги:

– Project → Build;

– File → Load Program;

– Debug → Reset CPU;

– Debug → Restart;

– Debug → Go main;

– Debug → Run.

 

Date: 2015-06-06; view: 730; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию