8-900-374-94-44
[email protected]
Slide Image
Меню

Программный spi avr на си – Программная реализация протокола SPI на AVR в CodeVisionAVR

Программная реализация ведущего шины SPI. (подробный разбор и некоторые процедуры на асме для PIC и AVR)

В этой статье рассматривается пример программной реализации на микроконтроллерах PIC и AVR функций ведущего шины SPI для разных режимов (mode0, mode1, mode2, mode3). Чтобы понимать что происходит — для начала, как всегда, читаем теорию (что такое SPI и как он работает). Если с теорией разобрались, тогда можно приступать к практической реализации.

Итак, что должен уметь делать SPI-мастер? Собственно говоря, всего четыре вещи:

1) читать с шины MISO нужное количество бит;

2) передавать по шине MOSI нужное количество бит;

3) формировать на шине SCLK нужное количество импульсов, соблюдая правильную полярность;

4) управлять шиной SS.

Как вы знаете (вы же с теорией знакомы?) — чтение и установку данных и «Мастер», и «Слэйв» производят по противоположным фронтам сигнала тактирования, причём для приёма и передачи может использоваться один и тот же сдвиговый регистр. Для наглядности давайте нарисуем для всех четырёх режимов диаграммы сигналов, соответствующие передаче по SPI двух бит, а уже по ним распишем действия контроллера:

Диаграммы нарисованы для случая, когда передача осуществляется младшим битом вперёд.

Биты, не выделенные жирным, — не имеют для нас значения и могут быть на следующем этапе перезаписаны (это, например, те биты, которые мы уже установили на шину данных, или, наоборот, — уже считали с шины данных).

По диаграммам видно, что в результате обмена данными сдвиговые регистры «Мастера» и «Слэйва» поменялись содержимым (помните, в теоретической части я писал, что у SPI есть такая особенность, — для приёма и передачи можно использовать один и тот же регистр).

Прежде чем переходить к написанию кода, — давайте ещё подумаем вот о чём. Архитектура контроллеров у нас 8-ми битная, а для SPI часто может потребоваться бо’льшая размерность сдвигового регистра.  Пусть в нашем примере размер сдвигового регистра можно будет выбрать от 1-го до 32-х бит. То есть максимально под сдвиговый регистр мы будем выделять 4 байта (4 восьмибитных регистра, расположенных в памяти так, как на рисунке справа). Для случаев, когда размер регистра превышает 1 байт (то есть равен 2, 3 или 4 байта) мы будем программно имитировать работу с несколькими 8-ми битными регистрами как с одним большим. Используемые для организации сдвигового регистра восьмибитные регистры в дальнейшем будем называть просто байтами, чтобы не путаться.

Итак, что представляет собой чтение с точки зрения «Мастера»? Да ничего особенного, — нужно просто прочитать сигнал на входе (MISO) и записать его в младший или старший бит сдвигового регистра (в зависимости от того — младшим или старшим битом вперёд передаются данные и от значения CPHA). Вот так это выглядит в коде:

Для контроллеров PIC:Для контроллеров AVR:

1) Для передачи младшим битом вперёд при CPHA=0 и старшим битом вперёд при CPHA=1

Read_MISO:
   bcf   INDF, 0
   btfsc PORT_SPI, MISO_Line
   bsf   INDF, 0
   return

2) Для передачи старшим битом вперёд при CPHA=0 и младшим битом вперёд при CPHA=1

Read_MISO:
   bcf   INDF, 7
   btfsc PORT_SPI, MISO_Line
   bsf   INDF, 7
   return

Для случая 1 в регистр FSR должен быть предварительно загружен адрес младшего используемого байта нашего сдвигового регистра, а для случая 2 — адрес старшего используемого байта этого регистра.

PORT_SPI — адрес порта ввода /вывода, к которому подключена линия MISO,

MISO_Line — номер канала порта.

1) Для передачи младшим битом вперёд при CPHA=0 и старшим битом вперёд при CPHA=1

Read_MISO:
   ld    temp, X
   cbr   temp, 0b00000001
   sbic  PIN_SPI, MISO_Line
   sbr   temp, 0b00000001
   st    X, temp
   ret

2) Для передачи старшим битом вперёд при CPHA=0 и младшим битом вперёд при CPHA=1

Read_MISO:
   ld    temp, X
   cbr   temp, 0b10000000
   sbic  PIN_SPI, MISO_Line
   sbr   temp, 0b10000000
   st    X, temp
   ret

Для случая 1 в регистр X должен быть предварительно загружен адрес младшего используемого байта нашего сдвигового регистра, а для случая 2 — адрес старшего используемого байта этого регистра.

PIN_SPI — адрес регистра, отображающего состояния входов порта ввода/вывода, к которому подключена линия MISO,

MISO_Line — номер канала порта.

Здесь и далее, temp — просто некий вспомогательный регистр.

Кроме того, перед началом передачи, предназначенные для передачи биты, должны быть выровнены по старшему биту старшего используемого нами для организации сдвигового регистра байта при передаче старшим битом вперёд, и по младшему биту младшего используемого байта при передаче младшим битом вперёд. Картинка внизу иллюстрирует, что имеется ввиду на примере 12-ти битного пакета SPI (то есть, когда мы реализуем 12-ти битный сдвиговый регистр; при этом из наших зарезервированных четырёх байт используются только два).

Идём дальше. «Сдвиг», как видно по диаграммам, состоит для «Мастера» (впрочем как и для «Слэйва», но мы в этой статье занимаемся только «Мастером») из двух действий: это, во-первых, собственно сдвиг регистра и, во-вторых, установка очередного бита на шину MOSI.

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

Для контроллеров PIC:Для контроллеров AVR:

1) Сдвиг вправо

Shift_Right:
   movf   Hi_byte_Address,0
   movlw  FSR
   movf   Byte_Number,0
   movlw  Byte_Counter
   bcf    STATUS,C
Next_Shift_Right:
   rrf    INDF,1
   incf   FSR
   decfsz Byte_Counter
   goto   Next_Shift_Right
   movf   Hi_byte_Address,0
   movlw  FSR
   btfsc  STATUS,C
   bsf    INDF,7
   return

