Difference between revisions of "Сериен порт"
Line 154: | Line 154: | ||
Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал. | Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал. | ||
+ | == Четене сериен порт == | ||
+ | |||
+ | === Raw === | ||
+ | |||
+ | |||
+ | === Canonical === | ||
+ | <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_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> | ||
== Самостоятелна подготовка == | == Самостоятелна подготовка == | ||
1. Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал. | 1. Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал. |
Revision as of 19:39, 15 February 2012
Contents
Цел на упражнението
Преговор типове данни, оператори. Достъп до сериен порт.
Променливи
Разгледайте различните типове данни в C.
Основната причина за съществуване на различни типове данни е да знае компилатора, колко памет да отдели за всяко число, буква или текст, когато съхранява стойностите им. Информацията се ползва и в последствие, при извеждане или при обработка на данните и взаимодействия с други данни.
Задача 1. Създайте програма, която да преобразува числото 65 в символ и да го извежда.
Упътване . Използвайте:
int x = 65;
char y;
y = (char) x;
printf( " %c ", y );
Задача 2. Създайте програма, която да извежда всички букви букви от ASCII кода в поредица AbCdEfGh.... yZ
Упътване . Всяка буква отговаря на число, всяка следваща буква е число с едно по-голямо. Главните букви започват от 65, малките от 97, а общо са 26. Може да ползвате:
int i = 0;
for (i = 0; i< 26; i = i + 2)
{ ... }
Задача 3. Създайте програма, която след въвеждане на буква от клавиатурата,извежда дали кодът на буквата е с четен или нечетен номер.
Упътване. Може да използвате примера от задача 2 на Упражнение 2 и кодът по-долу.
if ( ((int) s) % 2) puts(" .... ");
else puts(" ... ");
Задача 4. Преобразуване на буква в двоичен код. Изпълнете програмата, разгледайте кода и пробвайте с различни букви.
#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;
}
Проверка по четност
Задача 5 Преработете кодът от предната задача, така че да ви показва, колко единици има в двоичното число и дали броят на единици е четен или нечетен.
Упътване Може да замените
((a & z) == z) ? '0' : '1';
със
int e=0;
...
if((a & z) == z)
{
++e;
b[y] = '1';
}
Инсталация GTKTerm
Задача 6. Инсталирайте терминалната програма за комуникация през сериен порт GTKterm.
Упътване: Използвайте командата по-долу. След инсталацията може да намерите програмата в Applications -> Accessories.
:~$ sudo apt-get install gtkterm
Комуникация през терминал и сериен порт
Задача 8. Заредете Windows и Linux на два съседни компютъра. Свържете двата компютъра със сериен кабел през RS232 порта.
За Windows: стартирайте START -> Programs -> Accessories -> Communications -> Hyper Terminal
За Linux: стартирайте инсталираната програма в задача 6.
Настройте двете програми да предават и приемат с еднакви параметри.
Тествайте различни скорости на предаване и приемане.
Комуникация през C, POSIX и сериен порт
Задача 9. Създайте програма, която да изпраща информация по-серийния порт. Свържете два компютъра със сериен кабел, като на единия изпълнявате програмата, а на другия сте включили, някоя от терминалните програми за управление на серийната връзка от предходната задача.
#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
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
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &options);
cfsetispeed(&options, B2400);
cfsetospeed(&options, B2400);
options.c_cflag |= ( CREAD);
options.c_cflag |= ( CLOCAL);
options.c_cflag &= ( ~CSTOPB);
tcsetattr(fd,TCSANOW, &options);
write(fd, "a \n", 3); //write to serial port
return 0;
}
За повече информация Управление на сериен порт с POSIX, [POSIX serial port]
Задача 1
Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал.
Четене сериен порт
Raw
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_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;
}
Самостоятелна подготовка
1. Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал. 1. Да се напише програма, която изпраща символите от клавиатурата към серийния порт.
Край
Задача 11 Деинсталирайте GTKterm.
Упътване: Използвайте командата.
:~$ sudo apt-get purge gtkterm