ايران ويج

نسخه‌ی کامل: اشکال با وقفه پورت سریال
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
صفحه‌ها: 1 2
عرضم به حضورتون اول کلیات داستان را بگم
یک میکرو مادر دارم که همیشه یک عدد 5 کاراکتری مثل 123.4 را برام ارسال میکنه و اینطرف یک میکرو دارم که قراره این عدد را روی پورت سریالش )RX) بگیره و روی یک سون سگمنت 4تایی نمایش بده
حالا برای تست کار اومدم 2تا برنامه نوشتم که اولی یعنی میکروی مادر و ارسال کننده دیتا:
کد:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 1200

Dim S As String * 5

Do
Waitms 50
Print "432.1"
Wait 2
Print "123.4"
Wait 2

Loop

End

سمت گیرنده در حالت معمولی توی حلقه لوپ مشکلی با دریافت دیتا ندارم
ولی نکته کنکوری ، زمان چندمیلی ثانیه ای رفرش 4تا سون سگمنتم هست که اگه جابجا میشه دیگه خودتون میدونید که یا پر پر میزنه یا خلاصه ضایع بازی در میاره
گفتم سمت کلاینت یک برنامه مینویسم که توی حلقه لوپ اصلی برنامه مرتب یک متغییر عمومی ( که همون عدده هست ) را بخونه و روی سون سگمنت به صورت استاندارد نمایشش بده ، تا اینجا مشکلی نبود
بعد گفتم خب برای اینکه برنامه منتظر ورود دیتا از سمت میکرو مادر نخواد بشه باید از وقفه های پورت سریال استفاده کنم : سورس زیر :
کد:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 1200

Enable Urxc
Enable Timer1
On Urxc Getserialdata Nosave
Enable Interrupts


Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.4 , Db6 = Porta.5 , Db7 = Porta.6 , Rs = Porta.0 , E = Porta.2
Config Lcd = 16 * 4

Dim S As String * 8
Dim I As Integer , J As Integer

I = 0
J = 1
Cls
Lcd "welcome joker"
Wait 1
Cls
Home
Lcd J

Waitms 100

Do

J = J + 1
Locate 1 , 2
Lcd J

Waitms 100
Loop

End

Getserialdata:
Input S
S = Mid(s , 2 , 8)
Locate 2 , 1
Lcd S
'Wait 2
I = I + 1

       If I = 3 Then
       Lcd "               "
      End If


Return
End

اما نکته اینجاست که برنامه من به محض در یافت اولین دیتا از پورت سریال دیگه میره توی قسمت وقفه و قسمتی که مثلا حلقه لوپ بینهایت برنامه هست و قراره مثلا J+1 را انجام بده دیگه سراغش نمیره...
خب کجای کار باید چی اضافه کنم که خر و داشته باشیم و هم خرما را ؟ Wink
خوب مهندس رفرش سون سگنت رو با وقفه تایمر انجام بده و تو حلقه اصلی برنامه از پورت سریال دیتا بگیر !!!!
(۰۹-خرداد-۱۳۸۹, ۰۹:۳۶:۲۱)t3r!p3000 نوشته است: [ -> ]خوب مهندس رفرش سون سگنت رو با وقفه تایمر انجام بده و تو حلقه اصلی برنامه از پورت سریال دیتا بگیر !!!!

همین کار را کردم ( در ضمن سورس ساعت دیجیتالیت را هم خوندم
https://www.iranled.com/forum/showthread...#pid111795
ولی برنامه به زیرروال تایمر نمیره !!!!
یعنی حلقه لوپ اصلی اجرا میشه و دیتای ورودی پورت سریال را روی LCD بهم نشون میده ولی شمارنده ای که به صورت عمومی تعریف کردم ( i ) را گفتم توی کانتر صفر توی خط دوم LCD نشون بده ، اصلا بهش پرش نداره !
سورس : اشکال کجاست ؟
کد:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 1200

Config Timer0 = Timer , Prescale = 8 : On Timer0 Timer_label : Enable Timer0


Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.4 , Db6 = Porta.5 , Db7 = Porta.6 , Rs = Porta.0 , E = Porta.2
Config Lcd = 16 * 4

Dim S As String * 8
Dim Rs As String * 1
Dim Ls As String * 1

Dim I As Integer

I = 0
Cls
Lcd "welcome joker"
Wait 1
Cls

Start Timer0

Do

Input S
S = Mid(s , 2 , 8)
Ls = Left(s , 1)
Rs = Right(s , 1)
If Rs = "@" And Ls = "@" Then

I = I + 1
If I = 4 Then
Locate 1 , 1
Lcd " "
I = 0
' Cls
End If

S = Mid(s , 2 , 5)
Locate 1 , 1
Lcd S ' اينجا هميشه پنج کاراکتر عددي را جدا ميکند

End If ' اگر کاراکتر کنترلي @ وجود داشت

Loop
End



Timer_label:
' انگار نه انگار که بايد بياد اينجا
Locate 2 , 2
Lcd "i:" : Lcd I


Return

ادیت شد » Enable Interrupts را ننوشته بودم
ولی حالا مشکل یه چیز دیگه شد ، یکبار که وارد زیر روال تایمر میشه دیگه همین یکبار هست و بیرون نماید . ( حتی لوپ هم نمیشه :(

ادیت برای بار دوم ، مشکلم اینطوری حل شد ، اشکال از سرعت زیاد LCD بود :)
کد:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 1200

Enable Interrupts

Config Timer0 = Timer , Prescale = 1024 :
On Timer0 Scan :
Enable Timer0
Stop Timer0
Start Timer0


Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.4 , Db6 = Porta.5 , Db7 = Porta.6 , Rs = Porta.0 , E = Porta.2
Config Lcd = 16 * 4

Dim S As String * 8
Dim Rs As String * 1
Dim Ls As String * 1

Dim I As Integer
Dim J As Integer

I = 0
J = 1
Cls

Lcd "welcome joker2"
Wait 1
Cls


Do

   Input S
   S = Mid(s , 2 , 8)
  Ls = Left(s , 1)
  Rs = Right(s , 1)
  If Rs = "@" And Ls = "@" Then

            I = I + 1
         If I = 4 Then
   Locate 1 , 1
   Lcd "              "
            I = 0
           Cls
         End If

S = Mid(s , 2 , 5)
   Locate 1 , 1
   Lcd S                                                    ' ÇíäÌÇ åãíÔå äÌ ˜ÇÑǘÊÑ ÚÏÏí ÑÇ ÌÏÇ ãí˜äÏ

   End If                                                   '  ÇÑ ˜ÇÑǘÊÑ ˜äÊÑáí @ æÌæÏ ÏÇÔÊ

Loop
End



Scan:
' ÇäÇÑ äå ÇäÇÑ ˜å ÈÇíÏ ÈíÇÏ ÇíäÌÇ
J = J + 1

Locate 2 , 1
'Lcd "j:" : Lcd J : Lcd "S:" : Lcd S
Lcd S
'Waitms 10
'Cls

Return
End
(۰۹-خرداد-۱۳۸۹, ۰۹:۳۶:۲۱)t3r!p3000 نوشته است: [ -> ]خوب مهندس رفرش سون سگنت رو با وقفه تایمر انجام بده و تو حلقه اصلی برنامه از پورت سریال دیتا بگیر !!!!

خب ، ظهر تاحالا دهنم سرویس شده س حجی
گرفتن دیتا را گذاشتم توی لوپ اصلی
و رفرش کردن را گذاشتم توی تایمر صفر
نشد که نشد که نشد ،
ببین میتونی مشکلات اسلام و مسلمین را برام حل کنی ،

پیوست : توضیحات : تابعی دارم به اسم Call Showdigit(digistr که مقدار digistr را که یک عدد 3 رقمی + یک رقم اعشار هست را روی سون سگمنت چهارتایی بی مشکل نمایش میده ( توی لوپ اصلی ) حالا اومدم توی حلقه اصلی برنامه گفتم دیتای پورت سریال را بخون ( مقدارش را بعد از چک کردن crc توی digistr قرار بده
قاعدتا اگه تایمر صفر قرار باشه درست کار کنه ، حلقه لوپ اصلی برنامه هم درست کار کنه نباید مشکلی باشه ، ولی هست :(

آیا اصلا ممکنه چون من از waitms توی زیر توابعم برای خاموش روشن کردن s7 ها استفاده کردم تایمر صفر قاط بزنه ؟

سورس پست بالا برای کار در مورد LCD بدون مشکل کار میکنه
آیا اشکال از نحوه نوشتن تابع showdigit من هست ؟ که ظاهرا هست - اگه هست چرا در حالتی که وقفه های تایمر فعال نشدن بی مشکل کار میکنه ؟
خلاصه گو گیجه شدید گرفتم :)

ادیت شد : وقتی تابع Input را استفاده میکنم ، شروع بدبخته :)
مهندس اون تاخیر رو برداری درست میشه !

چون 3 میلی ثانیه تاخیر گذاشته ولی تو همین مدت زمان 12 بار وقفه تایمر یکی میشه و برنامه تایمر می ره دوباره از اول !!!!!

چی برنامه شلوغی نوشتی !
همش تابع هستش !
واسه اسکن سون سگمنت از جدول برگشتی استفاده کنی خیلی راحت تری !!
(۰۹-خرداد-۱۳۸۹, ۲۰:۴۹:۰۹)t3r!p3000 نوشته است: [ -> ]مهندس اون تاخیر رو برداری درست میشه !

چون 3 میلی ثانیه تاخیر گذاشته ولی تو همین مدت زمان 12 بار وقفه تایمر یکی میشه و برنامه تایمر می ره دوباره از اول !!!!!

چی برنامه شلوغی نوشتی !
همش تابع هستش !
واسه اسکن سون سگمنت از جدول برگشتی استفاده کنی خیلی راحت تری !!

تمام تاخیرها را برداشتم ، بی فایده بود

ظاهرا نمیشه موقع استفاده از پورت سریال ، از تایمر استفاده کرد :(
میشه !

من تو چند تا از برنامه هام این کارو کردم ! ( از وقفه سریال هم استفاده نکردم )

فقط من نفهمیدم شما چجوری اسکن می کنی تو وقفه تایمر !!!
من که با این قضیه مشکل ندارم !

فکر کنم برنامه اسکن شما مشکل داره !!!
(۰۹-خرداد-۱۳۸۹, ۲۱:۵۶:۳۴)t3r!p3000 نوشته است: [ -> ]فقط من نفهمیدم شما چجوری اسکن می کنی تو وقفه تایمر !!!
من یک تابع نوشتم که یک مقدار ثابت ( فرمت ثابت) مثل 123.4 را میگیره و روی 4تا سون سگمنت نمایش میده
این یک دونه تابع یک پارامتر ورودی ( همون رشته عددی) را میگیره به اسم DIGISTR
این DIGISTR هم توی لوپ اصلی برنامه با استفاده از تابع iNPUT پر میشه.
وقتی INPUT را استفاده میکنم که دیتا را از پورت سریال بخونه قاط میزنه
نقل قول: من که با این قضیه مشکل ندارم !
حالا هم طوری نیست ، شما برام بنویس ، :)
پروتکل ارتباطی منم ساده هست ، یک مقدار عددی با فرمت ثابت XYZ.A با کاراکتر کنترلی @ اول و آخرش یعنی مثلا @122.5@
میکرو مادر اینو روی پورت سریال ارسال میکنه ، شما برنامه شو برام بنویس که روی سون سگمنت نمایش بده.
خدا خیرت بده جوووون :)
خوب با input نخون !

با waitkey بخون و البته تو متغییر بایت بگیر و اگه 13 بود یعنی اینتر رو گرفتی و اونوقت بایت های قبل از اون رو با CHR تبدیل به رشته کن !!!

نمونه برنامه :

کد php:
$regfile "m32def.dat" $crystal 11059200

$baud 
1200 $hwstack 32 $swstack 10 $framesize 40

Dim C 
As Byte As String 25

Do

   
Waitkey()

   If 
13 Then :

      
Mid(14 )

      
Chr(0)

   Elseif 
7 Then :

      
Chr(c)
      Print 
Chr(c)

   
end if

Loop 

این برنامه واسه گرفتن مشکل نداره و الان هم همزمان دارم ازش تو سون سگنت استفاده می کنم !
برنامه های اسکن رو ننوشتم !

تو برنامه اسکن هم با MID تک کارکتر رو جدا کن و نشون بده دیگه !
ممنون ، تا حد زیادی فکر کنم مشکلم حل شد
حالا یه مشکل دیگه دارم
متغییری به این شکل تعریف کردم
Dim Digistr As String * 5

توی حلقه لوپ برنامه بعد از پردازش دیتای ورودی پورت سریال و تشخیص کامل عدد سالم مقدار این متغییر را براش پر میکنم ،
اما مشکل اینجاست که این مقدار را توی زیرتابع تایمر صفر بهش هیچ دسترسی به مقدارش نداره
نمیگه این متغییر نیست ، ولی مقدارش را نمیتونه بخونه ظاهرا

پیوست : تابع درست کار میکنه ، چون اگه دستی توی زیرمجموعه تایمر صفر بهش مقدار بدم روی سون سگمنتها بهم نشون میده
فرقی نمیکنه هر متغییری را توی حلقه لوپ اصلی برنامه مقدار بهش بدم ، توی زیرمجموعه تایمر صفر انگار اصلا آدم حسابش نمیکنه :(
حضور محترم برادر علی تریپ و ما بقی حاضرین گرامی :
یک مثال کوتاه و ساده جهت اینکه مشکل بین وقفه تایمر صفر و مقدار دهی متغییرها خارج از رنج تایمر را ببینید و به حال من گریه کنید و اگه دلتون به رحم اومد یه راه حل بهم بگین:
کد:
$regfile = "m16def.dat"
$crystal = 11059200
$baud = 1200 :

Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.4 , Db6 = Porta.5 , Db7 = Porta.6 , Rs = Porta.0 , E = Porta.2
Config Lcd = 16 * 2


Enable Interrupts
Config Timer0 = Timer , Prescale = 8 :
On Timer0 Scan :
Enable Timer0
Stop Timer0
Start Timer0


Dim Si As Single


Do
Loop
Si = Si + 1
اگه اینجا باشه مقدار همیشه برابر با 0.0 چاپ میشه ،
انگار نه انگار که اینجا این متغییر هی یکی بهش اضافه میشه مثلا...
End

Scan:
Cls
' Si = Si + 1

اما اگه همون خط دستور اضافه کردن را توی خود تایمر بنویسم
مثل بچه آدم اضافه و چاپ میکنه ، چرا ؟
چه خاکی تو سر این باسکام و ای وی آر و خودم بکنم ؟

Lcd Si
Return
End
صفحه‌ها: 1 2