2) Сдвиг влево

Shift_Left:
   movf   Low_byte_Address,0
   movlw  FSR
   movf   Byte_Number,0
   movlw  Byte_Counter
   bcf    STATUS,C
Next_Shift_Left:
   rlf    INDF,1
   decf   FSR,1
   decfsz Byte_Counter
   goto   Next_Shift_Left
   movf   Low_byte_Address,0
   movlw  FSR
   btfsc  STATUS,C
   bsf    INDF,0
   return

1) Сдвиг вправо

Shift_Right:
   mov   XL, Hi_byte_Address
   mov   Byte_Counter, Byte_Number
   clc
Next_Shift_Right:
   ld    temp, X
   ror   temp
   st    X, temp
   inc   XL
   dec   Byte_Counter
   brne  Next_Shift_Right
   brcc  Shift_Right_Exit
   mov   XL, Hi_byte_Address
   ld    temp, X
   sbr   temp, 0b10000000
   st    X, temp
Shift_Right_Exit:
   ret

2) Сдвиг влево

Shift_Left:
   mov   XL, Low_byte_Address
   mov   Byte_Counter, Byte_Number
   clc
Next_Shift_Left:
   ld    temp, X
   rol   temp
   st    X, temp
   dec   XL
   dec   Byte_Counter
   brne  Next_Shift_Left
   brcc  Shift_Left_Exit
   mov   XL, Low_byte_Address
   ld    temp, X
   sbr   temp, 0b00000001
   st    X, temp
Shift_Left_Exit:
   ret

Low_byte_Address — адрес младшего байта нашего сдвигового регистра,

Hi_byte_Address — адрес его старшего байта,

Byte_Counter — счётчик обработанных байт,

Byte_Number — количество байт, используемых для организации сдвигового регистра.

Вот здесь можно посмотреть пример использования описанных функций.

Ну вот, со сдвигом регистра разобрались, теперь можно приступать и к этапу передачи, именуемому «Сдвиг». Как я ранее уже писал, — этот этап передачи состоит из двух действий: сдвиг регистра и установка очередного бита на шину MOSI. В коде это будет выглядеть так:

Для контроллеров PIC:Для контроллеров AVR:

1) Для передачи младшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   call   Shift_Right
   movf   Low_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 0
   bsf    PORT_SPI, MOSI_Line
   return

2) Для передачи старшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   call   Shift_Left
   movf   Hi_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 7
   bsf    PORT_SPI, MOSI_Line
   return

3) Для передачи младшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   movf   Low_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 0
   bsf    PORT_SPI, MOSI_Line
   call   Shift_Right
   return

4) Для передачи старшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   movf   Hi_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 7
   bsf    PORT_SPI, MOSI_Line
   call   Shift_Left
   return

1) Для передачи младшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   rcall  Shift_Right
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Low_byte_Address
   ld     temp2, X
   sbrc   temp2, 0
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   ret

2) Для передачи старшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   rcall  Shift_Left
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Hi_byte_Address
   ld     temp2, X
   sbrc   temp2, 7
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   ret

3) Для передачи младшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Low_byte_Address
   ld     temp2, X
   sbrc   temp2, 0
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   rcall  Shift_Right
   ret

4) Для передачи старшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Hi_byte_Address
   ld     temp2, X
   sbrc   temp2, 7
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   rcall  Shift_Left
   ret

Хотелось бы обратить внимание вот на что: поскольку при CPHA=0 по первому фронту на шине тактирования происходит чтение, то первый передаваемый бит в этот момент уже должен быть установлен на шине. Лучше устанавливать его сразу при загрузке передаваемых данных в регистр или это можно делать, например, по сигналу SS, в любом случае — он должен быть установлен ещё до начала тактирования. Для CPHA=1 никакие вспомогательные действия до начала тактирования не нужны.

И ещё одно. После обмена пакетами с помощью приведённых выше процедур изменится граница выравнивания данных. То есть, если посылаемые данные были выровнены к младшему биту младшего байта, то принятые будут выровнены к старшему биту старшего байта, а если посылаемые данные были выровнены к старшему биту старшего байта, то принятые будут выровнены к младшему биту младшего байта.

Далее давайте подумаем как управлять линией SCLK и какие при этом надо решить задачи.

Во-первых, перед началом передачи (а точнее как только сконфигурировали SPI), нужно установить на линии SCLK уровень, соответствующий выбранной полярности (CPOL).

Во-вторых, нужно как-то определять моменты переключения линии SCKL. Очевидно, что частота этих переключений определяет скорость передачи.

Надо сказать, что вообще-то интерфейс SPI не предъявляет каких-либо требований к стабильности частоты импульсов на SCLK, поэтому переключения можно формировать когда угодно, например, как выполнили все действия по установке, чтению и сдвигу данных — так и переключайте себе SCLK. Понижать скорость можно добавлением пустых циклов перед каждым переключением. Это первый метод для управления шиной SCLK.

Второй метод заключается в том, чтобы использовать для отсчёта моментов переключения таймеры. Тут вообще красота, — очень легко можно сделать переключения со стабильной частотой, которая полностью будет определяться параметрами таймера. Алгоритм примерно такой: как только выполнили все подготовительные действия — запускаете таймер, а далее по прерыванию от таймера инвертируете линию SCLK, сбрасываете и перезапускаете таймер.

Чтобы знать когда остановиться (когда передали все биты) — специальным счётчиком нужно отсчитывать количество переданных бит или количество переключений линии SCLK. Естественно лучше считать количество бит, поскольку переключений линии SCLK будет в два раза больше.

Код никакой писать не буду, — тут всё просто (если что — на форум).

Ну и последнее, что нам осталось — управлять линией SS. Естественно, что моменты, когда нужно начинать и заканчивать сеанс — это полностью ваше личное дело, специфичное для каждой конкретной задачи, так что вам и флаг в руки. Скажу только, что обычно с точки зрения мастера есть два варианта управления этой линией: 1) решение о переключении линии SS принимается независимо ни от чего (ручное управление) 2) Линия SS переключается в низкий уровень автоматически при загрузке новых данных в сдвиговый регистр, а назад в высокий — также автоматически после передачи всех бит пакета (автоматическое управление).

 

