Difference between revisions of "Talk:Сериен порт"

From Ilianko
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
==php==
 
==php==
  
 +
Инсталира се ser2net и се конфигурира ser2net.conf
  
== Direktno ==
+
После се достъпва като стандартен сокет
Setup serial port
 
<code><pre>
 
stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
 
</pre></code>
 
 
 
  
 
<code><pre>
 
<code><pre>
<?php
 
 
 
if(isset($_POST['message']))
 
if(isset($_POST['message']))
 
{
 
{
   $fp =fopen("/dev/ttyS0", "w");
+
   $fp =fsockopen("localhost", 2000);
 +
 
 
   if( !$fp) {
 
   if( !$fp) {
 
     echo "Error";die();
 
     echo "Error";die();
 
   }
 
   }
 +
  fread($fp, 128);
 +
  fwrite($fp, "$_POST[message]");
 +
  $status = fread($fp, 128);
 +
  fclose($fp);
 +
  
  fwrite($fp, "$_POST[message] \n");
 
  fclose($fp);
 
 
}
 
}
  
Line 28: Line 26:
 
<form name="serial" action="" method="post">
 
<form name="serial" action="" method="post">
 
Message:  <input name="message" type="text"><input type="submit" value="Send">
 
Message:  <input name="message" type="text"><input type="submit" value="Send">
 +
 +
<?= (isset($status))? $status:'' ?>
 
</form>
 
</form>
 
</body>
 
</body>
Line 33: Line 33:
 
</pre></code>
 
</pre></code>
  
 +
