Rambler's Top100

Реклама на сайте | Реклама в Интернет | "Все Кулички"


Главная страница
Все о компьютерном "железе"
Вся полезная информация
Эрудиту
Гарантированная продажа рекламных мест
Цены магазинов Москвы на ноутбуки и мобильные компьютеры
Мои разработки и переводы
Микроконтроллеры >>
Мои разработки
Полезные конструкции
Программаторы
FAQ по ПИКам
"Глюки" ПИКов
Ссылки
Железо и драйвера >>
Статьи и FAQ
Ссылки на статьи
Определение конфигурации
Настройка компонентов ПК
Утилиты для накопителей информации
Ремонт "железа"
Восстановление информации
Полезный софт
Операционные системы
Безопасность и защита информации
Радиоэлектроника
Программирование >>
Техдокументация
Разработчику программ
Мобильники
Вебмастеру
Поиск информации
On-Line перевод
Обмен ссылками, сотрудничество
Немного о себе
Контакты
Гостевая книга
Форум

Поиск на сайте
Поиск на Куличках:

Сделать стартовой страницей

Реклама:

(!) MP3 плееры всех видов. Возьми с собой 6 обычных Audio-CD на одном(!!!) MP3-CD
Телевизоры, DVD-плееры, видеомагнитофоны, видео-плееры. Аппаратура Hi-End класса


rax.ru: показано число посетителей за сегодня

Рейтинг@Mail.ru

RadioTOP-рейтинг радиотехнических сайтов
PROext: Top 1000
ENGLISH version
Доброй ночи! Пятница, 29 марта 2024
FT8U245АM в интерфейсе USB (продолжение)
Источник: WWW.KULAKOV.RU
Автор статьи Семенов Ю.В.

Пример использования модуля USB.

<<< Начало       Окончание >>>

      Здесь рассматривается использование модуля USB совместно с микроконтроллером PIC18F458 фирмы «Microchip» и индикатора WD-C1602Q-1YLYc фирмы «Wintek». Пример не имеет практической ценности, но необходим для понимания принципов организации связи по USB со стороны микроконтроллера.

      Учебная задача сформулирована следующим образом:

  1. На индикатор должен выводиться текст, вводимый из окна редактирования формы на экране монитора компьютера.
  2. Этот же текст должен возвращаться устройством по USB в другое окно той же формы.
  3. Устройство должно позволять перемещать курсор на индикаторе влево и вправо, а так же полностью очищать индикатор.
  4. Максимальная длина текста ограничена шестнадцатью символами, что соответствует одной строке индикатора.
      Задача решается поэтапно. Сначала на основании документов [5] и [6] разрабатывается схема гипотетического устройства. Она приведена на рис. 5. В принципе, для микроконтроллеров с малым числом выводов можно объединить шину данных модуля USB и индикатора, оставив разделёнными лишь управляющие сигналы обоих устройств.
      С целью упрощения использования модуля, его выводы были перенумерованы в соответствии с разводкой печатной платы. Таблица соответствия приведена в таблице 2.

Наименование сигнала Поз.обозначение
1 GND – общий X15
2 D0 – данные X1
3 D1 – данные X3
4 D2 – данные Х4
5 D3 – данные X5
6 D4 – данные X6
7 D5 – данные X7
8 D6 – данные X8
9 D7 – данные X9
10 RD# - вход чтения X10
11 WR – вход записи X11
12 TXE# - выход буфера передачи X12
13 RXF# - выход буфера приёма X13
14 GND – общий X14

Рис.5. Схема включения модуля USB и двухстрочного индикатора совместно с микроконтроллером

Программа для микроконтроллера PIC18F458.

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

;Порт В
;Шина ввода-вывода для индикатора
;Порт С
;RC1 - выход управления индикатором RS
;RC2 - выход управления индикатором R/W
;RC3 - выход управления индикатором E
;RC4 - выход управления USB RD#
;RC5 - выход управления USB WR
;RC6 - вход с контроллера USB TXE#
;RC7 - вход с контроллера USB RXF#
;Порт D
;Шина ввода-вывода контроллера USB
      LIST P=18F458;
      #include ;
      В соответствии со схемой на рис.5 производится назначение выводов порта С, предназначенных для работы с модулем USB. RD# четвёртый вывод, WR пятый, TXE# и RXF# шестой и седьмой соответственно. Выводу WR не удалось присвоить родное обозначение из-за того, что оно зарезервировано во включаемом файле P18F458.INC для других целей.
RD# equ 0x04 ;выход управления USB RD#
WRITE equ 0x05 ;выход управления USB WR
TXE# equ 0x06 ;вход с контроллера USB TXE#
RXF# equ 0x07 ;вход с контроллера USB RXF#

      Далее следует текст, касающийся индикатора.

RS equ 0x01 ;выход управления индикатором RS
RW equ 0x02 ;выход управления индикатором R/W
E equ 0x03 ;выход управления индикатором E
       CBLOCK 0x000
       IndStat ;регистр состояний индикатора
       CntSymb ;счётчик символов
       Memory ;память
       IndBuf0 ;символ
       ENDC
;******************************************************************************
       org 0x00 ;
       goto START ;
;******************************************************************************
;Таблица перекодировки русских букв
       org 0x22
CodTab data 0xa041,0xa142,0x45e0,0xa4a3,0xa6a5,0xa74b,0x484d,0xa84f
       data 0x4350,0xa954,0x58aa,0xabe1,0xe2ac,0xaead,0xaf62,0xb1b0
       data 0xb261,0xb4b3,0x65e3,0xb7b6,0xb9b8,0xbbba,0xbdbc,0xbe6f
       data 0x6370,0x79bf,0x78e4,0xc0e5,0xe6c1,0xc3c2,0xc5c4,0xc7c6
;инициализация микро-ЭВМ
START bcf INTCON,GIE,0 ;запрет всех прерываний;
       clrf PORTA,0 ;программирование порта
       clrf LATA,0 ;А на ввод;
       movlw 0x01 ;
       movwf ADCON0,0 ;
       movlw 0x8C ;
       movwf ADCON1,0 ;
       movlw 0xff ;программирование порта А
       movwf TRISA,0 ;на ввод;
       clrf PORTB,0 ;программирование
       clrf LATB,0 ;порта В
       movlw 0xff ;на
       movwf TRISB,0 ;ввод;
       clrf PORTC,0 ;программирование
       clrf LATC,0 ;RC6, RC7, RC0
       movlw 0xc1 ;на ввод, а
       movwf TRISC,0 ;остальные на вывод;
      При начальных установках, сразу после первой инициализации порта С, выводы WR и RD# переводятся в пассивное состояние.
       bsf PORTC,WRITE,0 ;WR=1;
       bsf PORTC,RD#,0 ;RD#=1;
      После этих команд на указанных выводах появится высокий уровень, что переведёт шину данных модуля USB в третье состояние. Далее следует текст, касающийся индикатора и инициализации отдельных узлов микроконтроллера.
       bsf PORTC,RS ;RS=1;
       bsf PORTC,RW ;RW=1;
       bcf PORTC,E ;E=0;
       clrf PORTD,0 ;
       clrf LATD,0 ;
       movlw 0x07 ;
       movwf CMCON,0 ;
      Шина данных модуля USB, то есть порт D, при начальной инициализации программируется на ввод.
       movlw 0xff ;программирование
       movwf TRISD,0 ;порта D на ввод;
       clrf PORTE,0 ;программирование
       clrf LATE,0 ;порта Е
       movlw 0x03 ;на ввод;
       movwf TRISE,0 ;
       movlw 0xc0 ;
       movwf T0CON,0 ;
;******************************************************************************
;индикатор
       clrf TBLPTRU,0 ;очистка указателя
       clrf TBLPTRH,0 ;двнных в памяти программ;
       movlw 0x9e ;задержка 40 мс;
       movwf TMR1H,0 ;
       movlw 0x57 ;
       movwf TMR1L,0 ;
       movlw 0xb1 ;
       movwf T1CON,0 ;
       bcf PIR1,TMR1IF ;
M1 btfsc PIR1,TMR1IF ;
       bra M2 ;
       bra M1 ;
M2 clrf IndStat,0 ;регистр состояния индикатора=начало;
Begin movlw 0x0d ;если(!регистр состояния индикатора==вывод первой строки||
       xorwf IndStat,w,0 ; !регистр состояния индикатора==|| вывод второй строки)
       bz M16 ; переход к переключателю
       movlw 0x11 ;
       xorwf IndStat,w,0 ;
       bnz M15 ;
      В этом месте производится чтение из буфера приёма модуля USB. В начале опрашивается вывод RXF#. Если на нём высокий уровень, то буфер пуст и чтение не производится.
M16 btfsc PORTC,RXF#,0 ;если(RXF#) переход к концу цикла;
      bra M12 ;
      В случае, когда в буфере приёма есть хотя бы один символ, вывод RXF# имеет низкий уровень, и выполняются действия в соответствии с временной диаграммой, представленной на рис.3.
       bcf PORTC,RD#,0 ;сброс RD#
      После этой команды уровень на выводе RD# становится низким, что приводит к тому, что на выводах порта D, запрограммированного на ввод, через время Т3 появятся данные.
       movff PORTD,IndBuf0 ;символ=портD;
      Затем эти данные попадают с выводов порта D в приёмный буфер из одного байта в данном случае.
       bsf PORTC,RD#,0 ;установка RD#;
      Эта команда переводит вывод RD# в состояние с высоким уровнем, что означает окончание цикла чтения данных из буфера приёма модуля USB. Далее следует обработка полученных данных в соответствии с поставленной задачей.
             movf IndBuf0,w,0 ;если(символ==0х80)
       xorlw 0x80 ; {
       bnz M18 ;
       movff IndStat,Memory ; память=текущее состояние индикатора;
       movlw 0x12 ; регистр состояния индикатора=сдвиг курсора влево;
       movwf IndStat,0 ; переход к переключателю;
       bra M15 ; };
M18 movf IndBuf0,w,0 ;если(символ==0х81)
       xorlw 0x81 ; {
       bnz M181 ;
       movff IndStat,Memory ; память=текущее состояние индикатора;
       movlw 0x14 ; регистр состояния индикатора=сдвиг курсора вправо;
       movwf IndStat,0 ; переход к переключателю;
       bra M15 ; };
M181 movf IndBuf0,w,0 ;если(символ==0х82)
       xorlw 0x82 ; {
       bnz M182 ;
       movlw 0x06 ; регистр состояния индикатора=очистка дисплея;
       movwf IndStat,0 ; переход к переключателю;
       bra M15 ; };
      Аналогично осуществляется и запись данных в буфер передачи модуля USB. Перед циклом записи необходимо проверить, свободен ли буфер записи модуля USB. Если буфер занят целиком и в нём нет ни одного свободного байта, то запись откладывается до его освобождения. В этом случае на выводе TXE# будет присутствовать высокий уровень.
M182 btfsc PORTC,TXE#,0 ;если(TXE#) переход к концу цикла;
       bra M12 ;
      Если же в буфере записи есть хотя бы один свободный байт, то есть вывод TXE# имеет низкий уровень, тогда начинается цикл записи в соответствии с рис.4.
             clrf TRISD,0 ;портD->вывод;
       nop ;
       nop ;
      Порт D программируется на вывод. Затем следуют две холостые команды, которые дают время для полного затухания переходных процессов на выводах порта D, связанных с изменением его конфигурации.
       movff IndBuf0,PORTD ;портD=символ;
      После этого, данные передаются из буфера, состоящего из одного байта, на выводы порта D.
       bcf PORTC,WRITE,0 ;сброс WR;
       bsf PORTC,WRITE,0 ;установка WR;
      Две предыдущие команды формируют строб записи, то есть переводят вывод WR сначала в низкий, а затем в высокий уровень. На этом цикл записи данных в модуль USB можно считать завершённым.
       movlw 0xff ;портD->ввод;
       movwf TRISD,0 ;
      Однако после операции записи порт D необходимо перевести в состояние с высоким импедансом, что и делается с помощью двух предыдущих команд. После них порт D будет запрограммирован на ввод.
      Далее следует текст, не имеющий отношения к модулю USB. Этот текст снабжён комментариями, и желающие могут разобраться по нему с работой индикатора.
M19 movf IndBuf0,w,0 ;
       xorlw 0xa8 ;
       bz M20 ;
       movf IndBuf0,w,0 ;
       xorlw 0xb8 ;
       bz M21 ;
       bra M22 ;
M20 movlw 0xa2 ;перекодировка символа "ё";
       movwf IndBuf0,0 ;
       bra M15 ;переход к переключателю;
M21 movlw 0xb5 ;
       movwf IndBuf0,0 ;перекодировка символа "Ё";
       bra M15 ;переход к переключателю;
M22 movlw 0xc0 ;если (символ==русский)
       subwf IndBuf0,w,0 ;{
       bc M23 ;
       bra M15 ;
M23 addlw CodTab ;перекодировка символа;
       movwf TBLPTRL,0 ;
       tblrd * ;
       movff TABLAT,IndBuf0 ;};
M15 movf PCL,w,0 ;переключатель (регистр состояния индикатора)
       rlncf IndStat,w,0 ;
       addwf PCL,f,0 ;
       bra IndGo0 ;случай 0:{FunctionSet();выход;}
       bra IndGo1 ;случай 1:{задержка 37 мкс();выход;}
       bra IndGo0 ;случай 2:{Function Set();выход;}
       bra IndGo1 ;случай 3:{задержка 37 мкс()выход;}
       bra IndGo2 ;случай 4:{проверка флага занятости();выход;}
       bra IndGo3 ;случай 5:{DisplayON/OFF();выход;}
       bra IndGo2 ;случай 6:{проверка флага занятости();выход;}
       bra IndGo4 ;случай 7:{ClearDispley();выход;}
       bra IndGo2 ;случай 8:{проверка флага занятости();выход;}
       bra IndGo5 ;случай 9:{EntryModeSet();выход;}
       bra IndGo2 ;случай A:{проверка флага занятости();выход;}
       bra IndGo6 ;случай B:{начало первой строки();выход;}
       bra IndGo2 ;случай C:{проверка флага занятости();выход;}
       bra IndGo7 ;случай D:{вывод символа первой строки();выход;}
       bra IndGo2 ;случай E:{проверка флага занятости();выход;}
       bra IndGo8 ;случай F:{начало второй строки();выход;}
       bra IndGo2 ;случай 10:{проверка флага занятости();выход;}
       bra IndGo9 ;случай 11:{вывод символа второй строки();выход;}
       bra IndGo2 ;случай 12:{проверка флага занятости();выход;}
       bra IndGo10 ;случай 13:{сдвиг курсора влево();выход;}
       bra IndGo2 ;случай 14:{проверка флага занятости();выход;}
       bra IndGo11 ;случай 15:{сдвиг курсора вправо();выход;}
;--------------------------------------------------------------------------------
;FunctionSet()
;{
IndGo0 movlw 0x38 ;

       clrf TRISB,0 ;портВ->вывод;
       bcf PORTC,RS ;сброс RS;
       bcf PORTC,RW ;сброс RW;
       bsf PORTC,E ;установка Е;
       movwf PORTB,0 ;портВ=8 бит,2 строки, 5Х8 точек
       bcf PORTC,E ;сброс Е;
       movlw 0xFF ;портВ->ввод;
       movwf TRISB,0 ;
       movlw 0x8e ;
       movwf TMR1L,0 ;загрузка таймера задержки
       movlw 0xff ;
       movwf TMR1H,0 ;
       movlw 0xb1 ;
       movwf T1CON,0 ;и его запуск
       bcf PIR1,TMR1IF,0 ;
       incf IndStat,f,0 ;регистр состояния индикатора++
       bra M12 ;
;}
;--------------------------------------------------------------------------------
;задержка 37 мкс()
;{
IndGo1 btfss PIR1,TMR1IF,0 ;если (TMR1IF переполнен)
       bra M12 ;{
       incf IndStat,f,0 ;регистр состояния индикатора++;
       bcf PIR1,TMR1IF,0 ;
       bra M12 ;};
;}
;--------------------------------------------------------------------------------
;проверка флага занятости()
;{
IndGo2 movlw 0xFF ;
       movwf TRISB,0 ;портВ->ввод;
       bcf PORTC,RS ;сброс RS;
       bsf PORTC,RW ;установка RW;
       bsf PORTC,E ;установка E;
       movf PORTB,w,0 ;флаг занятости индикатора=портВ[бит7];
       bcf PORTB,E ;сброс E;
       andlw 0x80 ;если (флаг занятости индикатора)
       bz CHKOK ;
       bra M12 ;{остаться в состоянии проверки флага занятости;}
CHKOK incf IndStat,f,0 ;иначе
       bra M12 ;{перейти к следующему состоянию;};
;}
;--------------------------------------------------------------------------------
;Display ON/OFF()/*дисплей вкл, курсор вкл, мерцание вкл
;{
IndGo3 movlw 0x0F ;Execute(0x0f);
;}
;--------------------------------------------------------------------------------
;Execute(int W)
;{
Execute clrf TRISB,0 ;портВ->вывод;
       bcf PORTC,RS ;сброс RS;
       bcf PORTC,RW ;сброс RW;
       bsf PORTC,E ;установка Е;
       movwf PORTB,0 ;портВ=W;
       bcf PORTC,E ;сброс Е;
       movlw 0xFF ;портВ->ввод;
       movwf TRISB,0 ;
       incf IndStat,f,0 ;регистр состояния индикатора++;
       bra M12 ;
;}
;--------------------------------------------------------------------------------
;ClearDisplay()
;{
IndGo4 movlw 0x01 ;
       bra Execute ;Execute(0x01);
;}
;--------------------------------------------------------------------------------
;EntryModeSet()
;{
IndGo5 movlw 0x06 ;
       bra Execute ;Execute(0x06);
;}
;--------------------------------------------------------------------------------
;начало первой строки()
;{
IndGo6 movlw 0x10 ;счётчик символов=16;
       movwf CntSymb,0 ;
       movlw 0x80 ;Execute(0x80);
       bra Execute ;
;}
;--------------------------------------------------------------------------------
;вывод символа первой строки()
;{
IndGo7 clrf TRISB,0 ;портВ->вывод;
       bsf PORTC,RS,0 ;установка RS;
       bcf PORTC,RW,0 ;сброс RW;
       bsf PORTC,E,0 ;установка E;
       movff IndBuf0,PORTB ;портВ=символ;
       bcf PORTC,E,0 ;сброс Е;
       movlw 0xff ;портВ->ввод;
       movwf TRISB,0 ;
       dcfsnz CntSymb,f,0 ;счётчик символов --
       bra IncStat ;если (счётчик символов==0)
       decf IndStat,f,0 ;{регистр состояния индикатора--;}
       bra M12 ;иначе
IncStat incf IndStat,f,0 ;{регистр состояния индикатора++;}
       bra M12 ;
;}
;--------------------------------------------------------------------------------
;начало второй строки()
;{
IndGo8 movlw 0x10 ;
       movwf CntSymb,0 ;счётчик символов=16;
       movlw 0xc0 ;
       bra Execute ;Execute(0xc0);
;}
;--------------------------------------------------------------------------------
;вывод символа второй строки()
;{
IndGo9 clrf TRISB,0 ;портВ->вывод;
       bsf PORTC,RS ;установка RS;
       bcf PORTC,RW ;сброс RW;
       bsf PORTC,E,0 ;установка E;
       movff IndBuf0,PORTB ;портВ=символ;
       bcf PORTC,E,0 ;сброс Е;
       movlw 0xff ;портВ->ввод;
       movwf TRISB,0 ;
       dcfsnz CntSymb,f,0 ;счётчик символов --
       bra MovStat ;если (счётчик символов==0)
       decf IndStat,f,0 ;{регистр состояния индикатора--;}
       bra M12 ;иначе
MovStat movlw 0x0a ;{регистр состояния индикатора=начало первой строки;}
       movwf IndStat,0 ;
       bra M12 ;
;}
;--------------------------------------------------------------------------------
;сдвиг курсора влево()
;{
IndGo10 movff Memory,IndStat ;
       movf CntSymb,w,0 ;
       xorlw 0x10 ;если (курсор==начало строки)
       bnz M30 ;
       movf IndStat,w,0 ;
       xorlw 0x0d ; если (регистр состояния индикатора==вывод первой строки)
       bnz M31 ; {
       movlw 0x01 ;
       movwf CntSymb,0 ;
       movlw 0x11 ; регистр состояния индикатора=вывод второй строки;
       movwf IndStat,0 ;
       movlw 0xcf ; позиция курсора=конец второй строки;
       bra M32 ; }
M31 movlw 0x01 ; иначе
       movwf CntSymb,0 ; {
       movlw 0x0d ; регистр состояния индикатора=вывод первой строки;
       movwf IndStat,0 ; позиция курсора=конец первой строки;
       movlw 0x8f ; };
       bra M32 ;иначе
M30 incf CntSymb,f,0 ;{
       movlw 0x10 ;сдвиг курсора влево;
M32 decf IndStat,f,0 ;регистр состояния индикатора=проверка флага занятости;
       decf IndStat,f,0 ;};
       bra Execute ;
;}
;--------------------------------------------------------------------------------
;сдвиг курсора вправо()
;{
IndGo11 movff Memory,IndStat ;сдвиг курсора вправо()
       movf CntSymb,w,0 ;{
       xorlw 0x01 ;если (курсор==конец строки)
       bnz M33 ;
       movf IndStat,w,0 ; если (регистр состояния индикатора==вывод первой строки)
       xorlw 0x0d ; {
       bnz M34 ;
       movlw 0x10 ;
       movwf CntSymb,0 ;
       movlw 0x11 ; регистр состояния индикатора=вывод второй строки;
       movwf IndStat,0 ;
       movlw 0xc0 ; позиция курсора=начало второй строки;
       bra M35 ; }
M34 movlw 0x10 ; иначе
       movwf CntSymb,0 ; {
       movlw 0x0d ; регистр состояния индикатора=вывод первой строки;
       movwf IndStat,0 ; позиция курсора=начало первой строки;
       movlw 0x80 ; };
       bra M35 ;иначе
M33 decf CntSymb,f,0 ;{
       movlw 0x14 ;сдвиг курсора вправо;
M35 decf IndStat,f,0 ;регистр состояния индикатора=проверка флага занятости;
       decf IndStat,f,0 ;};
       bra Execute ;
;}
;--------------------------------------------------------------------------------
;конец цикла
M12 goto Begin ;переход к началу цикла
       end

      Как видно из приведённого примера, работа с модулем USB со стороны микроконтроллера проста и прозрачна. В связи с большой скоростью, на которой работает модуль USB, в циклах записи и чтения не требуются задержки, характерные при работе с медленными устройствами.       Для проверки примера, рассмотренного выше, необходимо скопировать текст программы в среду разработки, поддерживающую микроконтроллер PIC18F458 или подобный ему. Этой средой может быть, например, MPLAB 5.70, которым пользовался автор. Дальнейшие действия стандартны. После получения файла типа HEX его тем или иным способом загружают в микроконтроллер. Его, в свою очередь, помещают в устройство, изготовленное по схеме на рис.5 и соединяют с компьютером кабелем USB.       Если всё сделано правильно, то на экране монитора появится сообщение об обнаружении нового устройства. Тому, что необходимо сделать после этого, будет посвящён следующий раздел.

            Литература.

      5. www.microchip.com/download/lit/pline/picmicro/families/18fxx8/41159c.pdf
      6. 6. www.wintek.com.tw/spec/WD-C1602Q-6YLYc.pdf


Наверх | К списку статей | На главную страницу


Полное или частичное воспроизведение любых материалов, содержащихся на этом сайте, допускается только с письменного разрешения администрации. Авторские права на опубликованные на сайте материалы принадлежат их владельцам.
Замечания? Предложения? "Мертвые" ссылки? Проблемы с загрузкой страниц? Пишите вебмастеру или в гостевую книгу
Designed by Эfir studio | © 2002-03 Yuri Lysenkov