Курс AVR123.nm.ru


Electronic Banner Exchange (ElBE)
 


       
 



Задача - упражнение 12

Краткий курс - Самоучитель
Микроконтроллер AVR - быстрый старт с нуля

 

Программная реализация последовательной передачи данных

н
а примере управления PLL синтезатором частоты LMX2316


Пример использования синтезатора в самодельной
радиостанции FM-2006 на диапазоны 144 и 435 Мгц

 

Надеюсь вы читали курс с самого начала и делали то что предлагалось.
 

 

поиск   GOOGLE   по ключевым
словам в Кратком Курсе AVR

Поиск  на  этой  странице  -  Ctrl+F

 


Книги и учебники по радиоэлектронике и микроконтроллерам  там

Как и чем прошить AVR  на странице 7 курса

Как согласовать радиочастотные устройства, сделать
антенну или усилитель вы можете прочитать там

 

 

 

Цель задачи:  


1) Научиться понимать диаграммы последовательной передачи
информации публикуемые в даташитах микросхем с последовательным интерфейсом управления и микроконтроллеров. 

2) Научиться последовательно передавать данные. Учится будем на
примере  управления работой синтезаторов LMX2316 (LMX2306, LMX2326) 

 

Напоминаю: Последовательная  передача и прием данных по
аппаратному SPI  ATmaga16  рассматривалась уже в  задаче 7



     
 

Поиск по материалам Краткого курса AVR

1) Используйте поиск Windows в папке где сохраните курс, для того чтобы найти нужную вам информацию. Вы можете скачать курс одним архивом.

Для этого кликните правой кнопкой мыши (ПКМ) по папке где сохранен у вас курс и выбирете "найти..." в открывшимся диалоге поиска введите интересующее вас слово во второе поле. 

Например: вы вводите слово "прерывания" и запускаете поиск, в результате получите список файлов в которых найдено это слово. 

Открывайте эти файлы и вводите слово "прерывания" в поиск по тексту файла - через меню "Правка" - "Найти на этой странице" или комбинация Ctrl+F.

2) Вы можете воспользоваться поиском GOOGLE по краткому курсу - пожалуйста добавьте эту ссылку в "избранное" и пользуйтесь.

 
     

 

Для выполнения задачи вам нужно:  


1) Прочитать краткий курс по AVR с начала, проделать то что там
предлагается, знать материал курса и предыдущих задач

2) Знать материалы - устройство AVR  и  Си для МК 

3) Нужен компилятор CVAVR и симулятор VMLAB - скачать эти небольшие, полезные программы можно по ссылкам на заглавной странице курса.

4) ДатаШиты на микроконтроллер ATmega16  и синтезатор LMX2316

5) Свободное время и желание


 

Приступим ...

 

Что такое синтезатор ФАПЧ - PLL ?

Как работает синтезатор частоты ? 



ФАПЧ - это фазовая автоподстройка частоты, а по аглицки - PLL или "фэйз лок луп" дословно - контур захвата фазы. Вот структура синтезатора LMX2316 

 

OSCin - на этот вход подается опорная частота, обычно с генератора частота колебаний которого стабилизирована кварцем или более точного - пусть в нашем примере это будет 10245 КГц.  Эту же частоту мы будем использовать для тактирования микроконтроллера который будет управлять синтезатором.

Fin - это синтезируемая частота с выхода VCO (по русски ГУН - генератор частота которого зависит от управляющего напряжения - на рисунке его нет)

CPo - это выходной сигнал синтезатора - напряжение в пределах питания синтезатора. Это напряжение управляет частотой VCO.

FLo - это сигнал показывающий "захват фазы" или "совпадение фаз" и означает что частота на выходе VCO (она же на входе Fin) стала той которую мы заказывали синтезатору загружая в него управляющие команды.



Работает синтезатор так : 

В счетчик R (R counter) мы загрузим число на которое нужно поделить опорную частоту  - это будет шаг частот которые сможет синтезировать синтезатор.

