› Статьи › Микроконтроллеры › Микроконтроллер Attiny13A в реальном мире

Attiny13A в реальном мире (прерывания, вызов функций и таймеры)


 

 

Оценка скорости процессов переключения и запуска

В даташите написано, что частота максимально 9.6MHz, притом установлен fuse-bit CKDIV8 в 0. В этом случае тактовая частота делится в 8 раз. Значит, 1.2MHz. Повысить частоту можно установкой данного fuse-bit в 1. Однако, могут быть проблемы в будущем. Об этом - позже.

Так что же из него можно в итоге "выжать".


1. Скорость и точность исполнения вызовов функций

Напишем простую программу

 

#include <avr/io.h>

int main(void)
{
  DDRB = 0xff;
  while(1)
  {
    PORTB= 0xff;
    PORTB= 0x00;
    PORTB= 0xff;
    PORTB= 0x00;
  }
}

 

Подключаем к щупам X/Y осциллографа порты PB0 и PB4 микроконтроллера Attiny13A. Настраиваем триггер осциллографа на срабатывание по восходящему фронту или включаем ждущий режим (single), чтобы регистрация началась с момента подачи сигнала. Здесь и далее предполагается делитель пробника, установленный в положение 1:10. Т.е. все показания по oY (Вольты) надо умножить в 10 раз.

 

 

Итак:

  • Время запуска и начала исполнения первой инструкции переключения ~ 6,5 мкс.
  • Время переключения из лог. 1 в лог. 0 ~ 1 мкс. Что соответствует одному такту.
  • Время перехода из лог. 0 (конец цикла) в начало исполнения цикла и установки лог. 1 ~ 2.7 мкс. То есть 3 такта! Стоит указать, что при выходе из цикла происходит выход из области видимости, что может повлечь дополнительные такты на работу с переменными (редко).
  • Смещение срабатывания портов (на рисунке видно, что PB4 срабатывает позже) ~ 100нс (~10MHz). То есть подключать его к логике, работающей не менее чем на f/2 = 5MHz надо внимательно, иначе может возникнуть ситуация, когда один выход уже установлен, а другой должен быть установлен, но пока еще не переключился. Вообщем на стороне приемника надо ждать минимум 100-200нс для точного детектирования.
  • Частота устоявшегося цикла ~ 275kHz (Фьюз CKDIV8=0, Int. RC OSC 9.6 MHz 14CK + 64 ms).

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

 

Так что данный микроконтроллер подходит для решения простейших задач. К примеру, максимально удовлетворительным результатом был вывод результатов на семисегментный индикатор через программный SPI. Отправка данных на 7-ми знаковый индикатор происходит менее чем за 1 секунду.

А управление, к примеру, драйвером MAX7219 светодиодной матрицы для организации бегущей строки работает крайне медленно. Удовлетворительно - при CKDIV8=1 (соответственно, тактовая частота в 8 раз больше). Данный бит установлен в 0 производителем не просто так. Ведь не логично сознательно понижать тактовую частоту. К примеру, в Atmega88 данный бит установлен по умолчанию в 1.

Так вот в случае с Attiny13 практически все SPI-программаторы перестают "видеть" Attiny13 при установке данного fuse-bit в 1. Нужен либо параллельный высоковольтный программатор либо Fusebit doctor.

 

 

2. Скорость и точность исполнения по таймеру/прерываниям

Открываем даташит на Attiny13 и смотрим раздел №9 (Interrupts). В микроконтроллере одно внешнее настраиваемое прерывание INT0 (вывод PB1) и общее ненастраиваемое прерывание для порта PCINT[0:5]. Настроим INT0.

Для этого нам нужно установить биты ISC01, ISC00 регистра MCUCR.

 

 

 

Далее - в регистре GIMSK установить бит INT0, чтобы разрешить прерывания.

 

Далее необходимо разрешить использование прерываний макросом sei().

В регистре GIFR можно читать бит INTF0, чтобы детектировать было ли прерывание. Или писать 1, чтобы сбросить данный бит.

 

 

Пишем код

#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>

 

//Обработчик прерывания INT0

ISR(INT0_vect)
{
   PORTB = 0b00000001;
   PORTB = 0b00000000;
}

 

Инициализация прерываний

void InitINT0()
{
   MCUCR =_BV(ISC01) | _BV(ISC00);
   GIMSK = _BV(INT0);
   sei();
}

 

int main(void)
{
   DDRB  = 0b00000001;
   PORTB= 0b00000000;
   InitINT0();

    while(1){

   }
}

 

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

Для срабатывания прерывания в данном случае нужно сначала подать на порт PB1 сиганл низкого уровня (замкнуть с общим выводом), а потом разомкнуть. Данный порт никуда не подключен и на нем не установлены push/pull резисторы. Следовательно, на нем присутсвует некоторое напряжение (неопределенное сосояние Z). И прерывание произойдет, когда лог. 0 сменит Z на восходящем фронте. Процесс иллюстрируют два рисунка ниже. PB1 - желтый цвет. PB0 - голубой цвет.

 

Всего, судя по графику, около 17 тактов от восходящего фронта до срабатывания прерывания.

 

 

На последнем рисунке видно, что помеха от переключения порта PB1 перешла в порт PB0. Хотя мы и настроили срабатывание прерывания по восходящему фронту, это не означает, что оно сработает при переходе из лог. 0 в лог. 1. Оно срабатывает при переходе из лог. 0 в неопределенное состояние Z.

 

Время переключения всего порта PB (когда указываются все пины без применения булевых функций) в обработчике прерывания INT0 стандартно - 1 такт.

 

 

Изменим код таким образом, чтобы состояние вызывающего прерывание пина менялось автоматически.

 

#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>

 

ISR(INT0_vect)
{
   PORTB |= _BV(PB0);
   PORTB &= ~_BV(PB0);
}

 

void InitINT0()
{
   MCUCR =_BV(ISC01) | _BV(ISC00);
   GIMSK = _BV(INT0);
   sei();
}

 

int main(void)
{
   DDRB = 0b00000011;
   InitINT0();

    while(1){
   PORTB |= _BV(PB1);
   PORTB &= ~_BV(PB1);
   }
}

 

 

Вот примерное быстродействие срабатывания прерывания Attiny13 - 15.3 мкс. Добавим время на вычисление лог. И и присвоение значения лог. 0 пину PB0 в обработчике прерывания (2 такта) ~ 1.8 мкс. В итоге получается "боевая" рабочая частота не более 58 kHz.

 

На всех графиках заметны помехи. Рассмотрим их ближе:

 

Помеха переключения пина достигает 0.2 Вольт на соседнем пине. Также есть периодическая помеха амплитудой 20 мВ и частотой 2.4МГц. 

 




19/05/2011
Добавлена версия стандарта C++
В главном меню сайта добавлена ссылка на нашу версию оформления кода на C++.
0

11/05/2011
Запуск сайта
Сегодня запущен портал
0



      Копирование материалов сайта возможно только при размещении прямой ссылки на www.kernel.pro