الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

القرأه من السيريال بورت

مغلق
بدأه medo1976 في 7 أبريل 2005 · 11 رد · 2,353 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمه الله وبركاته

هل من مصدر او مساعده بلغه السى او السى ++ لمعرفه كيف اقوم بالقرأه من السيريال بورت حيث انى صممت دائره ارسال وهى تعمل بنجاج واريد قرأه البيانات المرسله الى السيريال بورت

وشكرا لكم

#2

العديد من الطرق لفعل ذلك , منها ماهو متبع مع المنفذ المتوازي ل LPT هنا فقط غير العنوان بعنوان COM PORT المطلوب وسيعمل مباشرة :

/index.php?showtopic=36111

وطرق أخرى كما فعلها الأخ في هذا الموضوع :

/index.php?showtopic=47025

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#3

اخى الحبيب ارجو منك معروفا انا ابرمج بالبورلاند سى 5.02

واريد ان اعمل البرنامج ليعمل تحت بيئه الدوس

اعذرنى فانى مبتدئ فى السى ++

وهناك امر اخر على طول تظهر هذه الرساله فى بعض الامثله التى اتعلم منا #error BGI graphics not supported under Windows

وهذا هو المثال

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#include <graph.h>

void main(void)

{

unsigned int horz, vert, lang, temp;

unsigned char vermaj, vermin, buttns;

_setvideomode(_TEXTC80);

// turn cursor off

_asm {

mov ah,01h

mov ch,20h

int 10h

}

_asm {

xor ax,ax

int 33h

mov temp,00h

jz short ResetD

mov temp,0FFFFh

ResetD:

}

if (temp) {

printf("Error while reseting mouse\n");

exit(-1);

}

printf("Mouse Language Used: ");

_asm {

mov ax,23h

int 33h

mov lang,bx

}

switch(lang) {

case 0: printf("English\n");

break;

case 1: printf("French\n");

break;

case 2: printf("Dutch\n");

break;

case 3: printf("German\n");

break;

case 4: printf("Swedish\n");

break;

case 5: printf("Finnish\n");

break;

case 6: printf("Spanish\n");

break;

case 7: printf("Portugues\n");

break;

case 8: printf("Italian\n");

break;

}

_asm {

mov ax,24h

int 33h

mov vermaj,bh

mov vermin,bl

}

printf("Mouse driver version: ");

printf("%u.%u\n", vermaj, vermin);

printf("Setting Cursor Position to 50, 12\n");

_asm {

mov cx,50 * 8

mov dx,12 * 8

mov ax,04h

int 33h

}

printf("Setting boundries at 30,5 and 70,20\n");

_settextposition(6, 31); printf("*");

_settextposition(6, 71); printf("*");

_settextposition(21, 31); printf("*");

_settextposition(21, 71); printf("*");

// set horzontal coords.

_asm {

mov cx,30 * 8

mov dx,70 * 8

mov ax,07h

int 33h

}

// set vertical coords.

_asm {

mov cx,5 * 8

mov dx,20 * 8

mov ax,08h

int 33h

}

// Mouse on

_asm {

mov ax,01h

int 33h

}

do {

// get mouse status (buttons and pos)

_asm {

mov ax,03h

int 33h

mov buttns,bl

mov horz,cx

mov vert,dx

}

_settextposition(10, 7);

printf(" Horz: %u ", horz>>3 );

_settextposition(11, 7);

printf(" Vert: %u ", vert>>3 );

_settextposition(12, 7);

printf(" Left Button: ");

if (buttns & 1) printf("Pressed"); else printf(" ");

_settextposition(13, 7);

printf("Right Button: ");

if (buttns & 2) printf("Pressed"); else printf(" ");

} while (!kbhit());

// Mouse off

_asm {

mov ax,02h

int 33h

}

// turn cursor on

_asm {

mov ah,01h

mov cx,0607h

int 10h

}

exit (0);

}

وشكرا وارجو ان لا اكون اثقلت عليك

#4
#include <graph.h>

void main(void)
{
unsigned int horz, vert, lang, temp;
unsigned char vermaj, vermin, buttns;

_setvideomode(_TEXTC80);

// turn cursor off
_asm {
mov ah,01h
mov ch,20h
int 10h
}

_asm {
xor ax,ax
int 33h
mov temp,00h
jz short ResetD
mov temp,0FFFFh
ResetD:
}

if (temp) {
printf("Error while reseting mouse\n");
exit(-1);
}

printf("Mouse Language Used: ");
_asm {
mov ax,23h
int 33h
mov lang,bx
}
switch(lang) {
case 0: printf("English\n");
break;
case 1: printf("French\n");
break;
case 2: printf("Dutch\n");
break;
case 3: printf("German\n");
break;
case 4: printf("Swedish\n");
break;
case 5: printf("Finnish\n");
break;
case 6: printf("Spanish\n");
break;
case 7: printf("Portugues\n");
break;
case 8: printf("Italian\n");
break;
}

_asm {
mov ax,24h
int 33h
mov vermaj,bh
mov vermin,bl
}
printf("Mouse driver version: ");
printf("%u.%u\n", vermaj, vermin);

printf("Setting Cursor Position to 50, 12\n");
_asm {
mov cx,50 * 8
mov dx,12 * 8
mov ax,04h
int 33h
}

printf("Setting boundries at 30,5 and 70,20\n");
_settextposition(6, 31); printf("*");
_settextposition(6, 71); printf("*");
_settextposition(21, 31); printf("*");
_settextposition(21, 71); printf("*");

// set horzontal coords.
_asm {
mov cx,30 * 8
mov dx,70 * 8
mov ax,07h
int 33h
}
// set vertical coords.
_asm {
mov cx,5 * 8
mov dx,20 * 8
mov ax,08h
int 33h
}

// Mouse on
_asm {
mov ax,01h
int 33h
}

do {
// get mouse status (buttons and pos)
_asm {
mov ax,03h
int 33h
mov buttns,bl
mov horz,cx
mov vert,dx
}
_settextposition(10, 7);
printf(" Horz: %u ", horz>>3 );
_settextposition(11, 7);
printf(" Vert: %u ", vert>>3 );
_settextposition(12, 7);
printf(" Left Button: ");
if (buttns & 1) printf("Pressed"); else printf(" ");
_settextposition(13, 7);
printf("Right Button: ");
if (buttns & 2) printf("Pressed"); else printf(" ");
} while (!kbhit());

// Mouse off
_asm {
mov ax,02h
int 33h
}

// turn cursor on
_asm {
mov ah,01h
mov cx,0607h
int 10h
}

exit (0);
}

للتسهيل في عملية القرائه

#5

Info :Compiling C:\bc5\bin\proj0000.cpp

Error: proj0000.cpp(8,15):Call to undefined function '_setvideomode'

Error: proj0000.cpp(8,24):Undefined symbol '_TEXTC80'

Error: proj0000.cpp(27,8):Call to undefined function 'printf'

Error: proj0000.cpp(28,6):Call to undefined function 'exit'

Error: proj0000.cpp(76,18):Call to undefined function '_settextposition'

Error: proj0000.cpp(121,17):Call to undefined function 'kbhit'

Error: proj0000.cpp(127,1):Compound statement missing }

هذا الخطأ ظهر ولا اعرف ما هو الحل

#6

الGraphics التي تستخدم ال BGI لا تعمل على ال Windows و لكنها للDOS فقط لانها قديمة جدا و لم تعد الWindows تدعمها منذ Windows 3.11 و يمكنك استخدام ال DOS Prompt لتشغيل هذه البرامج التي تستخدم هذا النوع من ال Graphics

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#7

الأخ medo1976

احب أن اوضح نقطه قد تكون غائبه عنك وهي أن عملية الاتصال تخضع لأوامر المرسل

فيجب ان يكون المستقبل في حالة استماع طوال الوقت لقرائة البيانات بمجرد وصولها , لأن اي تاخير في قرائة البيانات المستقبلة معناه ضياع البيانات لن المرسل مستمر في الارسال