И ещё одно. Все приведённые выше коды предполагают, что используются пушпульные выходы. Если выходы предполагается сделать с открытым стоком, то нужно записать в соответствующие защёлки нули, и работать не с регистром порта, а с регистром выбора направления работы порта (тогда сигналы, формируемые контроллером на соответствующих выводах будут меняться не между нулём и единицей, а между нулём и Z-состоянием).

Источник: http://radiohlam.ru

Возможно, вам это будет интересно:

meandr.org

Учебный курс AVR. Работа с SPI модулем. Ч1


   Микроконтроллеры AVR имеют в своем составе модули, реализующие стандартные интерфейсы. Эти модули используются для обмена данными с различными периферийными устройствами, например, цифровыми датчиками, микросхемами памяти, ЦАП, АЦП, другими микроконтроллерами и так далее. В этой статье, на примере микроконтроллера atmega16, мы разберемся, как работать с модулем последовательного периферийного интерфейса или модулем SPI (serial peripheral interface).

   SPI представляет собой четырехпроводную синхронную шину, предназначенную для последовательного обмена данными между микросхемами. Интерфейс был разработан компанией Motorola, но в настоящий момент используется всеми производителями. Данный интерфейс отличают простота использования и реализации, высокая скорость обмена и малая дальность действия.
   При любом обмене данными по SPI одно из устройств является ведущим (Master’ом), а другое ведомым (Slave’ом). Обычно (но не всегда) в роли ведущего выступает микроконтроллер. Ведущий переводит периферийное устройство в активное состояние и формирует тактовый сигнал и данные. В ответ ведомое устройство передает ведущему свои данные. Передача данных в обе стороны происходит синхронно с тактовым сигналом.
   Физически SPI реализуется на основе сдвигового регистра, который выполняет и функцию передатчика, и функцию приемника.
   Принцип обмена данными по SPI проиллюстрирован на следующих картинках.

 

   Сигналы, используемые данным интерфейсом, имеют следующее назначение: 


MOSI — Master Output / Slave Input. Выход ведущего / вход ведомого. Служит для передачи данных от ведущего устройства к ведомому.
MISO
– Master Input / Slave Output. Вход ведущего / выход ведомого. Служит для передачи данных от ведомого устройства к ведущему.
SLK — Serial Clock. Сигнал синхронизации. Служит для передачи тактового сигнала всем ведомым устройствам.
SS — Slave Select. Выбор ведомого. Служит для выбора ведомого устройства.

   Производители микросхем часто используют другие названия для этих сигналов. Альтернативные варианты могут быть такими:

MOSI – DO, SDO, DOUT.
MISO – DI, SDI, DIN.
SCK – CLK, SCLK.
SS – CS, SYNC.

   Типовая схема соединения двух устройств по SPI выглядит так.

 

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

 

   Исключение составляет каскадная схема соединения по SPI. При таком подключении сдвиговые регистры устройств образуют один большой регистр, и количество линий SPI остается равным 4-ем. Правда, такое подключение поддерживают далеко не все микросхемы.

 

   Также возможен сокращенный вариант схемы подключения, когда линия MOSI или MISO не используется. То есть передача данных осуществляется только в одну сторону. Такие схема, например, используются при подключении к микроконтроллеру внешних микросхем ЦАП и АЦП.

 

   Протокол обмена по SPI аналогичен логике работы сдвигового регистра и заключается в последовательном побитном выводе/вводе данных по определенным фронтам тактового сигнала. Установка данных и выборка осуществляется по противоположным фронтам тактового сигнала.
   Спецификация SPI предусматривает 4 режима передачи данных, которые отличаются между собой соотношением фазы и полярности тактового сигнала и передаваемых данных.
   Эти режимы описываются двумя параметрами:

CPOL – clock polarity. Полярность тактового сигнала — определяет исходный уровень сигнала синхронизации
CPHA – clock phase. Фаза тактового сигнала — определяет последовательность установки и выборки данных.

   Рисунки ниже иллюстрируют все четыре режима обмена SPI.

   SPI mode 0: CPOL = 0, CPHA=0. Тактовый сигнал начинается с уровня логического нуля. Защелкивание данных выполняется по нарастающему фронту. Смена данных происходит по падающему фронту. Моменты защелкивание данных показаны на рисунках стрелочками

 


  SPI mode 1: CPOL = 0, CPHA=1. Тактовый сигнал начинается с уровня логического нуля. Смена данных происходит по нарастающему фронту. Защелкивание данных выполняется по падающему фронту.

 


   SPI mode 2: CPOL = 1, CPHA=0. Тактовый сигнал начинается с уровня логической единицы. Защелкивание данных выполняется по падающему фронту. Смена данных выполняется по нарастающему фронту тактового сигнала.

 


   SPI mode 3: CPOL = 1, CPHA=1. Тактовый сигнал начинается с уровня логической единицы. Смена данных выполняется по падающему фронту тактового сигнала. Защелкивание данных выполняется по нарастающему фронту.

 


   Современные микроконтроллеры поддерживают все четыре режима работы SPI.
   Стоит отметить, что передача данных по SPI может происходить не только старшим битом вперед, но и младшим. А количество байт передаваемых за время удержания сигнала выбора (SS) ничем не ограничено и определяется спецификацией используемого ведомого устройства. Также в спецификации на ведомое устройство указываются поддерживаемые режимы работы SPI, максимальная частота тактового сигнала, содержимое передаваемых или принимаемых данных.

   Учебный курс AVR. Работа с SPI. Запись и чтение данных. Ч2
   Учебный курс AVR. Работа с SPI. Управление сдвиговым регистром. Ч3

chipenable.ru

Программная реализация ведущего шины SPI (подробный разбор и некоторые процедуры на асме для PIC и AVR)

