Аппаратные и программные средства встраиваемых систем


  Программирование последовательного канала



Pdf көрінісі
бет235/268
Дата07.01.2022
өлшемі3,23 Mb.
#18255
1   ...   231   232   233   234   235   236   237   238   ...   268
6.3  Программирование последовательного канала 
Простейшим из способов организации последовательного обмена является 
асинхронный  обмен  с  программной  проверкой  готовности.  Примером  такого 
обмена  может  служить  работа  с  контроллером  последовательного  канала 
(UART) МК ADuC812 в стенде SDK-1.1 «по опросу» (см. раздел 2.2.9.1). Если 
требуется  переслать  байт,  то: 1) сбрасывается TI; 2) в SBUF записывается 
нужный  байт  данных;  и 3) ожидается,  пока TI не  будет  установлен 
контроллером. С приемом здесь сложнее: нужно постоянно проверять флаг RI 
и,  если  он  установлен,  то  читать  принятый  байт  из SBUF и  сбрасывать RI. 
Такой  способ  удобен,  когда  разработчику  четко  известно,  когда  произойдет 
прием данных и когда его завершать. Неудобен он тем, что время выполнения 
самой  программы  напрямую  зависит  от  скорости  обмена.  В  самом  деле,  чем 
медленнее  скорость,  тем  дольше  по  времени  цикл  ожидания  готовности  к 
приему/посылке следующего байта.  
Пример программы: 
/*-------------------------------------------------------------------- 
init_sio 
---------------------------------------------------------------------- 
Инициализирует последовательный канал на заданной скорости. 
 
Вход:   char speed - скорость. Задается константами, описанными в  
        заголовочном файле sio.h 
        bit sdouble - дублирование скорости: 0 - не дублировать скорость, 
        заданную аргументом speed; 1 - дублировать. 
Выход:     нет 
Результат: нет 
------------------------------------------------------------------- */ 
void init_sio( unsigned char speed ) 

  TH1    = speed;  
  TMOD   |= 0x20; //Таймер 1 будет работать в режиме autoreload 
  TCON   |= 0x40; //Запуск таймера 1 
  SCON   = 0x50;  //Настройки последовательного канала 
  ES    = 0;      //Запрещение прерываний от приемопередатчика 

 
/*-------------------------------------------------------------------- 
RSioStat 
---------------------------------------------------------------------- 
Возвращает ненулевое значение, если буфер приема не пуст 
 
Вход:      нет 
Выход:     нет 
Результат: 0 - буфер приема пуст
           1 - был принят символ 
------------------------------------------------------------------- */ 
unsigned char rsiostat(void)  


 
250 

  return RI

 
/*-------------------------------------------------------------------- 
wsio 
---------------------------------------------------------------------- 
Отправляет символ по последовательному каналу 
 
Вход:      unsigned char c - символ, который нужно отправить 
Выход:     нет 
Результат: нет 
------------------------------------------------------------------- */ 
void wsio( unsigned char c ) 

  SBUF = c; 
  TI  = 0; 
  while( !TI ); 

 
/*-------------------------------------------------------------------- 
rsio 
---------------------------------------------------------------------- 
Дожидается приема символа из последовательного канала и возвращает его. 
 
Вход:      нет 
Выход:     нет 
Результат: принятый символ 
------------------------------------------------------------------- */ 
unsigned char rsio(void) 

  while( !RI ); 
  RI = 0; 
  return SBUF

 
/*-------------------------------------------------------------------- 
type 
---------------------------------------------------------------------- 
Выводит ASCIIZ-строку в последовательный канал 
 
Вход:      char *str - указатель на строку 
Выход:     нет 
Результат: нет 
------------------------------------------------------------------- */ 
void type(char * str) 

  while( *str ) wsio( *str++ ); 

 
/*-------------------------------------------------------------------- 
main 
--------------------------------------------------------------------*/ 
void main( void ) 

unsigned char c; 
 
    init_sio( S9600 ); 
 
    type("Тест драйвера SIO для стенда SDK-1.1\r\n"); 
    type("Нажимайте кноки для тестирования... \r\n"); 
 
    while( 1 ) 


 
251 
    { 
        if( rsiostat() ) 
        { 
            c = rsio(); 
 
            switch( c ) 
            { 
            case '1': type("\r\ntest 1\r\n"); break; 
            case '2': type("\r\ntest 2\r\n"); break; 
            case '3': type("\r\ntest 3\r\n"); break; 
 
            default: wsio( c );          break;    
            } 
        } 
    } 

 
При организации асинхронного обмена по прерыванию при приеме байта с 
линии  происходит  прерывание  и  передача  управления  соответствующей 
программе-обработчику,  который  читает  принятый  байт  из  порта  данных 
контроллера UART и, к примеру, помещает его в специальный буфер-очередь 
принятых  байт,  доступный  прерванной  программе  (см.  раздел  А.2.4).  По 
завершении  процедуры  обработки  прерывания  управление  передается  в 
прерванную  программу,  которая  при  желании  (в  любом  удобном  месте 
алгоритма)  может  забрать  принятый  байт.  С  другой  стороны,  при  завершении 
отправки  контроллером  очередного  байта  также  происходит  прерывание, 
сигнализирующее  о  том,  что  байт  послан  и  в  буфер UART можно  поместить 
новые  данные.  Обработчик  прерывания,  при  наличии  данных  в  исходящей 
очереди,  записывает  очередной  байт  в  порт  данных  контроллера  и  запускает 
посылку.  Основная  же  программа  может,  не  заботясь  о  готовности  или 
неготовности контроллера принять очередной байт, может спокойно помещать 
данные в исходящий буфер, а всю работу с устройством выполнит обработчик 
прерываний, когда оно (устройство) будет готово. 


Достарыңызбен бөлісу:
1   ...   231   232   233   234   235   236   237   238   ...   268




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет