PDA

توجه ! این یک نسخه آرشیو شده میباشد و در این حالت شما عکسی را مشاهده نمیکنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : سوال در مورد برنامه نویسی arm7



ut_naji
03-07-2010, 17:29
سلام
1- در میکرو at91sam7s64 اگه بخوام اطلاعاتی که در میکرو ذخیره کردم(مثلا از ADC گرفتم)، رو 8 تا پایه بذارم.کدوم پایه ها این امکانو داره؟
2- چه دستوری این کارو انجام میده؟

farzadsw
04-07-2010, 02:36
فرقی نداره شما میتونید از هر 8 پایه ای استفاده کنید ، پایه های 1 تا8 ، 2تا 9 و ... حتی لزومی نداره پایه ها پشت سر هم باشن . ولی برای سادگی برنامه بهتره پایه ها پشت سر هم باشن .
برای اینکار راه های مختلفی هست ، به عنوان نمونه اون عددتون رو به اندازه لازم شیفت بدید (اگه پایه های 1تا8 هست ، شبفت نمیخواد ، اگه 2تا 9 هست 1دونه شیفت میخواد و الی آخر) . حالا یه mask هم لازم داریم تا وضعیت بقیه پایه های میکرو به هم نخوره ، برای ساخت mask ، این عددی که شیفت دادید رو با ffff هگز or میکنید و تو یه متغییر دیگه ذخیره میکنید . پس الان 2تا متغییر 32 بیتی دارید که یکی اون 8 بیت رو داره و بیقیه بیتهاش صفره و یکی دیگه اون هشتا رو داره و بقیه بیتهاش یکه . متغییر اولی رو با مقدار پورت (که 32 بیتی هست) or میکنید و بعد حاصلش رو با متغییر دوم and میکنید.
البته خود پردازنده میکرو معمولا دستورالعمل مخصوص این کار ها داره ، مثلا برای arm ها این دستور العمل هست که کار هایی که در بالا گفتم رو یکجا انجام میده :

BFI Rd, Rn, #<lsb>, #<width>

بازم اگه insruction set هسته آرم رو بخونید موارد دیگه ای هم پیدا میشه .

ut_naji
04-07-2010, 18:28
خیلی تشکر آقا فرزاد.اما مشکل اصلی من حل نشد.:( فرض کنید بخوام به دوتا از پایه های ADC داده های آنالوگ رو بدم وبعد روی PA0 و PA1 این داده ها روwrite کنم.میدونم باید از دستور های AT91C_PIOA_OWER = 0x00;
AT91C_PIOA_ODSR = 0x01;
استفاده کنم.اما به این صورت که من نوشتم error میده.کد باید چه جوری باشه؟

farzadsw
05-07-2010, 15:59
خروجی ADC یه عدد 10 بیتی هست ، شما میخواید این عدد رو به صورت پارالل روی پورت نشون یدید ؟ خب دراین صورت به 10 تا پایه نیاز دارید نه 1 پایه . ولی اگه میخواید این اطلاعات رو به صورت سریال بفرستید راه های زیادی هست .
این اطلاعات رو به کجا میخواید بفرستید ؟(سوال و هدفتون از این کار رو درست متوجه نشدم)

اون دوتا دستوری که نوشتید ، برای ماسک کردن پایه های پورت هست تا مقدارشون تغییری نکنه (فرستادن اطلاعات به صورت همزمان روی 1 باس مشترک) . برای تغییر وضعیت یک پین یا به قول شما write روی اون باید از دستور های :
AT91C_PMC_PCER
AT91C_PIOA_PER
AT91C_PIOA_OER
AT91C_PIOA_SODR
AT91C_PIOA_CODR
استفاده کنید ، که 3 تای اولی برای راه اندازی پورت ، و تعریف اون به عنوان خروجی هست . و دوتای آخری برای 0 و 1 کردن اون .
اما علت اینکه ارور میده اینه که همه اینا پوینتر هستن و باید اینطوری ازشون استفاده کنید :

*AT91C_PMC_PCER=0x0000000F;
یعنی یه * پشتشون بگذارید تا آدرسی که اینا بهش اشاره میکنن تغییر کنه .

برای 0 و 1 کردن پایه های میکرو میتونید مثالهای led چشمک زن رو ببینید تا اصول کار دستتون بیاد . بعدش به جای 1 دونه پایه ، هرچندتا کهخواستید رو میتونید 0و1 کنید.

ut_naji
06-07-2010, 10:57
ببینید کل کار من اینه:
دو تا سیگنال آنالوگ رو، روی دو تا از پایه های adc می گیرم.بعد خروجی adc رو باید بذارم روی usb کامپیوتر.(که بعدا با یه نرم افزاری سیگنال آنالوگ رو نشون بدم)
من برای اول کار (برای اینکه adc رو امتحان کنم) خواستم بعد از دریافت این سیگنال ها، دیجیتال شده ی اونها رو روی PIO بذارم و با اسیلوسکوپ مقدارشونو ببینم.
درسته من اشتباه کردم.چون داده ها رو پارالل میخوام یک پایه نمیشه.اما چرا 10 تا پایه؟مگه 8تا نمیشه؟
0و1 کردن پایه ها رو میدونم.اما مشکل من استفاده از register های میکرو هست.یعنی همونطور که خودتون می دونید میخوام اطلاعات save شده رو بذارم روی PIO ها نه اینکه خودم 0و1 شون کنم.
هرچه میگردم مرجع کاربردی برای این مطالب پیدا نمی کنم.توی pmm هم در این زمینه( adcو register ها و usb )چیزی ندیدم.لطفا راهنمایی کنید

farzadsw
06-07-2010, 14:02
خب چون ADC میکرو 10 بیتی هست ، برای همین برای بیشترین رزولیشن میتونید تو 10 تا پایه نشون بدید . در غیر این صورت میتونید عدد حاصل از ADC رو بر 4 تقسیم کنیدو تو 8 تا پایه نشون بدید ،یا بر 16 تقسیم کنید و رو 6 تا پایه نشون بدید و الی آخر ...

اما اگه هدفتون فقط تست ADC هست ، به نظر من اطلاعات رو روی LCD کاراکتری یا 7SEG نشون بدید کارتون راحتتره .
اون رجیستر ها همه 32 بیتی هستن ، یعنی به این این صورت استفاده میشن :


*AT91C_PIOA_SODR=0x0000000F;

الان این دستور ، هر بیتی که 1 باشه رو میبینه و پایه معادلش رو SET یا همون 1 میکنه . مثلا 0X0000000F معادل باینریش میشه 1111 و 28 تا صفر پشتش . پس این دستور میاد پایه های 1و2و3و4 پورت میکرو رو SET میکنه و به بقیه کاری نداره . حالا شما میتونید به جای اون عدد هگز ، از یه متغییر استفاده کنید :



*AT91C_PIOA_SODR=ADC1;

الان این متغییر ADC1 اگه مثلا مقدارش 255 باشه ، معادل هگزش میشه 0X000000FF . همونطور که گفتم اگه قراره پایه های مثلا 5 تا 12 پورت رو برای نمایش خروجی استفاده کنید ، باید متغییر تون رو اول به اندازه کافی (4 تا در این مثال) شیفت بدید و بعدش اون رو به پورت اعمال کنید .
تا اینجا نصف کار انجام شده ! فقط پایه SET شده . برای نمایش عدد رو پورت باید RESET یا صفر های اون رو هم اعمال کنید . برای این کار از دستور

CODE]*AT91C_PIOA_CODR=~ADC1;[/CODE]

باید استفاده کنید .این دستور به ازای بیتهای 1 ای که میبینه ، پایه متاظر بااون روی پورت رو RESET میکنه و به بقیه کاری نداره . یه علامت نقیض هم پشت متغییر گذاشته شده تا 0 های اون به 1 تبدیل بشن ( تا پایه های متناظر روی پورت 0 بشن ) و 1 های اون به 0 تبدیل بشن (تا پایه های متناظر با اون تغییر نکنن) .


ولی در کل باز هم توصیه میکنم از LCD کاراکتری یا 7SEG استفاده کنید چون برای 2 تا متغییر کلی از پایه های میکرو اشغال میشه و کلی هم درد سر داریدبرای خوندن مقدار پایهها و تبدیل اون به عدد قابل فهم . ولی LCD عدد رو مستقیم نشون میده.