В этой статье рассматривается пример программной реализации на микроконтроллерах PIC и AVR функций ведущего шины SPI для разных режимов (mode0, mode1, mode2, mode3). Чтобы понимать что происходит — для начала, как всегда, читаем теорию (что такое SPI и как он работает). Если с теорией разобрались, тогда можно приступать к практической реализации.

Итак, что должен уметь делать SPI-мастер? Собственно говоря, всего четыре вещи:

  1. читать с шины MISO нужное количество бит;
  2. передавать по шине MOSI нужное количество бит;
  3. формировать на шине SCLK нужное количество импульсов, соблюдая правильную полярность;
  4. управлять шиной SS.

Как вы знаете (вы же с теорией знакомы?) — чтение и установку данных и «Мастер», и «Слэйв» производят по противоположным фронтам сигнала тактирования, причём для приёма и передачи может использоваться один и тот же сдвиговый регистр. Для наглядности давайте нарисуем для всех четырёх режимов диаграммы сигналов, соответствующие передаче по SPI двух бит, а уже по ним распишем действия контроллера:

Диаграммы нарисованы для случая, когда передача осуществляется младшим битом вперёд.

Биты, не выделенные жирным, — не имеют для нас значения и могут быть на следующем этапе перезаписаны (это, например, те биты, которые мы уже установили на шину данных, или, наоборот, — уже считали с шины данных).

По диаграммам видно, что в результате обмена данными сдвиговые регистры «Мастера» и «Слэйва» поменялись содержимым (помните, в теоретической части я писал, что у SPI есть такая особенность, — для приёма и передачи можно использовать один и тот же регистр).

Прежде чем переходить к написанию кода, — давайте ещё подумаем вот о чём. Архитектура контроллеров у нас 8-ми битная, а для SPI часто может потребоваться бОльшая размерность сдвигового регистра.

Пусть в нашем примере размер сдвигового регистра можно будет выбрать от 1-го до 32-х бит. То есть максимально под сдвиговый регистр мы будем выделять 4 байта (4 восьмибитных регистра, расположенных в памяти так, как на рисунке справа). Для случаев, когда размер регистра превышает 1 байт (то есть равен 2, 3 или 4 байта) мы будем программно имитировать работу с несколькими 8-ми битными регистрами как с одним большим. Используемые для организации сдвигового регистра восьмибитные регистры в дальнейшем будем называть просто байтами, чтобы не путаться.

Что представляет собой чтение с точки зрения «Мастера»? Да ничего особенного, — нужно просто прочитать сигнал на входе (MISO) и записать его в младший или старший бит сдвигового регистра (в зависимости от того — младшим или старшим битом вперёд передаются данные и от значения CPHA). Вот так это выглядит в коде:

Для контроллеров PICДля контроллеров AVR

1) Для передачи младшим битом вперёд при CPHA=0 и старшим битом вперёд при CPHA=1

Read_MISO:
   bcf   INDF, 0
   btfsc PORT_SPI, MISO_Line
   bsf   INDF, 0
   return

Read_MISO: bcf INDF, 0 btfsc PORT_SPI, MISO_Line bsf INDF, 0 return

2) Для передачи старшим битом вперёд при CPHA=0 и младшим битом вперёд при CPHA=1

Read_MISO:
   bcf   INDF, 7
   btfsc PORT_SPI, MISO_Line
   bsf   INDF, 7
   return

Read_MISO: bcf INDF, 7 btfsc PORT_SPI, MISO_Line bsf INDF, 7 return

Для случая 1 в регистр FSR должен быть предварительно загружен адрес младшего используемого байта нашего сдвигового регистра, а для случая 2 — адрес старшего используемого байта этого регистра.

PORT_SPI — адрес порта ввода /вывода, к которому подключена линия MISO,

MISO_Line — номер канала порта.

1) Для передачи младшим битом вперёд при CPHA=0 и старшим битом вперёд при CPHA=1

Read_MISO:
   ld    temp, X
   cbr   temp, 0b00000001
   sbic  PIN_SPI, MISO_Line
   sbr   temp, 0b00000001
   st    X, temp
   ret

Read_MISO: ld temp, X cbr temp, 0b00000001 sbic PIN_SPI, MISO_Line sbr temp, 0b00000001 st X, temp ret

2) Для передачи старшим битом вперёд при CPHA=0 и младшим битом вперёд при CPHA=1

Read_MISO:
   ld    temp, X
   cbr   temp, 0b10000000
   sbic  PIN_SPI, MISO_Line
   sbr   temp, 0b10000000
   st    X, temp
   ret

Read_MISO: ld temp, X cbr temp, 0b10000000 sbic PIN_SPI, MISO_Line sbr temp, 0b10000000 st X, temp ret

Для случая 1 в регистр X должен быть предварительно загружен адрес младшего используемого байта нашего сдвигового регистра, а для случая 2 — адрес старшего используемого байта этого регистра.

PIN_SPI — адрес регистра, отображающего состояния входов порта ввода/вывода, к которому подключена линия MISO,

MISO_Line — номер канала порта.

Здесь и далее, temp — просто некий вспомогательный регистр.

Кроме того, перед началом передачи, предназначенные для передачи биты, должны быть выровнены по старшему биту старшего используемого нами для организации сдвигового регистра байта при передаче старшим битом вперёд, и по младшему биту младшего используемого байта при передаче младшим битом вперёд. Картинка внизу иллюстрирует, что имеется ввиду на примере 12-ти битного пакета SPI (то есть, когда мы реализуем 12-ти битный сдвиговый регистр; при этом из наших зарезервированных четырёх байт используются только два).

Идём дальше. «Сдвиг», как видно по диаграммам, состоит для «Мастера» (впрочем как и для «Слэйва», но мы в этой статье занимаемся только «Мастером») из двух действий: это,
во-первых, собственно сдвиг регистра и, во-вторых, установка очередного бита на шину MOSI.

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

Для контроллеров PICДля контроллеров AVR

1) Сдвиг вправо

Shift_Right:
   movf   Hi_byte_Address,0
   movlw  FSR
   movf   Byte_Number,0
   movlw  Byte_Counter
   bcf    STATUS,C
