Simulácia RS-232 rozhrania
Doporučené preštudovať : Komunikačné rozhrania | USB - Módy detekcie
Už vieme ako funguje USB. Najjednoduhším spôsobom je využiť framework v režime PC - MASTER,
a Device - CDC (RS-232).
Napísanie aplikácie komunikujúcej prostredníctvom sériovky RS-232 je naozaj veľmi jednoduché.
Firmware alebo inak Framework, je časť rozsiahlého kódu, ktorej súčasti sú zavedené v metode main. Odtial je cyklicky spúšťané jadro frameworku obsluhujúce metódy pre príjem/odosielanie dát.
* Kompletná sada všetkých možných variant frameworku je k dispozícií na stiahnutie v článku MPLAB,
bod 3. --> článok
Framework podporuje nespočetne mnoho rodín MCU - PIC, avšak pri aplikácií frameworku na určitý typ procesora je nutné niektoré jeho časti upraviť pre konkrétny typ. Aplikácia alebo skôr nastavenie firmware býva to najťažšie.
Spôsob prenosu dát
Rozvrstvenie a smer komunikácie je rozpísaný na obrázku nižšie.
Firmware rozširuje dve funkcie getsUSBUSART a putsUSBUSART
funkcie |
byte getsUSBUSART(char *buffer, byte len)
void putsUSBUSART(char *data) |
Metoda getsUSBUSART obsahuje dva parametre - pointer typu char (ako ukazateľ na poľe znakov), a parameter typu byte reprezentujúci počet znakov, ktoré sa majú preniesť. Návratová hodnota metody je typu byte a vracia nám počet znakov, ktoré boli z HOSTA (PC) prenesené.
Metoda putsUSBUSART nemá žiadnu návratovú hodnotu, avšak má jeden parameter - ukazateľ na pole znakov. Metoda nám slúži na odosielanie dát do HOSTA (PC).
Obe metody sú cyklicky používané - spracovávané metodou
funkcie |
void ProcessIO(void)
|
Činnosť metody ProcessIO je ukázaná na diagrame aktivit:
Prvým rozhodujúcim blokom sa zistí stav descriptora a konfigurácie USB zariadenia.
Pokiaľ nedošlo k detekovaniu zariadenia, metoda sa ukončí. V opačnom prípade sa zistí, či je firmware schopný príjmať/odosielať dáta medzi HOST <--> MCU.
Pokiaľ áno, zistí, či boli neaké dáta prijaté (návratová hodnota metody getsUSBUSART() nie je nulová). Ak boli dáta prenesené, naplní sa buffer. Obsah bufferu sa obslužnou metodou odošle napríklad na LCD .
Následne sa buffer vyprázdni.
Pred samotným ukončením metody ProcessIO je volaná metoda
funkcie |
void CDCTxService(void)
|
Metoda obstaráva transakcie prenosu - zisťuje, či je vôbec možné prijať/odoslať dáta pred tým, než by k tomu došlo.
FIRMWARE PIC24FJ64GB002
---------------------------------------------------------------------
Podporované procesory: PIC24FJ64GB002
Typ: CDC RS232 sim. SLAVE
Posledná revízia: 29.7 2014
Autor celkovej úpravy: Diallix
---------------------------------------------------------------------
Pre procesor PIC24FJ64GB002 upravím stávajúci firmware, okrešem ho len o režim RS-232, navrhnem spôsob signalizácie a samotný prenos pre príjem dát alebo riadiacích inštrukcií.
Po spustení projektu je jeho rozloženie následovné:
Konfigurácia štruktúr a vlastná implementácia ProcessIO je v headere USB_CDC.h
USB_CDC.h |
void ProcessIO(void)
{ BlinkUSBStatus(); if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(USBUSARTIsTxTrfReady()) { if (USB_Received.ready == 0) { USB_Received.size = getsUSBUSART(USB_....Tmp.Data,USB_....Tmp.buffer_size); if (USB_Received.size > 0) { BYTE cdc_rx_len; for(cdc_rx_len = 0; cdc_rx_len < USB_Received.size; cdc_rx_len++) { if(Keys.Tmp.swt == 2) { USB_....Data.Command[cdc_rx_len] = USB_....Tmp.Data[cdc_rx_len]; } else { USB_Received.Data.Data[cdc_rx_len] = USB_.....Tmp.Data[cdc_rx_len]; } } USB_Received.ready = 1; USB_Transmission_Receive.cp_ptr = 0; } } if(USB_Received.ready) { BlinkUSBStatus(); /* Prijaté dáta sú uložené v poli USB_Received.Data.Data. Pocet prijatých dát je uložený v USB_Received.size. Ďalšie spracovanie - metóda napríklad s "unsigned char*" parametrom + pocet prijatých dát. */ } if(USB_Received.ready) { USB_Received.ready = 0; USB_Received.size = 0; USB_Transmission_Receive.cp_ptr = 0; for(cdc_rx_len = 0; cdc_rx_len < CDC_DATA_IN_EP_SIZE; cdc_rx_len++) { USB_Received.Data.Data[cdc_rx_len] = 0; USB_Received.Data.Command[cdc_rx_len] = 0; USB_Transmission_Receive.Tmp.Data[cdc_rx_len] = 0; } } } CDCTxService(); } |
Oranžovou farbou "..." sú označené skrátené názvy - kôli úzkym proporciám stránky.
Premennou Keys.Tmp.swt zaisťujeme naplnenie riadiacého bufferu (Keys.Tmp.swt==2), napríklad pri nutnosti rozdeľovať vstupný tok dát. V opačnom prípade sa dočasným bufferom naplní dátový buffer.
Ako je v poznámke popísané, s dátami je možné pracovať v vloku označenom " /* */ ".
Obsah main.c
main.c |
#define __NoTypeDef__ //nutne nepouzivat vlastne udajove typy suboru config_.c
#include "config_diall.h" #include "USB_CDC.h" #include "header_wordsf.h" char *PageSys(void) { OSCTUN = 0; RCONbits.SWDTEN = 0; This.Detect.Debug = FALSE; //vypiname moznost debugovania LedStatus.Port = uintptr &PORTB; //nastavujeme register pre detekciu LED pri INIte LedStatus.Led = 0; //pre LED nastavujeme cislo portu USB_Status.Led.Port = uintptr &PORTB; //nastavujeme register pre signalizaciu USB USB_Status.Led.blink = TRUE; //povolujeme signalizaciu LED USB_Status.Led.Led = 0; //pre LED nastavujeme cislo portu return "0x21"; //vraciame hodnotu inicializacie } int main(void) { Init(null,USB_Interface,null,null,null,null); //USB funkciou Init sinicializujeme while(1) { #if defined(USB_INTERRUPT) if(USB_BUS_SENSE && (USBGetDeviceState() == DETACHED_STATE)) { USBDeviceAttach(); } #endif #if defined(USB_POLLING) USBDeviceTasks(); #endif ProcessIO(); } } |
Konfiguračné bity
Teraz sa zameriame na bitovú konfiguráciu MCU. Viacej o konfiguračných bitov je popísané v
článku >>konfiguračné bity<<
Pri zostavovaní zariadenia, požadujeme, aby vedel komunikovať cez USB ako Slave v režime CDC.
Využijeme priamo 4MHz výstup z interného oscilátora. Konfiguráciou konfiguračného bitu FNOSC_FRCPLL
vyberieme vnútorný oscilátor FRC (Fast-Rc-Oscilator) + PPL (Phase-Locked-Loop).
Taktovacia frekvencia MCU sa nastaví 24 zmenou multiplikátora a deliacej hodnoty, ktoré riadia MCU clock.
Konfiguračným bitom PLL96MHZ_ON 96 MHz PLL povolíme automatický štart v MCU. Deliacu hodnotu nastavíme
ako "No Div"bitom PLLDIV_NODIV. Oscilátor vstup využíva priamo ako 4MHz input.
Nastavením bitov POSCMOD_NONE zakážeme hlavný oscilátor, vypneme hodinový prepínač FCKSM_CSDCMD,
FCKSM_CSDCMD,OSCIOFNC_ON nastavíme port RA3 ako I/O - disablujeme defaultný mód portu ako OSCO
(Clock Output).
SOSCSEL_IO zrušíme defaultný mód portov RB4, RA4 sekundárneho oscilátora, ktoré sú v stave (SOSCO, SOSCI)
a nastavíme ich ako I/O. Kompletná realizácia je v kóde 3. Všetky ostatné nepopísané konfiguračné bity vychádzajú z doporučeného zapojenia MCU.
Ostatné nastavenia
Neaké ďalšie nastavenia nie sú nutné.
Projekt stačí extrahovať na lokálny disk C:\.
Projekt sa uloží na lokálny disk pod názvom USB_CDC_Diall_IFACE. Celá cesta: C:\USB_CDC_Diall_IFACE\cdc1.mcp .
Návod na nastavenie ciest je popísaný v kroku 4.3 tu: >>MPLAB návod<<, len je nutné zmeniť koreňový adresár projektu na c:\USB_CDC_Diall_IFACE .