لهذا يحتاج البرنامج الى أن يكون في حلقة تكراريه لا يخرج منها الا لانهاء البرنامج ووظيفة هذه الحلقه مراقبة المنفذ والقرائة منه عند ورود بيانات جديده

وهذه الطريقه اذا أردت تطبيقها في برامج للـ 16 بيت مثل DOS ستمنعك من عمل اي شيء آخر في البرنامج سوي القرائه من المنفذ ولن تستطيع التعامل مع المستخدم أو اي شيء آخر

وهذا لأن النظام لا يدعم الـ Threading وهو تعدد المهام أي أنك لن تستطيع تشغيل أكثر من اجراء على التوازي

ولكن مايدعم هذا هو أنظمة 32 بيت مثل Windows , Linux , DOS 32bit

لذلك أنصحك ببناء البرنامج للعمل على أي منهم

أما اذا كنت مصمم على أن تعمل على نظام 16 بيت وستتولى عملية التبديل بين الاجراءات بنفسك فيمكنك استخدام مقاطعة الدوس في الأسمبلي وبالتحديد Int 14 الدالة 2

حيث ستقوم باستلام البيانات بايت بــ بايت

و اعزرني مليش في الجرافيكس

#8

بسم الله الرحمن الرحيم

اخى bashmohandes

اقتباس
الGraphics التي تستخدم ال BGI لا تعمل على ال Windows و لكنها للDOS فقط لانها قديمة جدا و لم تعد الWindows تدعمها منذ Windows 3.11 و يمكنك استخدام ال DOS Prompt لتشغيل هذه البرامج التي تستخدم هذا النوع من ال Graphics

كيف اخى الحبيب؟؟

الأخ medo1976

احب أن اوضح نقطه قد تكون غائبه عنك وهي أن عملية الاتصال تخضع لأوامر المرسل

فيجب ان يكون المستقبل في حالة استماع طوال الوقت لقرائة البيانات بمجرد وصولها , لأن اي تاخير في قرائة البيانات المستقبلة معناه ضياع البيانات لن المرسل مستمر في الارسال

لهذا يحتاج البرنامج الى أن يكون في حلقة تكراريه لا يخرج منها الا لانهاء البرنامج ووظيفة هذه الحلقه مراقبة المنفذ والقرائة منه عند ورود بيانات جديده

وهذه الطريقه اذا أردت تطبيقها في برامج للـ 16 بيت مثل DOS ستمنعك من عمل اي شيء آخر في البرنامج سوي القرائه من المنفذ ولن تستطيع التعامل مع المستخدم أو اي شيء آخر

وهذا لأن النظام لا يدعم الـ Threading وهو تعدد المهام أي أنك لن تستطيع تشغيل أكثر من اجراء على التوازي

ولكن مايدعم هذا هو أنظمة 32 بيت مثل Windows , Linux , DOS 32bit

لذلك أنصحك ببناء البرنامج للعمل على أي منهم

أما اذا كنت مصمم على أن تعمل على نظام 16 بيت وستتولى عملية التبديل بين الاجراءات بنفسك فيمكنك استخدام مقاطعة الدوس في الأسمبلي وبالتحديد Int 14 الدالة 2

حيث ستقوم باستلام البيانات بايت بــ بايت

و اعزرني مليش في الجرافيكس

اخى asm4all

اريد جدول بجميع ارقام ال intrrupt numbers

وكيفيه التعامل معها

ارجو الا اكون اثقلت عليك

وشكرا

#9

تفضل يا أخي مكتبه كامله تحتوي على كل المقاطعات واوامر الأسمبلي , مفيده جدا

بعد فك ضغط الملفات شغل ملف helppc.com

اقتباس
ارجو الا اكون اثقلت عليك

لا تقل هذا يا أخي ده واجب علينا اننا نساعد بعض :D

helppc.zip

#10

asalamooo alikoo

i want to tell you that you can do your work in a dos project if you want

in borland 5.02 choose [new ptoject-dos]and check the sign beside "BGI"in your project

don't forget to add the contents of your BGI folder to the folder that containing your project

#11

السلام عليكم ورحمة الله وبركاته..

توجد طريقه أخرى ادق من المقاطعه Int 14

وهي بالتعامل مع ال UART مباشرة , والطريقه ليست صعبه

سوف تتعامل مع المنفذ عن طريق رقم المنفذ مثلما تتعامل مع منفذ الطابعه, لمعرفة رقم المنفذ للـ COM PORT استخدم هذا المثال :

#include <stdio.h>
#include <dos.h>
void main(void)
{
unsigned int far *ptraddr; /* Pointer to location of Port Addresses */
unsigned int address; /* Address of Port */
int a;
ptraddr=(unsigned int far *)0x00000400;
for (a = 0; a < 4; a++)
{
address = *ptraddr;
if (address == 0)
printf("No port found for COM%d \n",a+1);
else
printf("Address assigned to COM%d is %Xh\n",a+1,address);
*ptraddr++;
}
}

وكمثال على عملية تكرار القرائه من المنفذ

/* Name : Sample Comm's Program - Polled Version - termpoll.c */
/* Written By : Craig Peacock <cpeacock@senet.com.au> */
/* Date : Saturday 22nd February 1997 */
/* Copyright 1997 CRAIG PEACOCK <cpeacock@senet.com.au> */
/* See http://www.senet.com.au/~cpeacock/serial.htm */
/* For More Information */
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#define PORT1 0x3F8
/* Defines Serial Ports Base Address */
/* COM1 0x3F8 */
/* COM2 0x2F8 */
/* COM3 0x3E8 */
/* COM4 0x2E8 */
void main(void)
{
int c;
int ch;
outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */
/* PORT 1 - Communication Settings */
outportb(PORT1 + 3 , 0x80); /* SET DLAB ON */
outportb(PORT1 + 0 , 0x03); /* Set Baud rate - Divisor Latch Low Byte */
/* Default 0x03 = 38,400 BPS */
/* 0x01 = 115,200 BPS */
/* 0x02 = 56,700 BPS */
/* 0x06 = 19,200 BPS */
/* 0x0C = 9,600 BPS */
/* 0x18 = 4,800 BPS */
/* 0x30 = 2,400 BPS */
outportb(PORT1 + 1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */
outportb(PORT1 + 3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */
outportb(PORT1 + 2 , 0xC7); /* FIFO Control Register */
outportb(PORT1 + 4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */
printf("\nSample Comm's Program. Press ESC to quit \n");
do { c = inportb(PORT1 + 5); /* Check to see if char has been */
/* received. */
if (c & 1) {ch = inportb(PORT1); /* If so, then get Char */
printf("%c",ch);} /* Print Char to Screen */
if (kbhit()){ch = getch(); /* If key pressed, get Char */
outportb(PORT1, ch);} /* Send Char to Serial Port */
} while (ch !=27); /* Quit when ESC (ASC 27) is pressed */
}

ولكن انتظر !!!

فهناك طريقه اخرى للتعامل مع المنفذ التسلسلي باستخدام مقاطعات الهاردوير, بدلا من استخدام طريقة Poll التي تقيد الحركه , يمكننا استخدام طريقة المقاطعه (مش عارف فاتتني ازاي :lol: )

المهم الفكره هي ضبط اعداد ال UART لعمل مقاطعه عند ورود بيانات من الخارج , تمرر هذه المقاطعه الى المعالج لتقطع عمله الحالي وينفذ البرنامج الخاص بهذه المقاطعه (كأنك في 8051 أو اي ميكروكنترولر آخر) وبعد ذلك يعود المعالج الى البرنامج الرئيسي ويكمل باقي البرنامج بصوره طبيعيه الى حدوث مقاطعه ثانيه

طبعا لازم تكون مجهز البرنامج الخاص بالمقاطعه , وهو ببساطه ممكن يكون قرائة الحرف من المنفذ وتخزينه في Buffer أو طباعته على الشاشه أو اي وظيفه تراها أنت

ولوضوح الفكره يوجد مثال بسيط وجميل يوضحها

/* Name : Sample Comm's Program - 1024 Byte Buffer - buff1024.c */
/* Written By : Craig Peacock <cpeacock@senet.com.au> */
/* Copyright 1997 CRAIG PEACOCK <cpeacock@senet.com.au> */
/* See http://www.senet.com.au/~cpeacock/serial.htm */
/* For More Information */
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#define PORT1 0x2E8 /* Port Address Goes Here */
/* Defines Serial Ports Base Address */
/* COM1 0x3F8 */
/* COM2 0x2F8 */
/* COM3 0x3E8 */
/* COM4 0x2E8 */
#define INTVECT 0x0B /* Com Port's IRQ here */
/* (Must also change PIC setting) */
int bufferin = 0;
int bufferout = 0;
char ch;
char buffer[1025];
void interrupt (*oldport1isr)();
void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */
{
int c;
do { c = inportb(PORT1 + 5);
if (c & 1) {buffer[bufferin] = inportb(PORT1);
bufferin++;
if (bufferin == 1024) bufferin = 0;}
}while (c & 1);
outportb(0x20,0x20);
}
void main(void)
{
int c;
outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */
oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector for */
/* later recovery */
setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */
/* COM1 - 0x0C */
/* COM2 - 0x0B */
/* COM3 - 0x0C */
/* COM4 - 0x0B */
/* PORT 1 - Communication Settings */
outportb(PORT1 + 3 , 0x80); /* SET DLAB ON */
outportb(PORT1 + 0 , 0x03); /* Set Baud rate - Divisor Latch Low Byte */
/* Default 0x03 = 38,400 BPS */
/* 0x01 = 115,200 BPS */
/* 0x02 = 56,700 BPS */
/* 0x06 = 19,200 BPS */
/* 0x0C = 9,600 BPS */
/* 0x18 = 4,800 BPS */
/* 0x30 = 2,400 BPS */
outportb(PORT1 + 1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */
outportb(PORT1 + 3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */
outportb(PORT1 + 2 , 0xC7); /* FIFO Control Register */
outportb(PORT1 + 4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */
outportb(0x21,(inportb(0x21) & 0xF7)); /* Set Programmable Interrupt */
/* Controller */
/* COM1 (IRQ4) - 0xEF */
/* COM2 (IRQ3) - 0xF7 */
/* COM3 (IRQ4) - 0xEF */
/* COM4 (IRQ3) - 0xF7 */
outportb(PORT1 + 1 , 0x01); /* Interrupt when data received */
printf("\nSample Comm's Program. Press ESC to quit \n");
do {
if (bufferin != bufferout){ch = buffer[bufferout];
bufferout++;
if (bufferout == 1024) bufferout = 0;
printf("%c",ch);}
if (kbhit()){c = getch();
outportb(PORT1, c);}
} while (c !=27);
outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */
outportb(0x21,(inportb(0x21) | 0x08)); /* MASK IRQ using PIC */
/* COM1 (IRQ4) - 0x10 */
/* COM2 (IRQ3) - 0x08 */
/* COM3 (IRQ4) - 0x10 */
/* COM4 (IRQ3) - 0x08 */
setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */
}

ولكن خد بالك من الكلمه التي قالها كاتب البرنامج :

اقتباس
Note: The source code on the earier pages is not a really good example on how to

program but is rather cut down to size giving quick results, and making it easier

to understand. Upon executing your communications program, it would be wise

to store the status of the UART registers, so that they all can be restored before

you quit the program. This is to cause the least upset to other programs which

may also be trying to use the communications ports.

طبعا الأفضل أن تطلع على مصدر هذا الكلام

SERIAL.PDF

تم تعديل هذه المشاركة بواسطة Asm4all في 27 أبريل 2005 في 22:59

#12

تشكر جزيلا يا asm4all على كم المعلومات المفيد هذا حقيقة :)

banner_60_468.gif

NOTHING IS IMPOSSIBLE

هذا الموضوع مغلق.

مواضيع مشابهة