Next_Shift_Right:
   rrf    INDF,1
   incf   FSR
   decfsz Byte_Counter
   goto   Next_Shift_Right
   movf   Hi_byte_Address,0
   movlw  FSR
   btfsc  STATUS,C
   bsf    INDF,7
   return

Shift_Right: movf Hi_byte_Address,0 movlw FSR movf Byte_Number,0 movlw Byte_Counter bcf STATUS,C Next_Shift_Right: rrf INDF,1 incf FSR decfsz Byte_Counter goto Next_Shift_Right movf Hi_byte_Address,0 movlw FSR btfsc STATUS,C bsf INDF,7 return

2) Сдвиг влево

Shift_Left:
   movf   Low_byte_Address,0
   movlw  FSR
   movf   Byte_Number,0
   movlw  Byte_Counter
   bcf    STATUS,C
Next_Shift_Left:
   rlf    INDF,1
   decf   FSR,1
   decfsz Byte_Counter
   goto   Next_Shift_Left
   movf   Low_byte_Address,0
   movlw  FSR
   btfsc  STATUS,C
   bsf    INDF,0
   return

Shift_Left: movf Low_byte_Address,0 movlw FSR movf Byte_Number,0 movlw Byte_Counter bcf STATUS,C Next_Shift_Left: rlf INDF,1 decf FSR,1 decfsz Byte_Counter goto Next_Shift_Left movf Low_byte_Address,0 movlw FSR btfsc STATUS,C bsf INDF,0 return

1) Сдвиг вправо

Shift_Right:
   mov   XL, Hi_byte_Address
   mov   Byte_Counter, Byte_Number
   clc
Next_Shift_Right:
   ld    temp, X
   ror   temp
   st    X, temp
   inc   XL
   dec   Byte_Counter
   brne  Next_Shift_Right
   brcc  Shift_Right_Exit
   mov   XL, Hi_byte_Address
   ld    temp, X
   sbr   temp, 0b10000000
   st    X, temp
Shift_Right_Exit:
   ret

Shift_Right: mov XL, Hi_byte_Address mov Byte_Counter, Byte_Number clc Next_Shift_Right: ld temp, X ror temp st X, temp inc XL dec Byte_Counter brne Next_Shift_Right brcc Shift_Right_Exit mov XL, Hi_byte_Address ld temp, X sbr temp, 0b10000000 st X, temp Shift_Right_Exit: ret

2) Сдвиг влево

Shift_Left:
   mov   XL, Low_byte_Address
   mov   Byte_Counter, Byte_Number
   clc
Next_Shift_Left:
   ld    temp, X
   rol   temp
   st    X, temp
   dec   XL
   dec   Byte_Counter
   brne  Next_Shift_Left
   brcc  Shift_Left_Exit
   mov   XL, Low_byte_Address
   ld    temp, X
   sbr   temp, 0b00000001
   st    X, temp
Shift_Left_Exit:
   ret

Shift_Left: mov XL, Low_byte_Address mov Byte_Counter, Byte_Number clc Next_Shift_Left: ld temp, X rol temp st X, temp dec XL dec Byte_Counter brne Next_Shift_Left brcc Shift_Left_Exit mov XL, Low_byte_Address ld temp, X sbr temp, 0b00000001 st X, temp Shift_Left_Exit: ret

  1. Low_byte_Address — адрес младшего байта нашего сдвигового регистра,
  2. Hi_byte_Address — адрес его старшего байта,
  3. Byte_Counter — счётчик обработанных байт,
  4. Byte_Number — количество байт, используемых для организации сдвигового регистра.

Ну вот, со сдвигом регистра разобрались, теперь можно приступать и к этапу передачи, именуемому «Сдвиг». Как я ранее уже писал, — этот этап передачи состоит из двух действий: сдвиг регистра и установка очередного бита на шину MOSI. В коде это будет выглядеть так:

Для контроллеров PICДля контроллеров AVR

1) Для передачи младшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   call   Shift_Right
   movf   Low_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 0
   bsf    PORT_SPI, MOSI_Line
   return

Shift_&_Set_MOSI: call Shift_Right movf Low_byte_Address,0 movwf FSR bcf PORT_SPI, MOSI_Line btfsc INDF, 0 bsf PORT_SPI, MOSI_Line return

2) Для передачи старшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   call   Shift_Left
   movf   Hi_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 7
   bsf    PORT_SPI, MOSI_Line
   return

Shift_&_Set_MOSI: call Shift_Left movf Hi_byte_Address,0 movwf FSR bcf PORT_SPI, MOSI_Line btfsc INDF, 7 bsf PORT_SPI, MOSI_Line return

3) Для передачи младшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   movf   Low_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 0
   bsf    PORT_SPI, MOSI_Line
   call   Shift_Right
   return

Shift_&_Set_MOSI: movf Low_byte_Address,0 movwf FSR bcf PORT_SPI, MOSI_Line btfsc INDF, 0 bsf PORT_SPI, MOSI_Line call Shift_Right return

4) Для передачи старшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   movf   Hi_byte_Address,0
   movwf  FSR
   bcf    PORT_SPI, MOSI_Line
   btfsc  INDF, 7
   bsf    PORT_SPI, MOSI_Line
   call   Shift_Left
   return

Shift_&_Set_MOSI: movf Hi_byte_Address,0 movwf FSR bcf PORT_SPI, MOSI_Line btfsc INDF, 7 bsf PORT_SPI, MOSI_Line call Shift_Left return

1) Для передачи младшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   rcall  Shift_Right
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Low_byte_Address
   ld     temp2, X
   sbrc   temp2, 0
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   ret

Shift_&_Set_MOSI: rcall Shift_Right in temp1, PORT_SPI cbr temp1, (1 << MOSI_Line) mov XL, Low_byte_Address ld temp2, X sbrc temp2, 0 sbr temp1, (1 << MOSI_Line) out PORT_SPI, temp1 ret

2) Для передачи старшим битом вперёд при CPHA=0

Shift_&_Set_MOSI:
   rcall  Shift_Left
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Hi_byte_Address
   ld     temp2, X
   sbrc   temp2, 7
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   ret