Если нам нужен шаг 12,5 КГц то поделим  10245 КГц на 12,5 КГц  получаем число 819,6  - но дробное значение R нам не подходит. Уменьшим шаг в 10 раз - до 1,25 КГц   - теперь в R нам нужно загрузить число 8196.  Смотрим в даташит LMX2316 раздел "PROGRAMMABLE REFERENCE DIVIDER" и видим, что диапазон чисел для  от  3 до 16383  - значит  наш коэффициент деления опорной частоты - 8196 - допустим.

Шаг сетки синтезируемых частот будет 1,25 КГц.  Эта частота будет поступать на верхний вход компаратора фаз  - на диаграмме это треугольник "PHASE COMP".



Очевидно, что устойчивое совпадение фаз сигналов возможно только при подаче и на нижний вход компаратора "PHASE COMP" сигнала с частотой 1,25 КГц.   Т.е. синтезируемая частота со входа Fin должна быть поделена так что бы получить 1,25 КГц. 
Этот коэффициент деления называется - N 

Пусть нам нужно синтезировать частоту от 144 до 172 МГц.

Вычислим N  для этих частот.  

Для частоты 144 МГц           N  = 
144000 / 1.25 115200        

а  для частоты  172 МГц      N  =  172000 / 1.25 137600

Устройство счетчика-делителя N описано в разделе даташит "2.6 N COUNTER". Это 18 битное число в котором 13 бит с номерами от 18 до 6 образуют коэф. B, а 5 бит с номерами от 5 до 1  образуют коэф. A   Коэффициенты А и В вычисляют по формулам :

