Первые шаги в увлекательный мир USB с дешевым маловыводным микроконтроллером PIC18F14K50

Очень краткое описание PIC18F14K50

Микроконтроллер PIC18F14K50 представляет собой интересную штучку в 20-ти выводном корпусе :). Детальные характеристики Вы всегда можете найти на сайте производителя, я выделю только самые основные, которые понравились мне для моих задач:

  1. Наличие аппаратной поддержки USB. Просто подключаем к двум ножкам кусок провода со штекером и устанавливаем один конденсатор. Это и все внешние компоненты для начала работы с USB.
  2. Напряжение питания ядра 3.6В, при этом внутри есть встроенный регулятор напряжения, который позволяет питать этот МК напряжением до 5.5В. Полный диапазон составляет 1.8-5.5В. В случае батарейного питания, три 1.5-вольтовые батарейки "высосет" полностью!
  3. маленький корпус на 20 выводов. Для некоторых задач этого вполне достаточно.

Для чего это разрабатывалось?

Учитывая положительный опыт эксплуатации приставки к ПК - большой алфавитно-цифровой ЖК-дисплей и приемник ИК сигналов пульта, я принял решение сделать еще одну, но уже с USB-портом. Выбор пал на маловыводный МК ценой в 20 грн - PIC18F14K50.

Приставка к ПК. ЖК-дисплей + сприемник ИК сигналов пульта ДУ + часы реального времени на базе PIC18F14K50

но о всем по порядку.

Подключаем USB

Для работы USB в режиме High Speed нам понадобиться кварц на 12 МГц. Почему 12 МГц? Дело в том, что этот МК допускает работу с кварцами до 20 МГц, для USB нужно 48 МГц. Внутри МК есть аппаратный умножитель частоты на 4, (4 * 12 МГц = 48МГц). Для скорости Low Speed можно поставить кварц на 6 МГц.
Обсуждение выбора кварца смотрите здесь:USB в PIC18F14K50 на 6МГц.

Подключение USB к PIC18F14K50

Собираем схему. Как сделать DCD (преобразователь USB-UART), HID (мышка, клавиатура и др.) и подобные вещи я рассказывать не буду, так как есть готовые примеры для разных компиляторов. Остановлюсь на диалоговом режиме. Ниже приведен пример кода:
  1. #include <18F14K50.h>
  2.  
  3. #FUSES NOWDT                    //Без сторожевого таймера
  4. #FUSES WDT128                   //Делитель сторожевого таймера 1:128
  5. #FUSES HS                       //Высокоскоростной кварц (выше 4 МГц)
  6. #FUSES NOFCMEN                  //Fail-safe clock monitor disabled
  7. #FUSES BROWNOUT                 //Сброс при опасном снижении напряжения питания
  8. #FUSES BORV19                
  9. #FUSES PUT                      //Таймер задержки включения питания
  10. #FUSES NOCPD                    //No EE protection
  11. #FUSES STVREN                   //Перезагружать МК при переполнении стека
  12. #FUSES NODEBUG                  //No Debug mode for ICD
  13. #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  14. #FUSES NOWRT                    //Память программ не защищена от записи
  15. #FUSES NOWRTD                   //Data EEPROM not write protected
  16. #FUSES NOWRTC                   //configuration not registers write protected
  17. #FUSES IESO                     //Внутренний регулятор питания включен
  18. #FUSES NOEBTR                   //Memory not protected from table reads
  19. #FUSES NOEBTRB                  //Boot block not protected from table reads
  20. #FUSES NOMCLR                   //Master Clear pin used for I/O
  21. #FUSES NOPROTECT                //Code not protected from reading
  22. #FUSES NOCPB                    //No Boot Block code protection
  23. #FUSES NOWRTB                   //Boot block not write protected
  24. #FUSES NOLVP                    //Режим низковольтного программирования отключен
  25. #FUSES NOHFOFST              
  26. #FUSES NOWRT0                
  27. #FUSES NOWRT1                
  28. #FUSES USBDIV1              
  29. #FUSES PCLKEN                
  30. #FUSES BBSIZ2K                  //2K words Boot Block size
  31. #FUSES PLLEN                 //Тактовая частота от кварца умножается на 4. Для USB нужна тактовая 48 МГц.
  32. #FUSES CPUDIV4                  //Тактовая частота ядра делится на 4
  33.  
  34. #use delay(clock=12M,RESTART_WDT) //Тактовая частота ядра 12 МГц
  35.  
  36.  
  37. #use fast_io(A) // Работа с портами без переключения
  38. #use fast_io(B) // каждый раз регистров TRIS
  39. #use fast_io(C) //
  40.  
  41.  
  42. //#define USB_CON_SENSE_PIN PIN_RA3 //Появление лог.1 на этой ножке дает знать USB-стеку, что МК подключили к USB хоста. Можно закомментировать данную сстроку и тогда стек будет считать что МК постоянно подключен к USB.
  43. #include <usb_cdc.h>
  44.  
  45. void usb_dialog(void);
  46.  
  47. void main(void)
  48. {
  49.    setup_spi(SPI_SS_DISABLED);    
  50.    setup_wdt(WDT_OFF);
  51.    setup_timer_0(RTCC_INTERNAL);
  52.    setup_timer_1(T1_DISABLED);
  53.    setup_timer_2(T2_DISABLED,0,1);
  54.    setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  55.    setup_comparator(NC_NC_NC);// This device COMP currently not supported by the PICWizard
  56.  
  57.    enable_interrupts(INT_EXT);
  58.  
  59.    set_tris_b(0b01111111);
  60.  
  61.    usb_init_cs();
  62.    usb_attach();
  63.  
  64.    delay_ms(250); delay_ms(250); delay_ms(250); delay_ms(250);
  65.    delay_ms(250); delay_ms(250); delay_ms(250); delay_ms(250);    
  66.    
  67.    usb_cdc_putc("USB by PIC18F14K50 working!!!\n\rPress any key");    
  68.  
  69.   while(1)
  70.         {
  71.      usb_task();
  72.      usb_dialog();
  73.  
  74.      if (usb_cdc_carrier.dte_present) //Готовность принимать данные
  75.       output_high(PIN_B7);
  76.         else
  77.       output_low(PIN_B7);
  78.      
  79.       delay_ms(250);  
  80.         }
  81. }
  82.  
  83. void usb_dialog(void)
  84. { unsigned char key;
  85.  
  86. // Тут будем вести пимитивный диалог. Подключительс к этому
  87. // виртуальному порту через HiperTerminal или другую
  88. // терминальную программу на скорости 9600 кбит/с
  89.  
  90. if (usb_cdc_kbhit()) //Есть ли принятые данные в буфере?
  91.         { key=usb_cdc_getc(); //Получем байт из буфера
  92.       usb_cdc_putc(key);
  93.       usb_cdc_putc("\n\r");
  94.       switch(key) {
  95.           case '1'      : usb_cdc_putc("You are selected Computer \n\r"); break;
  96.           case '2'      : usb_cdc_putc("You are selected uController \n\r"); break;
  97.           case '3'      : usb_cdc_putc("You are selected uComputer \n\r"); break;
  98.           default       : usb_cdc_putc("\n\rSelect item:\n\r1. Computer\n\r2. Microcontroller\n\r3. PDA\n\r>:"); break;
  99.                         }          
  100.         }
  101. }

Компилируем и прошиваем (Откомпилированная прошивка здесь.). Подключаем к USB, Windows находит новое устройство и просит драйвера. Следует подсунуть .inf файл, который лежит в примерах для CDC. Убеждаемся в диспетчере оборудования, что появился новый COM-порт и запускаем любую терминальную программу (я использовал стандартный HyperTerminal). Вот результат работы:

Подключение PIC18F14K50 к ПК по USB

Итак! USB работает! Железка отвечает на наши вопросы! Далее дело только за Вашей фантазией! Удачи!

Фото приставки к ПК на базе МК PIC18F14K50, дисплея RC2002C-YKY-CSX, RTC DS1307, Flash 24FC256, Кварц 12 МГц, USB и двухцветный светодиод

USB-шнур был сделан из куска коротенького (0.5м) USB-удлинителя, который неудачно (для себя) подвернулся под руку :)


Не заработало? Проверяем внимательно монтаж, полярность USB D+/D-, сам кварц и др. Если все правильно, но при подключении получаем сообщение "неопознанное USB-устройство", то вполне возможно, что Ваш компилятор выставляет неправильное слово конфигурации для PIC18F14K50. Я столкнулся с этим в компиляторе CSS версий 4.093, 4.076. После компиляции, перед прошивкой в микроконтроллер, я вручную изменял слово конфигурации. Для приведеного выше примера я использовал следующую комбинацию фьюз:

Правильное слово конфигурации для USB PIC18F14K50, если получаем єто устройство не опознанно

По слухам, в версии CSS 4.107 это уже исправили.

10.06.2010