Shift_&_Set_MOSI: rcall Shift_Left in temp1, PORT_SPI cbr temp1, (1 << MOSI_Line) mov XL, Hi_byte_Address ld temp2, X sbrc temp2, 7 sbr temp1, (1 << MOSI_Line) out PORT_SPI, temp1 ret

3) Для передачи младшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Low_byte_Address
   ld     temp2, X
   sbrc   temp2, 0
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   rcall  Shift_Right
   ret

Shift_&_Set_MOSI: in temp1, PORT_SPI cbr temp1, (1 << MOSI_Line) mov XL, Low_byte_Address ld temp2, X sbrc temp2, 0 sbr temp1, (1 << MOSI_Line) out PORT_SPI, temp1 rcall Shift_Right ret

4) Для передачи старшим битом вперёд при CPHA=1

Shift_&_Set_MOSI:
   in     temp1, PORT_SPI
   cbr    temp1, (1 << MOSI_Line)
   mov    XL, Hi_byte_Address
   ld     temp2, X
   sbrc   temp2, 7
   sbr    temp1, (1 << MOSI_Line)
   out    PORT_SPI, temp1
   rcall  Shift_Left
   ret

Shift_&_Set_MOSI: in temp1, PORT_SPI cbr temp1, (1 << MOSI_Line) mov XL, Hi_byte_Address ld temp2, X sbrc temp2, 7 sbr temp1, (1 << MOSI_Line) out PORT_SPI, temp1 rcall Shift_Left ret

Хотелось бы обратить внимание вот на что: поскольку при CPHA=0 по первому фронту на шине тактирования происходит чтение, то первый передаваемый бит в этот момент уже должен быть установлен на шине. Лучше устанавливать его сразу при загрузке передаваемых данных в регистр или это можно делать, например, по сигналу SS, в любом случае — он должен быть установлен ещё до начала тактирования. Для CPHA=1 никакие вспомогательные действия до начала тактирования не нужны.

И ещё одно. После обмена пакетами с помощью приведённых выше процедур изменится граница выравнивания данных. То есть, если посылаемые данные были выровнены к младшему биту младшего байта, то принятые будут выровнены к старшему биту старшего байта, а если посылаемые данные были выровнены к старшему биту старшего байта, то принятые будут выровнены к младшему биту младшего байта.

Далее давайте подумаем как управлять линией SCLK и какие при этом надо решить задачи.

Во-первых, перед началом передачи (а точнее как только сконфигурировали SPI), нужно установить на линии SCLK уровень, соответствующий выбранной полярности (CPOL).

Во-вторых, нужно как-то определять моменты переключения линии SCKL. Очевидно, что частота этих переключений определяет скорость передачи.

Надо сказать, что вообще-то интерфейс SPI не предъявляет каких-либо требований к стабильности частоты импульсов на SCLK, поэтому переключения можно формировать когда угодно, например, как выполнили все действия по установке, чтению и сдвигу данных — так и переключайте себе SCLK. Понижать скорость можно добавлением пустых циклов перед каждым переключением. Это первый метод для управления шиной SCLK.

Второй метод заключается в том, чтобы использовать для отсчёта моментов переключения таймеры. Тут вообще красота, — очень легко можно сделать переключения со стабильной частотой, которая полностью будет определяться параметрами таймера. Алгоритм примерно такой: как только выполнили все подготовительные действия — запускаете таймер, а далее по прерыванию от таймера инвертируете линию SCLK, сбрасываете и перезапускаете таймер.

Чтобы знать когда остановиться (когда передали все биты) — специальным счётчиком нужно отсчитывать количество переданных бит или количество переключений линии SCLK. Естественно лучше считать количество бит, поскольку переключений линии SCLK будет в два раза больше.

Код никакой писать не буду, — тут всё просто (если что — на форум).

Ну и последнее, что нам осталось — управлять линией SS. Естественно, что моменты, когда нужно начинать и заканчивать сеанс — это полностью ваше личное дело, специфичное для каждой конкретной задачи, так что вам и флаг в руки. Скажу только, что обычно с точки зрения мастера есть два варианта управления этой линией:

  1. решение о переключении линии SS принимается независимо ни от чего (ручное управление)
  2. линия SS переключается в низкий уровень автоматически при загрузке новых данных в сдвиговый регистр, а назад в высокий — также автоматически после
    передачи всех бит пакета (автоматическое управление).

И ещё одно. Все приведённые выше коды предполагают, что используются пушпульные выходы. Если выходы предполагается сделать с открытым стоком, то нужно записать в соответствующие защёлки нули, и работать не с регистром порта, а с регистром выбора направления работы порта (тогда сигналы, формируемые контроллером на соответствующих выводах, будут меняться не между нулём и единицей, а между нулём и Z-состоянием).

Вот здесь можно посмотреть пример использования описанных функций.

radiohlam.ru

SPI интерфейс. Часть 1. Конфигурация в Bascom-AVR — Полезная информация — AVR project.ru

 Интерфейс SPI, пожалуй, самый распространенный интерфейс коммуникации между микроконтроллерами и периферией. Он широко распространился за счет универсальности, простоты реализации и высокой скорости передачи данных по шине. В каждом микроконтроллере AVR имеется поддержка интерфейса SPI, более того – эта шина используется для внутрисхемной прошивки микроконтроллера (тот самый ISP). Поэтому пришло время подобраться к этому интерфейсу поближе и разобраться с принципом работы в Bascom-AVR.

 Главной составляющей интерфейса SPI является обычный сдвиговый регистр, так что если разобрались с принципом работы сдвигового регистра 74hc595, то понять, как работает передача данных в SPI будет как два пальца обоссвальт =)


Пример подключения одного подчиненного устройства к ведущему:

 Во время передачи данных, ведущий начинает побитно выдвигать данные на вывод MOSI, который соединен с входами MOSI ведомых устройств. В это время на выводе SCLK генерируются импульсы, которые задвигают данные в регистр. Чтобы подчиненное устройство знало, что работают именно с ним, контроллер должен просадит его линию SS к земле. Прием данных из подчиненного происходит по лини MISO и также синхронизировано с сигналом на SCLK (именно за счет независимых линий приема/передачи достигается большая скорость обмена информацией по шине SPI).


 Также этот протокол позволяет подключать практически неограниченное количество подчиненных устройств, за счет простой адресации к каждому из них – активным будет то подчиненное устройство, на выводе SS которого находится низкий уровень. Схема подключения в таком случае будет выглядеть так:

 Конфигурирование SPI в Bascom-AVR
 Тут можно пойти двумя путями: использовать аппаратный SPI с жесткой привязкой к определённым портам микроконтроллера или сконфигурировать программный, со своим назначением портов. Кстати, если верить отзывам, аппаратная реализации этого интерфейса у Atmel не особа удачна и лучше юзать программный SPI. Если есть знающие люди – прошу прокомментировать. 

Синтаксис для конфигурации программного SPI

CONFIG SPI = SOFT, DIN = PIN, DOUT = PIN , SS = PIN|NONE, CLOCK = PIN , SPIIN=value , MODE=mode

Синтаксис для конфигурации аппаратного SPI
CONFIG SPI = HARD, INTERRUPT=ON|OFF, DATA ORDER = LSB|MSB , MASTER = YES|NO , POLARITY = HIGH|LOW , PHASE = 0|1, CLOCKRATE = 4|16|64|128 , NOSS=1|0 , SPIIN=value



описание параметров:

SPI: Soft/hard тут вроде все понятно, выбираем программный или аппаратный SPI


DIN: Вход данных, альтернативное обозначения линии MISO


DOUT: Выход данных, альтернативное название линии MOSI


SS: Порт отвечающий за выбор ведомого, если не требуется использование можно ставить none (если выбор ведомого будет производится в ручную)


CLOCK: Выход для синхронизирующих импульсов, альтернативное название линии SCLK

MODE: Число от 0 до 3, определяющее режим работы программного SPI. О ней чуть позже. Эта настройка поддерживается только в новых версиях компилятора 2.0.х.х


DATA ORDER: Этим параметром указывается в каком порядке в регистр будут передаваться данные (MSB – старший бит будет идти первым, LSB – младший бит идет первым)


MASTER: этим параметром устанавливается будет ли устройство ведущим на шине SPI


POLARITY: параметром указывается по какому уровню на линии SCLK в регистр будут записываться данные


PHASE:  какая-то непонятная фигня, смело ставим 0


CLOCKRATE: здесь устанавливаем с какой частотой будет работать шина SPI, скорость будет устанавливаться выбором знаменателя из чисел 4|16|64|128 на который будет делиться частота работы микроконтроллера (пример: при частоте кварца 8МГц, CLOCKRATE = 4; скорость работы шины будет составлять 2МГц)


NOSS: отключает линию SS в случае если она не используется. Это необходимо например, когда к ведущему подключается более одного ведомого устройства. Для этого ставим NOSS=1 (линия SS теперь не будет автоматически прижиматься к 0), а в качестве SS1, SS2, SSn устанавливаем свои пины для работы с ведомыми устройствами. И когда нужно будет пообщаться с каким-либо устройством, вручную ставим на его линии SS низкий уровень. После окончания общения незабываем снова ставить высокий уровень.


INTERRUPT: включаем/отключаем прерывания от SPI


SPIIN: значение которое отправляем ведомому устройству для его инициализации обычно это значение 0 (стоит по умолчанию), но может понадобиться отправить свое значение.


По умолчанию настройки аппаратной шины SPI принимают следующие параметры:


DATA ORDER = MSB, POLARITY = HIGH, MASTER = YES, PHASE = 0, CLOCKRATE = 4


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


Пример конфига для использования программного SPI:

 

Config SPI = SOFT, DIN = PINB.0 , DOUT = PORTB.1, SS = PORTB.2, CLOCK = PORTB.3
SPIINIT  ‘инициализируем SPI


 Обратите внимание, что DIN это вход данных и поэтому при конфигурировании этой линии необходимо писать PIN, а не PORT.

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


На этом сухой теории пока хватит, чуть позже попробуем покидаться данными между микроконтроллерами. Оставайтесь на линии 😉

avrproject.ru

AVR. Учебный курс. Трактат о программаторах

Программа для микроконтроллера пишется на любом удобном языке программирования, компилируется в бинарный файл (или файл формата intel HEX) и заливается в микроконтроллер посредством программатора.
 

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

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

Программаторы бывают разные под разные семейства контроллеров существуют свои программаторы. Впрочем, бывают и универсальные. Более того, даже ту же простейшую AVR’ку можно прошить несколькими способами:
 

Внутрисхемное программирование (ISP)
Самый популярный способ прошивать современные контроллеры. Внутрисхемным данный метод называется потому, что микроконтроллер в этот момент находится в схеме целевого устройства — он может быть даже наглухо туда впаян. Для нужд программатора в этом случае выделяется несколько выводов контроллера (обычно 3..5 в зависимости от контроллера).


К этим выводам подключается прошивающий шнур программатора и происходит заливка прошивки. После чего шнур отключается и контроллер начинает работу.
У AVR прошивка заливается по интерфейсу SPI и для работы программатора нужно четыре линии и питание (достаточно только земли, чтобы уравнять потенциалы земель программатора и устройства):
 

  • MISO — данные идущие от контроллера (Master-Input/Slave-Output)
  • MOSI — данные идущие в контроллер (Master-Output/Slave-Input)
  • SCK — тактовые импульсы интерфейса SPI
  • RESET — сигналом на RESET программатор вводит контроллер в режим программирования
  • GND — земля

Сам же разъем внутрисхемного программирования представляет собой всего лишь несколько штырьков. Лишь бы на него было удобно надеть разъем. Конфигурация его может быть любой, как тебе удобней.
Однако все же есть один популярный стандарт:

 

Для внутрисхемной прошивки контроллеров AVR существует не один десяток разнообразных программаторов. Отличаются они в первую очередь по скорости работы и типу подключения к компьютеру (COM/LPT/USB). А также бывают безмозглыми или со своим управляющим контроллером.
 