В  = целая часть от частного ( N / P

Где  P это коэф. деления  предделителя "PRESCALER" (он может делить частоту на 32 или 33 - мы будем использовать 32)

A  =  N - ( B * P

Этот коэф. учитывает отброшенную при вычислении В дробную часть. A  может иметь значение от 0 до 31 и не может превышать В


Частотам присвоим произвольные номера каналов и вычислим N   B и A :


Номер частотного
канала
 

Частота в КГц
 
N B A
0 144000,0 115200 3600 0
1 144012,5 115210 3600 10
2 144025,0 115220 3600 20
3 144037,5 115230 3600 30
4 144050,0 115240 3601 8
         
17 144212,5 115370 3605 10
         
0s 154700,0 123760 3867 16
1s 154712,5 123770 3867 26
2s 154725,0 123780 3868 4

 

Каналы с индексом s смещены относительно каналов без
индекса на 10,7 МГц (10,7 МГц /1,25 КГц = 8560)

Так как на компаратор фаз у нас подается 1,25 КГц а шаг сетки частот мы приняли в 12,5 КГц то N меняется на 10 единиц при переходе на соседний канал. 
B
увеличивается на 1 при перескоке A через число 31.

10,7 МГц /1,25 КГц = 8560

 

 

Реклама недорогих радиодеталей почтой:

 

 

Как загружать данные в синтезатор.

На диаграмме выше показаны 3 сигнала последовательной передачи данных в синтезатор - это интерфейса SPI  (последовательный интерфейс с периферийными устройствами).

CLOCK - этот сигнал по названию тактовый, но по сути просто "защелкивающий" (записывающий) своим фронтом (переходом из "0" в "1") очередной бит во входной сдвигающий 21-битный регистр синтезатора "DATA  REGISTER".

LE - этот сигнал указывает на окончание передачи данных в синтезатор своим фронтом и уровнем "1" не менее времени  tEW  по диаграмме "1.4 SERIAL DATA INPUT TIMING"  и должен быть "0" во время передачи данных.

DATA - на этом входе управляющий контроллер создает "1" или "0" в зависимости от того чему равен передаваемый в данный момент бит.

CE - на этой линии нужно сделать "1" для загрузки данных в синтезатор и для включения выхода управления VCO.  При "0" на этом синтезатор входит в режим пониженного потребления.

Все выводы синтезатора описаны в разделе даташит "Pin Descriptions".


Вот диаграмма передачи данных :

 


Очень важно соблюдать временные интервалы указанные на диаграмме.
В даташите LMX2316 не очень аккуратно (не совсем верно) расставлены размерные линии - я сделал более точный, на мой взгляд, рисунок :

Постарайтесь четко понять что означают эти интервалы и обозначения. Зеленым цветом я пометил моменты когда на линии DATA находится четкий "0" или "1" а красным - обозначен момент переключения  линии DATA если следующий передаваемый бит отличается от предыдущего. Длительность красного периода зависит от конструктивного исполнения схемы и от параметров источника сигнала. Микроконтроллер AVR может переключать свой вывод с частотой до 20 МГц  - т.е. каждые 50 nS  - наверно в большинстве случаев можно считать что красный период не превышает этого времени.

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

tCWH  - длительность "1" на линии CLOCK не менее 50 nS

t
CWL - длительность "0" на линии CLOCK не менее 50 nS

tCH  - длительность неизменности сигнала DATA после защелкивающего
          фронта на линии CLOCK не менее 10 nS

tCS - после установки сигнала DATA нужно подождать не менее 50 nS
          до создания защелкивающего фронта на линии CLOCK

Начинается передача со старшего бита - MSB (мост сигнификант бит - или наиболее значащий бит) при "0" на линии LE.

 

 

Реализация алгоритма SPI на языке Си

По диаграмме передачи данных по SPI видно что это многократное повторение некоторой последовательности действий - значит можно применить условные циклы  while( ) или for(;;)  - как они устроены и работают написано в "Си для МК"  

Давайте создавать функцию для передачи данных в синтезатор.

 

Я буду писать код программы на белом фоне. Структура программы
на Си для МК описана в "Си для МК"

   
 

/* Это произвольные комментарии
     на любое число строк
*/

// Это комментарии в ОДНУ строку


/*    **********************************

Программу советую начинать с краткого описания.

Название программы, версия, дата и авторство.
Название компилятора (инструментов) и версия.
Название микроконтроллера.
Частота тактирования, настройки.
Описание назначения и работы программы.
Описание как и что подключено к выводам МК.
Дополнительные сведения.

Чем подробней напишите - тем проще вам будет работать.

      **********************************    */
 

/* Теперь нужные библиотеки-заголовки .h  .c */

#include <mega16.h>
// Библиотека содержит описание регистров ATmega16

 

/* далее пользовательские определения #define   */

/* Синтезатор мы подключим к
  микроконтроллеру ATmega16 так:

PD4  DATA
PD5  CLOCK
PD6  LE

Когда на LE будет "1" синтезатор не будет реагировать на сигналы
на DATA и CLOCK - значит выводы PD4, PD5 можно будет использовать
для генерации ШИМ при необходимости.

CE - можно подключить к питанию синтезатора. */

#define DATA_LINE    PORTD.4
#define CLOCK_LINE   PORTD.5
#define LE_LINE      PORTD.6

#define DATA_LINE_ON  DDRD.4
#define CLOCK_LINE_ON DDRD.5
#define LE_LINE_ON    DDRD.6

#define PAUZA       #asm("nop")

   

 

Теперь можно в тексте программы писать так :

DATA_LINE_ON = 1;
//
включить линию DATA - т.е. сделать выходом вывод PD4

CLOCK_LINE_ON = 0;
//
ВЫключить линию CLOCK - т.е. сделать входом PD5
//
Помните! При "1" в PORTD.5 на входе будет подтяжка !

DATA_LINE = 1;
//
Сделать "1" на включенной линии DATA

Если нам нужно подключить синтезатор к другим выводам МК то изменения нужно будет сделать только в блоке программы выше и не придется искать и менять все строчки программы где происходят манипуляции с выводами синтезатора.

Значит  #define  это удобно.


 

   
 

/*  Объявление глобальных переменных  и констант  */

/* Для хранения 21 бита загружаемых в синтезатор нам потребуется три  глобальных переменных типа unsigned char. Назовем их: 

data_hi - будет хранить биты 21_14  

data_mid  - будет хранить биты 13_5  

data_low - будет хранить биты 4_0        */

volatile unsigned char data_hi, data_mid, data_low;
 

   

 

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

 

   
 

/*  Эта функция загружает в синтезатор 21 бит из трех
глобальных переменных типа unsigned char  именуемых: 
data_hi
, data_mid и  data_low.  
 */

void data_to_synt (void) {

  char  ctr = 8; /*  Локальная переменная счетчик */


/* 

Включаем линии (выводы МК) управляющие синтезатором
 
*/

LE_LINE_ON
= 1;  
LE_LINE    = 0;
/* я начал с линии LE так как на ней нужно сделать "0" а паузу после этого  автоматически создаст время конфигурации следующих линий */

CLOCK_LINE = 0;
CLOCK_LINE_ON = 1;
/* теперь на линии CLOCK "0" и она является выходом */

DATA_LINE_ON = 1;
/* линию DATA достаточно просто включить - сделать выходом */

 


/* Цикл вывода data_hi начиная с бита_7 (Это 21-й
бит - самый старший - MSB). Будем делать 8 раз
каждый раз отправляя в синтезатор очередной бит  */

// сейчас ctr равен 8

while (ctr){ // выполнять {в скобках} если ctr не ноль

  /* Вывести на DATA 7-й бит data_hi */
  DATA_LINE = data_hi & 0b10000000;

/* Мы каждый раз будем выводить 7-й бит, только в следующий раз мы подвинем на это место 6-й бит, затем 5-й и так далее */

  /*  Пауза гарантировано более 50 nS */
  PAUZA

  CLOCK_LINE = 1;  /* Сделать фронт на CLOCK */

  /* Сдвинуть data_hi на 1 позицию в лево */
  data_hi <<= 1;
  /* это поместит в бит_7 data_hi бит_6  - т.е. тот который
     будет передан при следующем выполнении цикла */

  CLOCK_LINE = 0;  /* Сделать спад на CLOCK */

  /* Уменьшить счетчик оставшихся прогонов цикла на 1 */
  ctr --;

           };
 

  ctr = 8;
/*
Снова "взводим" переменную счетчик на 8 прогонов цикла */
 

/* Вывести data_mid точно так же как data_hi */
while
(ctr){
 
  DATA_LINE = data_mid & 0b10000000;
  PAUZA
  CLOCK_LINE = 1; 

  data_mid <<= 1;
  CLOCK_LINE = 0; 

  ctr --;  
           };

 

  ctr = 5; /* Снова "взводим" переменную счетчик
  
но теперь на 5
   так как в data_low всего 5 бит нужно передать  */

while (ctr){/* Цикл вывода data_low начиная с бита_7
                  будем делать ПЯТЬ раз */

  /* Вывести на DATA 7-й бит data_low */
  DATA_LINE = data_low & 0b10000000;

  /*  Пауза 50 nS */
  PAUZA

  CLOCK_LINE = 1; /* Сделать фронт на CLOCK */

  /* Сдвинуть data_low на 1 позицию в лево */
  data_low <<= 1;

  CLOCK_LINE = 0; /* Сделать спад на CLOCK */

  /* Уменьшить счетчик оставшихся циклов на 1 */
  ctr --;

           };
 

/* Отправили 21 бит, теперь нужно сделать "1"
   на LE (см. диаграмму выше) */

  LE_LINE = 1;  /*  Вывести "1" на LE  */

/*
Передача 21 бита данных в синтезатор окончена
 
*/

}
 

   

 

 

 

Давайте откомпилируем программу  и посмотрим в осциллографе SCOPE  симулятора VMLAB результат. Он должен соответствовать диаграмме.


Для быстрой проверки кода программы в CVAVR и
VMLAB 
я сделал заготовку шаблон :


- скачайте  codevisionavr_vmlab.rar

- поместите его в папку   C:\VMLAB\TEST\        

Теперь в этой папке у вас есть все необходимое для быстрого тестирования работоспособности самих CVAVR и VMLAB и разрабатываемых программ. 

Использовать шаблон CVAVR - VMLAB рекомендую так

- распакуйте содержимое архива в папку   C:\VMLAB\TEST\

- кликните 2 раза по файлу проекта CVAVR  -  cv.prj 

- в запустившемся CVAVR нажмите   "Project"  - "Make"

- в окне информации об успешной компиляции кликните "ОК"

- запустите симулятор VMLAB

- через меню "Project" - "Open project" откройте файл  -  vmlab.prj

- теперь пересоберите проект -  "Project" - "Re-build all"  

- в окне "Messages" должно возникнуть сообщение "Success ! ...

- разместите окна на экране как вам удобно.

- нажмите светофор несколько раз до устойчивой симуляции.

Вы увидите: в окне SCOPE рисуются графики сигналов на выводах МК, в окне терминала TTY появилась приветствие которое передал МК по USART и светодиоды мигают, а в окне Code видно движение программы по коду на Си.


Подробно о работе с CVAVR и VMLAB написано в задаче 3 курса

 

Вы убедились - компилятор и симулятор у вас работают правильно можно модифицировать проект и программу в компиляторе. 

Разверните окно CVAVR и откройте меню "Project" - "Configure", закладку "C Compiler".  Установите частоту тактирования 10,245 МГц (как в расчетах выше) и нажмите "ОК" - отметьте это изменение в начале текста программы в описании - строка  "Clock frequency : 10,245 МГц"  

Очевидно изменение частоты такта МК повлияет на скорость USART - запустите мастер кода CVAVR (серая шестеренка в панели инструментов) в закладке "Chip" должны быть ATmega16 и частота 10,245 МГц  -  перейдите на закладку USART и активируйте галочку у "Трансмитер" (передача) - посмотрите скорости USART. Ошибка скорости не красного цвета (значит допустима) лишь при 9600 бод и ниже. Оставим 9600.  Чтоб посмотреть какие изменения нужно внести в программу для такой скорости нужно посмотреть сгенерированный текст программы  - откройте меню мастера "File" - "Program Preview"  и в тексте найдите строку

// USART Baud rate: 9600

 Ниже её есть настройки делителя для такой скорости - строки

UBRRH=0x00;
UBRRL=0x42;

ими нужно заменить аналогичные строчки в тексте программы шаблона в CVAVR и указать новую скорость - 9600. Скопируйте строчки, закройте текст и мастер и сделайте изменения в программе.

Запустите компиляцию и убедитесь что не возникло ошибок. 

Теперь соответствующие изменения нужно внести в файл проекта VMLAB - разверните его (или запустите если раньше закрыли) и на замечания о том что файлы были изменены ответьте "ОК" и сделайте глубокий рестарт программы - круговая стрелка темно синего цвета.  Откройте файл проекта через меню "View" - "Project File" и укажите новую частоту тактирования

.CLOCK 10.245meg

новую скорость терминала TTY   -  9600  

X1 TTY(9600 8) PD0 PD1

и в окно SCOPE мы выведем нужные сигналы

.plot V(PD4) V(PD5) V(PD6)

Сверните окно файла проекта и сделайте сохранение "File" - "Save all"  Перестройте проект - Shift+F9   Если всё готово к запуску то троекратным нажатием на светофор запустите устойчивую симуляцию.  Программа работает как и ранее только в окне SCOPE рисуются прямые линии с напряжением 2.5 вольт.  Дело в том что в шаблоне они сконфигурированы как высокоомные входы -  а так как они ни к чему не подключены то напряжение на них не известно и симулятор считает его средним между напряжениями питания МК. Остановите симуляцию.

 

Мы убедились что наша виртуальная отладочная макетная плата работает правильно и можно созданную выше на белом фоне программу вписать в исходник программы шаблона в CVAVR.


Это очень правильно и удобно создавать или модифицировать программу частями постоянно проверяя ее работоспособность и вылавливая ошибки сразу по мере возникновения !

 

Весь текст программы что мы создали на белом фоне выше нужно последовательно скопировать и вставить в исходник после строчки :

#include <delay.h>

до строчки :

void main(void){

 

Затем ниже строки:

while(1){

в бесконечный цикл вставим присвоение временных данных в 3
переменные и вызов функции отправки данных в синтезатор :

   
 

data_hi  = 0b10101010;
data_mid = 0b10101010;
data_low = 0b10101010;

data_to_synt ();

   

Я  поместил в переменные произвольные числа где "1" чередуется с "0" - думаю так диаграмма в осциллографе VMLAB будет выглядеть понятней.

 

Теперь выполните компиляцию программы - ошибок быть не должно.

Вот  архив с исправленными и скомпилированными файлами. Можно использовать их.  Теперь открывайте проект в VMLAB, пересоберите
его (Ребилд ол) и запускайте симуляцию светофором.
 

У меня получилась прекрасная картинка

Шкалу времени в SCOPE я поставил на 5 uS.

 

Уменьшив время развертки можно рассмотреть импульсы лучше :


Инструментом "Cursors" измерьте временнЫе интервалы.  

У меня получилось общее время передачи 63,3 мкС  и  такие значения :

tCWH  - 688 nS            tCH  -  2290 nS             tCS  -  680 nS
         

Очевидно что интервалы в 50 nS выдерживаются гарантировано - значит паузы можно исключить из алгоритма. Кроме того - чисто для "красивости" - можно сместить фронт на CLOCK правее - ближе к центру бита.

Я меняю алгоритм в CVAVR вот так - убираю паузу, а строку сдвига и декремента счетчика переношу в место над строкой создающей фронт на CLOCK

   
 

while (ctr){
 
DATA_LINE = data_hi & 0b10000000;

data_hi <<= 1;

ctr --;

CLOCK_LINE = 1; /* Сделать фронт на CLOCK */

CLOCK_LINE = 0; /* Сделать спад на CLOCK */

};
 

   

Аналогично меняю следующие 2 цикла  и перекомпилирую программу.

 

Открываю окно VMLAB - он сообщает что файлы изменены, жму "ОК" затем делаю "глубоки рестарт" (это соответствует выключению питания МК) и делаю пересборку проекта - Shift+F9  

Тремя не торопливыми нажатиями светофора запускаю симуляцию. После появления осциллограмм вывода 21 бита можно снова рассмотреть и измерить времена. Теперь импульсы располагаются красиво - почти по центру бита. Ширина импульса на CLOCK 190 nS  время передачи бита 2700 nS, а общее время передачи посылки сократилось до  59,2 мкС.  


Думаю функцию передачи можно считать отлаженной. 

Вот  архив с исправленными файлами

 

 

 

Продолжение следует ... 

 

Далее проверим временные интервалы передачи и будем делать управление - какую частоту загружать и расчет чисел.

 

 

 



 

          

 
 

 

 

ключевые слова: электронные проекты, хобби, язык си для микроконтроллеров, язык программирования си Основы программирования (кнопочки, светодиоды) Работа с портами. Прерывания и таймеры. Основы ШИМ, программная и аппаратная реализация. Сервоприводы. Работа с АЦП, программирование микроконтроллеров, как написать программу для микроконтроллера, обучение программированию микроконтроллеров, микроконтроллеры atmega128, как запрограммировать микроконтроллер, как прошить микроконтроллер, отладка программы для AVR, моделирование работы электронных схем, Настройка и программирование UART Работа с I2C Связь (UART, I2C, SPI) 
AT76C712 , AT76C713 , AT90CAN128 , AT90CAN128 Automotive , AT90CAN32 , AT90CAN64 , AT90PWM2 , AT90PWM3 , AT90S1200 , AT90S2313 , AT90S2323 , AT90S2343 , AT90S4433 , AT90S8515 , AT90S8535 , ATmega128 , ATmega1280 , ATmega1281 , ATmega16 , ATmega161 , ATmega162 , ATmega163 , ATmega164 , ATmega165 , ATmega168 , ATmega168 Automotive , ATmega169 , ATmega2560 , ATmega2561 , ATmega32 , ATmega323 , ATmega324 , ATmega325 , ATmega3250 , ATmega329 , ATmega3290 , ATmega406 , ATmega48 , ATmega48 Automotive , ATmega64 , ATmega640 , ATmega644 , ATmega645 , ATmega6450 , ATmega649 , ATmega6490 , ATmega8 , ATmega8515 , ATmega8535 , ATmega88 , ATmega88 Automotive , ATtiny11 , ATtiny12 , ATtiny13 , ATtiny15L , ATtiny2313 , ATtiny25 , ATtiny26 , ATtiny28L , ATtiny45 , ATtiny85


 

 

 

Сайт управляется системой uCoz