== [http://ilianko.com/files/Serial.zip C#] ==
 +
 +
 +
<!--
 +
''Начин на работа'''
 +
1. Намерете десетичния код на ASCII символа.
 +
2. Тествайте следната програма и проверете резултата си от стъпка едно
 +
<code><pre>
 +
/*********************************************************\
 +
* Title:Convertion from character to integer
 +
* Edited by ilianko
 +
\*********************************************************/
 +
 +
#include <stdio.h>
 +
 +
#define ASCII_SYMBOL 'a'
 +
 +
int main()
 +
{
 +
//difine varibles
 +
char ascii = ASCII_SYMBOL;
 +
int code;
 +
 +
//convert types
 +
code = (int) ascii;
 +
 +
//formated output
 +
printf("Desetichniqt kod e %i", code);
 +
return 0;
 +
}
 +
</pre></code>
 +
 +
''Основната причина за съществуване  на различни типове данни е да знае компилатора, колко памет да отдели за всяко число, буква или текст, когато съхранява стойностите им. Информацията се ползва и в последствие, при извеждане или при обработка на данните и взаимодействия с други данни.''
 +
 +
3. Създайте програма, която да извежда всички букви букви от ASCII кода в поредица AbCdEfGh.... yZ
 +
 +
'' '''Упътване''' . Всяка буква отговаря на число, всяка следваща буква е число с едно по-голямо. Главните букви започват от 65, малките от 97, а общо са 26. Може да ползвате:''
 +
<code><pre>
 +
int x = 65;
 +
char y;
 +
y = (char) x;
 +
printf( " %c ", y );
 +
 +
int i = 0;
 +
for (i = 0; i< 26; i = i + 2)
 +
{ ... }
 +
</pre></code>
 +
 +
 +
4. Създайте програма, която след въвеждане на буква от клавиатурата, извежда дали кодът на буквата е с четен или нечетен номер.
 +
 +
'' '''Упътване.''' Може да използвате примера от [[Упражнение 2. Достъп до периферни устройства.|задача 2 на Упражнение 2]] и кодът по-долу.''
 +
<code><pre>
 +
if ( ((int) s) % 2) puts(" .... ");
 +
else puts(" ... ");
 +
</pre></code>
 +
 +
5. Изпълнете програматаза преобразуване на буква в двоичен код, разгледайте кода и пробвайте с различни букви.
 +
 +
<code><pre>
 +
#include <stdio.h>  /* Standard input/output definitions */
 +
 +
#define TESTD 'a'
 +
 +
int main(void)
 +
{
 +
  int z=128, y = 0;
 +
  char a = TESTD;
 +
  char b[9] = "00000000";
 +
       
 +
  for ( y=0;  y < 8;  ++y)
 +
  {
 +
    b[y] = ((a & z) == z) ? '1' : '0';
 +
        /* a = 0 0 1 0 1 0 0 0
 +
          AND
 +
          z = 0 0 0 0 1 0 0 0
 +
          ===================
 +
          r = 0 0 0 0 1 0 0 0 = z */
 +
    z = z >> 1; // <=> z >>= 1  - преместване с един бит
 +
  }
 +
   
 +
  printf("%s \n", b);
 +
  return 0;
 +
}
 +
</pre></code>
 +
 +
'''Проверка по четност'''
 +
 +
6. Преработете кодът от предната задача, така че да ви показва, колко единици има в двоичното число и дали броят на единици е четен или нечетен.
 +
 +
'' '''Упътване''' Може да замените ''
 +
<code><pre>
 +
((a & z) == z) ? '0' : '1';
 +
</pre></code>
 +
със
 +
<code><pre>
 +
int e=0;
 +
...
 +
if((a & z) == z)
 +
{
 +
  ++e;
 +
  b[y] = '1';
 +
}
 +
</pre></code>
 +
-->
 +
==Конфигуриране на системна конзола ==
 +
 +
http://www.cyberciti.biz/faq/howto-setup-serial-console-on-debian-linux/
 +
 +
В Ubuntu управлението на процесите при стартиране се управляват от Upstart програмата (която заменя и е обратно съвместима с init).
 +
*init e процес номер 1, PID - 1, т.е. той стартира всички останали процеси.
 +
*тествайте следната команда <code>ps -A | less</code> - извежда всички процеси. 
 +
 +
 +
След инициализиране на хардуера се стартира програмата '''getty''' и следват следните стъпки за вход:
 +
*'''getty''' извежда съобщението за вход
 +
*потребителят въвежда името на акаунта
 +
*'''getty''' стартира програмата '''login''' с параметър въведеното име
 +
*'''login''' изисква парола и проверя дали акаунтът е валиден в /etc/shadow
 +
*при валиден акаунт '''login''' извежда текущи съобщения от /etc/motd и стартира шел програма (примерно bash)
 +
*'''bash''' налични стартиращи скриптове (.bashrc)
 +
*'''bash''' извежда промта и чака команди
 +
 +
По подразбиране в Ubuntu getty се стартира на виртуални терминали от tty1 до tty6, на tty7 се стартира графичната система.
 +
За да се стартира getty и на серийния порт, то трябва да се добави файл '''/etc/init/ttyS0.conf''' със следното съдържание:
 +
<code><pre>
 +
# ttyS0 - getty
 +
#
 +
# This service maintains a getty on ttyS0 from the point the system is
 +
# started until it is shut down again.
 +
 +
start on stopped rc or RUNLEVEL=[2345]
 +
stop on runlevel [!2345]
 +
 +
respawn
 +
exec /sbin/getty -L 9600 ttyS0 vt102
 +
</pre></code>
 +
 +
След което да се рестартира компютъра или да се стартира процеса с командата
 +
sudo start ttyS0
 +
 +
След така направената конфигурация Linux системата е достъпна през сериен порт
 +
 +
Връзки
 +
*[https://help.ubuntu.com/community/SerialConsoleHowto конфигуриране терминал в Ubuntu]
 +
*[http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/term.html freeBSD]
 +
*[http://superuser.com/questions/122353/how-can-i-login-to-ubuntu-using-a-usb-serial-port USB сериен порт UBUNTU > 10.4]
 +
*[http://versalogic.com/kb/KB.asp?kbid=1551 конфигуриране терминал в Debian с Getty]
 +
 +
 +
'''Задача''' Влезте в Ubuntu през системнатa конзола и тествайте командите:
 +
*reboot,
 +
*halt,
 +
*shutdown.
 +
 +
== [[Управление на сериен порт с POSIX|Комуникация през C, POSIX и сериен порт]] ==
 +
'''Задача ''' Тествайте програмата, която изпраща информация по-серийния порт. Свържете два компютъра със сериен кабел, като на единия изпълнявате програмата, а на другия сте включили, някоя от терминалните програми за управление на серийната връзка от предходната задача. Тествайте с различни съобщения.
 +
 +
 +
<code><pre>
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <stdlib.h>
 +
#include <signal.h>
 +
#include <sys/wait.h>
 +
#include <sys/types.h>
 +
#include <fcntl.h>
 +
#include <termios.h>
 +
 +
void handler(int nsig)
 +
{
 +
  int status;
 +
 
 +
  //wait for change in child
 +
  wait(&status);
 +
 
 +
  if(WIFEXITED(status))
 +
  {  //if child is exited
 +
    printf("Thank You!\n");
 +
    exit(0);
 +
  }
 +
}
 +
 +
int main()
 +
{
 +
  int pid, serial;
 +
  char ch;
 +
  struct termios oIn, nIn, oSerial, nSerial;
 +
   
 +
  //open serial port
 +
  serial = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
 +
 
 +
  // Signal handler
 +
  (void) signal(SIGCHLD, handler);
 +
   
 +
  // Current configuration
 +
  tcgetattr(0,&oIn);
 +
  tcgetattr(0,&nIn);
 +
  tcgetattr(serial,&oSerial);
 +
  tcgetattr(serial,&nSerial);
 +
   
 +
  // Raw mode
 +
  nIn.c_lflag = 0;
 +
  nSerial.c_lflag = 0;
 +
 
 +
  // Set new configuration
 +
  tcsetattr(0, TCSANOW, &nIn); //stdin
 +
  tcsetattr(serial, TCSANOW, &nSerial);
 +
   
 +
  write(1,"For exit press \'q\' \n", 20);   
 +
   
 +
  fflush(stdout);
 +
  fflush(stdin);
 +
   
 +
  // Create new process
 +
  pid = fork();
 +
 +
  while(1)
 +
  {
 +
    if(pid < 1)
 +
    {  // child process
 +
        read(0,&ch,1); // read stdin
 +
        write(serial,&ch, 1); //write to serial port
 +
       
 +
        if(ch == 'q')
 +
        {
 +
          tcsetattr(0, TCSANOW, &oIn); //restore original configuration
 +
          tcsetattr(serial, TCSANOW, &oSerial);
 +
          exit(0);
 +
        }
 +
      }
 +
    else
 +
    {  // parent process
 +
        read(serial,&ch,1);
 +
        write(1,&ch, 1);
 +
    }
 +
  }
 +
  return(0);
 +
}
 +
</pre></code>
  
=== [http://ilianko.com/files/php_serial.class.php php_serial.clas] ===
 
  
 
<code><pre>
 
<code><pre>
<?php
+
/*********************************************************\
     include "php_serial.class.php";
+
* Title: Write to serial port
 +
* http://www.easysw.com/~mike/serial/serial.html
 +
* Edited by ilianko
 +
\*********************************************************/
 +
 
 +
#include <stdio.h>  /* Standard input/output definitions */
 +
#include <string.h>  /* String function definitions */
 +
#include <unistd.h>  /* UNIX standard function definitions */
 +
#include <fcntl.h>  /* File control definitions */
 +
#include <errno.h>  /* Error number definitions */
 +
#include <termios.h> /* POSIX terminal control definitions */
 +
 
 +
#define PORTNAME  "/dev/ttyS0"
 +
 
 +
int main(void)
 +
{
 +
    int fd; // File descriptor for the port
 +
    struct termios options; // Serial port settings
 +
 +
//Open for reading and writing + special FIFO port settings
 +
    fd = open( PORTNAME, O_RDWR | O_NOCTTY | O_NONBLOCK);
 +
 +
     if (fd == -1)//Could not open the port.
 +
{
 +
perror("open_port: Unable to open port");
 +
    }
 +
    else
 +
    {
 +
//reset of file flags
 +
fcntl(fd, F_SETFL, 0);
 +
}
 +
   
 +
    tcgetattr(fd, &options);      //read controller settings
 +
   
 +
   
 +
    cfsetispeed(&options, B2400); // change input speed
 +
    cfsetospeed(&options, B2400); // change output speed
 +
   
 +
    options.c_cflag |= ( CREAD);  // enable reciever
 +
    options.c_cflag |= ( CLOCAL); // Local line - do not change "owner" of port
 +
    options.c_cflag &= ( ~CSTOPB); // set 1 stop bit
 +
   
 +
    tcsetattr(fd,TCSANOW, &options); // load the controller settings
  
     // Let's start the class
+
     write(fd, "a \n", 3); //write to 3 byte to the serial port
     $serial = new phpSerial();
+
         
 +
     return 0;
 +
}
 +
</pre></code>
  
    // First we must specify the device. This works on both Linux and Windows (if
+
За повече информация [[Управление на сериен порт с POSIX]], [http://www.easysw.com/~mike/serial/serial.html POSIX serial port]
    // your Linux serial device is /dev/ttyS0 for COM1, etc.)
 
    $serial->deviceSet("/dev/ttyUSB0");
 
  
    // Set for 9600-8-N-1 (no flow control)
+
== Осцилограма ==
    $serial->confBaudRate(9600); //Baud rate: 9600
 
    $serial->confParity("none");  //Parity (this is the "N" in "8-N-1")
 
    $serial->confCharacterLength(8); //Character length    (this is the "8" in "8-N-1")
 
    $serial->confStopBits(1);  //Stop bits (this is the "1" in "8-N-1")
 
    $serial->confFlowControl("none");
 
  
    // Then we need to open it
+
'''Задача''' Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал.
    $serial->deviceOpen();
 
  
    // Read data
+
== Четене сериен порт ==
    $read = $serial->readPort();
 
  
     // Print out the data
+
=== Raw ===
     echo $read;
+
<code><pre>
 +
/****************************************************************\
 +
* Edited by Ilianko
 +
* http://www.easysw.com/~mike/serial/serial.html
 +
* Description: Raw reading of the serial port
 +
\****************************************************************/
 +
#include <termios.h>
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <fcntl.h>
 +
     
 +
#define BAUDRATE B2400
 +
#define MODEMDEVICE "/dev/ttyUSB2"
 +
     
 +
int  main()
 +
{
 +
int fd, c, res, stop = 0;
 +
    struct termios oldtio,newtio;
 +
    char buf[255];
 +
       
 +
    /* open the device to be non-blocking (read will return immediatly) */
 +
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
 +
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
 +
       
 +
    fcntl(fd, F_SETFL, 0);
 +
fcntl(fd, F_SETFL, FNDELAY);       
 +
       
 +
    tcgetattr(fd,&oldtio); /* save current port settings */
 +
       
 +
     /* set new port settings for canonical input processing */
 +
    newtio.c_cc[VMIN]=1;
 +
    newtio.c_cc[VTIME]=0;
 +
   
 +
    newtio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
 +
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
 +
    newtio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 +
           
 +
tcsetattr(fd,TCSANOW,&newtio);
 +
 +
tcflush(fd, TCIFLUSH);
 +
 +
/* loop while waiting for input. normally we would do something */
 +
     while ( stop == 0)
 +
{
 +
usleep(100);
 +
        fflush (stdout);
 +
        res = read(fd,buf,10);
 +
       
 +
        // strcat(buf,buf2);
 +
         
 +
        for( c=0; c<res; c++)
 +
        {
 +
          printf("%c", (char) buf[c]);
 +
        }
 +
}
 +
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 +
return 0;
 +
}
 +
</pre></code>
  
    // If you want to change the configuration, the device must be closed.
+
=== Canonical ===
     $serial->deviceClose();
+
<code><pre>
?>
+
/****************************************************************\
 +
* Edited by Ilianko
 +
* Description: Raw reading of the serial port
 +
\****************************************************************/
 +
 
 +
#include <termios.h>
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <fcntl.h>
 +
     
 +
#define BAUDRATE B2400
 +
#define MODEMDEVICE "/dev/ttyUSB2"
 +
     
 +
int  main()
 +
{
 +
int fd, c, res, stop = 0;
 +
    struct termios oldtio,newtio;
 +
    char buf[255];
 +
       
 +
    /* open the device to be non-blocking (read will return immediatly) */
 +
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
 +
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
 +
       
 +
    fcntl(fd, F_SETFL, 0);
 +
fcntl(fd, F_SETFL, FNDELAY);       
 +
       
 +
    tcgetattr(fd,&oldtio); /* save current port settings */
 +
       
 +
    /* set new port settings for canonical input processing */
 +
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
 +
    newtio.c_iflag = IGNPAR | ICRNL;
 +
     newtio.c_oflag = 0;
 +
    newtio.c_lflag = ICANON;
 +
         
 +
    newtio.c_cc[VMIN]=1;
 +
    newtio.c_cc[VTIME]=0;
 +
       
 +
tcsetattr(fd,TCSANOW,&newtio);
 +
tcflush(fd, TCIFLUSH);
 +
 +
 +
/* loop while waiting for input. normally we would do something */
 +
    while ( stop == 0)
 +
{
 +
usleep(100);
 +
        fflush (stdout);
 +
        res = read(fd,buf,10);
 +
       
 +
        for( c=0; c<res; c++)
 +
        {
 +
          printf("%c", (char) buf[c]);
 +
        }
 +
       
 +
}
 +
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 +
return 0;
 +
}
 +
</pre></code>
 +
 
 +
== Самостоятелна подготовка ==
 +
#Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал.
 +
#Да се напише програма, която изпраща символите от клавиатурата към серийния порт.
 +
#Която да се логва през системната конзола и да рестартира Linux системата.
 +
 
 +
== Край ==
 +
 
 +
''' Задача 11 ''' Деинсталирайте GTKterm.
 +
 
 +
'' '''Упътване:''' Използвайте командата.
 +
<code><pre>
 +
:~$ sudo apt-get purge gtkterm
 
</pre></code>
 
</pre></code>
 +
 +
 +
== Литература ==
 +
http://en.wikipedia.org/wiki/RS-232
 +
https://learn.sparkfun.com/tutorials/serial-communication/wiring-and-hardware

Latest revision as of 18:18, 23 February 2015

php

Инсталира се ser2net и се конфигурира ser2net.conf

После се достъпва като стандартен сокет

if(isset($_POST['message']))
{
  $fp =fsockopen("localhost", 2000);
  
  if( !$fp) {
    echo "Error";die();
  }
  fread($fp, 128);
  fwrite($fp, "$_POST[message]");
  $status = fread($fp, 128);
  fclose($fp);


}

?>
<html><head></head>
<body>
<form name="serial" action="" method="post">
Message:  <input name="message" type="text"><input type="submit" value="Send">

<?= (isset($status))? $status:'' ?>
</form>
</body>
</html>

C#

Конфигуриране на системна конзола

http://www.cyberciti.biz/faq/howto-setup-serial-console-on-debian-linux/

В Ubuntu управлението на процесите при стартиране се управляват от Upstart програмата (която заменя и е обратно съвместима с init).

  • init e процес номер 1, PID - 1, т.е. той стартира всички останали процеси.
  • тествайте следната команда ps -A | less - извежда всички процеси.


След инициализиране на хардуера се стартира програмата getty и следват следните стъпки за вход:

  • getty извежда съобщението за вход
  • потребителят въвежда името на акаунта
  • getty стартира програмата login с параметър въведеното име
  • login изисква парола и проверя дали акаунтът е валиден в /etc/shadow
  • при валиден акаунт login извежда текущи съобщения от /etc/motd и стартира шел програма (примерно bash)
  • bash налични стартиращи скриптове (.bashrc)
  • bash извежда промта и чака команди

По подразбиране в Ubuntu getty се стартира на виртуални терминали от tty1 до tty6, на tty7 се стартира графичната система. За да се стартира getty и на серийния порт, то трябва да се добави файл /etc/init/ttyS0.conf със следното съдържание:

# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc or RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -L 9600 ttyS0 vt102

След което да се рестартира компютъра или да се стартира процеса с командата

sudo start ttyS0

След така направената конфигурация Linux системата е достъпна през сериен порт

Връзки


Задача Влезте в Ubuntu през системнатa конзола и тествайте командите:

  • reboot,
  • halt,
  • shutdown.

Комуникация през C, POSIX и сериен порт

Задача Тествайте програмата, която изпраща информация по-серийния порт. Свържете два компютъра със сериен кабел, като на единия изпълнявате програмата, а на другия сте включили, някоя от терминалните програми за управление на серийната връзка от предходната задача. Тествайте с различни съобщения.


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>

void handler(int nsig)
{
  int status;
  
  //wait for change in child 
  wait(&status);
  
  if(WIFEXITED(status))
  {  //if child is exited
    printf("Thank You!\n");
    exit(0);
  }
}

int main()
{
  int pid, serial;
  char ch;
  struct termios oIn, nIn, oSerial, nSerial;
    
  //open serial port
  serial = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
  
  // Signal handler
  (void) signal(SIGCHLD, handler);
    
  // Current configuration
  tcgetattr(0,&oIn);
  tcgetattr(0,&nIn);
  tcgetattr(serial,&oSerial);
  tcgetattr(serial,&nSerial);
    
  // Raw mode 
  nIn.c_lflag = 0;
  nSerial.c_lflag = 0;
  
  // Set new configuration
  tcsetattr(0, TCSANOW, &nIn); //stdin
  tcsetattr(serial, TCSANOW, &nSerial);
    
  write(1,"For exit press \'q\' \n", 20);    
    
  fflush(stdout);
  fflush(stdin);
    
  // Create new process
  pid = fork();

  while(1)
  {
     if(pid < 1)
     {  // child process
        read(0,&ch,1); // read stdin
        write(serial,&ch, 1); //write to serial port
        
        if(ch == 'q')
        {
           tcsetattr(0, TCSANOW, &oIn); //restore original configuration
           tcsetattr(serial, TCSANOW, &oSerial);
           exit(0);
        }
      }
     else
     {  // parent process
        read(serial,&ch,1);
        write(1,&ch, 1);
     }
  }
  return(0);
}


/*********************************************************\
 * Title: Write to serial port
 * http://www.easysw.com/~mike/serial/serial.html
 * Edited by ilianko
\*********************************************************/

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

#define PORTNAME  "/dev/ttyS0"

int main(void)
{
    int fd; // File descriptor for the port 
    struct termios options; // Serial port settings
	
	//Open for reading and writing + special FIFO port settings
    fd = open( PORTNAME, O_RDWR | O_NOCTTY | O_NONBLOCK);
	
    if (fd == -1)//Could not open the port.
	{
		perror("open_port: Unable to open port");
    }
    else 
    {
		//reset of file flags
		fcntl(fd, F_SETFL, 0);
	}
    
    tcgetattr(fd, &options);      //read controller settings
    
    
    cfsetispeed(&options, B2400); // change input speed
    cfsetospeed(&options, B2400); // change output speed
    
    options.c_cflag |= ( CREAD);  // enable reciever 
    options.c_cflag |= ( CLOCAL); // Local line - do not change "owner" of port
    options.c_cflag &= ( ~CSTOPB); // set 1 stop bit
    
    tcsetattr(fd,TCSANOW, &options); // load the controller settings

    write(fd, "a \n", 3); //write to 3 byte to the serial port
           
    return 0;
}

За повече информация Управление на сериен порт с POSIX, POSIX serial port

Осцилограма

Задача Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал.

Четене сериен порт

Raw

/****************************************************************\
 * Edited by Ilianko
 * http://www.easysw.com/~mike/serial/serial.html
 * Description: Raw reading of the serial port
\****************************************************************/
#include <termios.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
      
#define BAUDRATE B2400
#define MODEMDEVICE "/dev/ttyUSB2"
       
int  main()
{
	int fd, c, res, stop = 0;
    struct termios oldtio,newtio;
    char buf[255];
        
    /* open the device to be non-blocking (read will return immediatly) */
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
        
    fcntl(fd, F_SETFL, 0);
	fcntl(fd, F_SETFL, FNDELAY);        
        
    tcgetattr(fd,&oldtio); /* save current port settings */
        
    /* set new port settings for canonical input processing */
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
    
    newtio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
            
	tcsetattr(fd,TCSANOW,&newtio);
	
	tcflush(fd, TCIFLUSH);
	
	/* loop while waiting for input. normally we would do something */
    while ( stop == 0)
	{
		usleep(100); 
        fflush (stdout);
        res = read(fd,buf,10);
        
        // strcat(buf,buf2);
          
        for( c=0; c<res; c++)
        {
           printf("%c", (char) buf[c]);
        }
	}
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 return 0;
 }

Canonical

/****************************************************************\
 * Edited by Ilianko
 * Description: Raw reading of the serial port
\****************************************************************/

#include <termios.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
      
#define BAUDRATE B2400
#define MODEMDEVICE "/dev/ttyUSB2"
       
int  main()
{
	int fd, c, res, stop = 0;
    struct termios oldtio,newtio;
    char buf[255];
        
    /* open the device to be non-blocking (read will return immediatly) */
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
        
    fcntl(fd, F_SETFL, 0);
	fcntl(fd, F_SETFL, FNDELAY);        
        
    tcgetattr(fd,&oldtio); /* save current port settings */
        
    /* set new port settings for canonical input processing */
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;
           
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
        
	tcsetattr(fd,TCSANOW,&newtio);
	tcflush(fd, TCIFLUSH);
	
	
	/* loop while waiting for input. normally we would do something */
    while ( stop == 0)
	{
		usleep(100); 
        fflush (stdout);
        res = read(fd,buf,10);
         
        for( c=0; c<res; c++)
        {
           printf("%c", (char) buf[c]);
        }
        
	}
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 return 0;
 }

Самостоятелна подготовка

  1. Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал.
  2. Да се напише програма, която изпраща символите от клавиатурата към серийния порт.
  3. Която да се логва през системната конзола и да рестартира Linux системата.

Край

Задача 11 Деинсталирайте GTKterm.

Упътване: Използвайте командата.

:~$ sudo apt-get purge gtkterm


Литература

http://en.wikipedia.org/wiki/RS-232 https://learn.sparkfun.com/tutorials/serial-communication/wiring-and-hardware