Безмозглые программаторы, как правило, дешевые, очень простые в изготовлении и наладке. Но при этом обычно работают исключительно через архаичные COM или LPT порты. Которые найти в современном компьютере целая проблема. А еще требуют прямого доступа к портам, что уже в Windows XP может быть проблемой. Плюс бывает зависимость от тактовой частоты процессора компьютера.
 

Так что твой 3ГГЦ-овый десятиядерный монстр может пролететь, как фанера над Парижем.
 

Идеальный компьютер для работы с такими программаторами это какой-нибудь PIII-800Mhz с Windows98…XP.
Вот очень краткая подборка проверенных лично безмозглых программаторов:
 

  • Программатор Громова.
    Простейшая схема, работает через оболочку UniProf(удобнейшая вещь!!!), но имеет ряд проблем. В частности тут COM порт используется нетрадиционно и на некоторых материнках может не заработать. А еще на быстрых компах часто не работает. Да, через адаптер USB-COM эта схема работать не будет. По причине извратности подхода 🙂
  • STK200
    Надежная и дубовая, как кувалда, схема. Работает через LPT порт. Поддерживается многими программами, например avrdude. Требует прямого доступа к порту со стороны операционной системы и наличие LPT порта.
  • FTBB-PROG.
    Очень надежный и быстрый программатор работающий через USB, причем безо всяких извратов. C драйверами под разные операционные системы. И мощной оболочкой avrdude. Недостаток один — содержит редкую и дорогую микросхему FTDI, да в таком мелком корпусе, что запаять ее без меткого глаза, твердой руки и большого опыта пайки весьма сложно. Шаг выводов около 0.3мм. Данный программатор встроен в демоплаты Pinboard

Программаторы с управляющим контроллером лишены многих проблем безмозглых. Они без особых проблем работают через USB. А если собраны на COM порт, то без извращенских методик работы с данными — как честный COM порт. Так что адаптеры COM-USB работают на ура. И детали подобрать можно покрупней, чтобы легче было паять. Но у этих программаторов есть другая проблема — для того чтобы сделать такой программатор нужен другой программатор, чтобы прошить ему управляющий контроллер. Проблема курицы и яйца. Широко получили распространение такие программаторы как:

  • USBASP
  • AVRDOPER
  • AVR910 Protoss

Внутрисхемное программирование, несмотря на все его удобства, имеет ряд ограничений.
Микроконтроллер должен быть запущен, иначе он не сможет ответить на сигнал программатора. Поэтому если неправильно выставить биты конфигурации (FUSE), например, переключить на внешний кварцевый резонатор, а сам кварц не поставить. То контроллер не сможет запуститься и прошить его внутрисхемно будет уже нельзя. По крайней мере до тех пор пока МК не будет запущен.
Также в битах конфигурации можно отключить режим внутрисхемной прошивки или преваратить вывод RESET в обычный порт ввода-вывода (это справедливо для малых МК, у которых RESET совмещен с портом). Такое действо тоже обрубает программирование по ISP.
 

Параллельное высоковольтное программирование
Обычно применяется на поточном производстве при массовой (сотни штук) прошивке чипов в программаторе перед запайкой их в устройство.
 

Параллельное программирование во много раз быстрей последовательного (ISP), но требует подачи на RESET напряжения в 12 вольт. А также для параллельной зашивки требуется уже не 3 линии данных, а восемь + линии управления. Для программирования в этом режиме микроконтроллер вставляется в панельку программатора, а после прошивки переставляется в целевое устройство.
 

Для радиолюбительской практики он особо не нужен, т.к. ISP программатор решает 99% насущных задач, но тем не менее параллельный программатор может пригодиться. Например, если в результате ошибочных действий были неправильно выставлены FUSE биты и был отрублен режим ISP. Параллельному программатору на настройку FUSE плевать с высокой колокольни. Плюс некоторые старые модели микроконтроллеров могут прошиваться только высоковольтным программатором.
Из параллельных программаторов для AVR на ум приходит только:

  • HVProg от ElmChan
  • Paraprog
  • DerHammer

 

А также есть универсальные вроде TurboProg 6, BeeProg, ChipProg++, Fiton которые могут прошивать огромное количество разных микроконтроллеров, но и стоят неслабо. Тысяч по 10-15. Нужны в основном только ремонтникам, т.к. когда не знаешь что тебе завтра притащат на ремонт надо быть готовым ко всему.
 

Прошивка через JTAG
Вообще JTAG это отладочный интерфейс. Он позволяет пошагово выполнять твою программу прям в кристалле. Но с его помощью можно и программу прошить, или FUSE биты вставить. К сожалению JTAG доступен далеко не во всех микроконтроллерах, только в старших моделях в 40ногих микроконтроллерах. Начиная с Atmega16.
 

Компания AVR продает фирменный комплект JTAG ICEII для работы с микроконтроллерами по JTAG, но стоит он (как и любой профессиональный инструмент) недешево. Около 10-15тыр. Также есть первая модель JTAG ICE. Ее можно легко изготовить самому, а еще она встроена в мою демоплату Pinboard.

 

Прошивка через Bootloader
Многие микроконтроллеры AVR имеют режим самопрошивки. Т.е. в микроконтроллер изначально, любым указанным выше способом, зашивается спец программка — bootloader. Дальше для перешивки программатор не нужен. Достаточно выполнить сброс микроконтроллера и подать ему специальный сигнал. После чего он входит в режим программирования и через обычный последовательный интерфейс в него заливается прошивка. Подробней описано в статье посвященной бутлоадеру.
Достоинство этого метода еще и в том, что работая через бутлоадер очень сложно закосячить микроконтроллер настолько, что он не будет отвечать вообще. Т.к. настройки FUSE для бутлоадера недоступны.
 

Бутлоадер также прошит по умолчанию в главный контроллер демоплаты Pinboard чтобы облегчить и обезопасить первые шаги на пути освоения микроконтроллеров.
 

Pinboard II
Прошивка AVR с помощью демоплаты Pinboard II (для Pinboard 1.1 все похоже)

 

easyelectronics.ru

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *