19 декабря 2013 г.

Нататкі аб RL78: Сапраўднае прывітанне праз УАПП

Так склалася, што УАПП з'яўляецца, напэўна, самым распаўсюджаным інтерфесам для сувязі прыбораў з навакольным светам. УАПП гэта Унівярсальны Асінхронны Прыёмма-Перадатчык, або Universal Asyncronous Reciever-Transmitter (UART) па ангельскі.

Прынцып працы

УАПП вызначае лагічны узровень сувязі (фарміраванне байтаў), а фізічныя характэрыстыкі адпавядаюць КМАП тэхналогіі.  Калі ёсць спецыфічныя патрабаванні, фізічны узровень можна замяніць на шэраг іншых: RS232, RS485, LIN, токавая пятля і іншыя.

Байты выглядаюць вось так:

Каб перадаць 8 бітаў інфармацыі, да іх трэба дадаць адзін біт у пачатку (так званы стартавы) і адзін у канцы (стопавы). Колькасць стопавых бітаў можа быць рознай: 1, 2 і нават 1.5. Стартавы біт заўсёды мае значэнне 0, па яму ідзе сінхранізацыя прыёмніка. Існуе шмат розных дадатковых рэжымаў выкарыстання. Напрыклад, бітаў можа быць не 8, а 7 альбо 9, можа прысутнічаць дадатковы біт праверкі цотнасці.

Раней, у кожным ПК можна было знайсці COM парты, якія з'яўляюцца УАПП з фізічнымі ўзроўнямі RS232. Цяпер іх знайсці ў бытавых ПК складана, яго выцясніў USB. Так як патрэба у УАПП не адпала, былі створаны пераўтваральнікі USB у УАПП, напрыклад: CP2102, PL2303, FT232, MCP2200, TUSB3410 і іншыя.

Схема далучэння

У МК ёсць некалькі модуляў УАПП. Сігналы з гэтых модуляў выведзены на парты якія пазначаны як TxD ды RxD. TxD - выхад перадатчыка, а RxD - уваход прыёмніка. Далучаць сігналы трэба так: TxD мікракантролера да RxD ператваральніка USB у УАПП, а RxD мікракантролера да TxD ператваральніка USB у УАПП. Такім чынам выхад перадатчыка МК далучаны да ўвахода ператваральніка інтерфейса.

У гэтым прыкладзе я далучыў вывад TxD0 да TOOL0, каб карыстацца адным провадам для праграмавання мікракантролера і каб атрымліваць паведамленні па УАПП, пасля запуску прашыўкі. Гэта схема працуе ў мяне пры дапамозе праграмы rl78flash, якая, пасля праграмавання, запускае тэрмінал, на які выводзіць тое, што прыходзіць ад МК.

Наладка модуля

Асобнага модуля УАПП ў RL78/G14 няма, іх некалькі і яны аб'яднаны ў масіў, які клічацца Serial Array Unit. Такіх масіваў можа быць некалькі. Кожны з масіваў складаецца з некалькіх каналаў, напрыклад, у масіве 0 іх 4. Нулявы канал можа працаваць як перадатчык УАПП, а першы - як прыёмнік. Разам каналы 0 і 1 клічуцца UART0.

Тут разглядаю толькі перадатчык, таму карыстацца будзем толькі каналам 0. Каб кампутар ды мікракантролер разумелі адзін аднаго, трэба каб фармат дадзеных супадалі на абодвух канцах.

За наладку модуля адказваюць рэгістры:
  • SMRxx - вызначае рэжым працы адпаведнага канала (напрыклад, SMR01 адпавядае каналу 1 у масіве 0);
  • SCRxx - вызначае фармат дадзеных;
  • SDRxx - вызначае хуткасць абмену.
 Ёсць яшчэ рэгістры адказныя за наладкі агульныя да ўсяго масіва:
  • біт SAUxEN - уключае масіў;
  • SPSx - вызначае часціні, якія даступны каналам, для вызначэння хуткасці абмену;
  • SOLx - вызначае інверсію сігналаў (ёсць ці не);
  • SOx - вызначае узровень на выхадзе;
  • SOEx - дазваляе каналу кіраваць выхадам (інакш, выкарыстоўваецца значэнне ў SOx);
  • SSx - уключае працу каналаў;
  • STx - выключае працу каналаў.
Прыклад наладкі:
void uart0_init (void)
{
    /* Configure UART0 */
    SAU0EN = 1; /* Supply clock to serial array unit 0 */
    {
        /* >=4 cycle delay required by manual */
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
    }
    SPS0 = 0x00U; /* Set input clock (CK00 and CK01) to fclk = 16MHz */
    /* Setup operation mode for transmitter (channel 0) */
    SMR00 = 0x0023U; /* Operation clock : CK00,
                        Transfer clock : division of CK00
                        Start trigger : software
                        Detect falling edge as start bit
                        Operation mode : UART
                        Interrupt source : buffer empty
                      */
    SCR00 = 0x8097U; /* Transmission only
                        Reception error interrupt masked
                        Phase clock : type 1
                        No parity
                        LSB first
                        1 stop bit
                        8-bit data length
                      */
    SDR00 = (7U << 9); /* transfer clock : 16 MHz / (7 + 1) / 2 = 1 Mbps */
    SOL0 &= ~0x01U; /* Output is not inverted */
    SO0 |= 0x01U; /* Initial output level is 1 */
    SOE0 |= 0x01U; /* Enable data output */

    /* Configure PM51 as open-drain output */
    POM5 |= (1U << 1);
    P5 |= (1U << 1);
    PM5 &= ~(1U << 1);

    SS0 = 0x01U; /* Enable UART0 transmitter operation (channel 0) */
    STIF0 = 1;
}
Апошні радок патрэбен таму, што флаг будзе выстаўлены пасля першай перадачы і не існуе спосаба адлічыць ці модуль заняты, ці яго толькі што ўключылі.

Адсылка дадзеных

Каб адаслаць адзін байт, трэба яго значэнне запісаць у рэгістр SDRxx. Але каб адаслаць другі, трэба пачакаць, калі модуль будзе здольны прыняць наступны байт. Калі модуль гатовы, флаг перарывання STIFx прымае значэнне 1. Пасля запісу наступнага байта трэба яго абнуліць.
/* Прыклад функцыі адсылкі аднаго байта праз UART0 */
int uart0_putchar (int c)
{
    while (STIF0 == 0);
    STIF0 = 0;
    SDR00 = (unsigned char)c;
    return (unsigned char)c;
}

Адсылка радка - гэта паслядоўная адсылка кожнага байта:
int uart0_puts (const char * s)
{
    while (*s != '\0')
    {
        (void)uart0_putchar(*s++);
    }
    (void)uart0_putchar('\n');
    return 1;
}

Выкарыстанне

Няма нічога прасцей, чым карыстаць гатовыя функціі:
int main(void)
{
    uart0_init();
    (void)uart0_puts("Hello, RL78! [:");
    for(;;);
}

Вынік

Вынік можна пабачыць у тэрмінале:

Альбо пры дапамозе аналізатара:

Увесь зыходны код, а таксама праект гатовы да зборкі можна знайсці тут: https://github.com/msalov/rl78-samples-R5F104FEAFP/tree/master/01-uart

Комментариев нет:

Отправить комментарий