ايران ويج

نسخه‌ی کامل: شروع با کد ویژن و مشکلات اون
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
صفحه‌ها: 1 2
امروز گفتم بیخیال بیسیک بشم و بیام سراغ کدویژن
ببینید مشکل کد من چیه
اول یک متغیر از نوع Int به اسم i تعریف کردم با مقدار 0
کد:
int i = 0;

بعد خواستم یک حلقه فور بنویسی که مثلا 100 بار یه کاری را انجام بده ، بعد که از حلفه اومد بیرون یه کار دیگه .
کد:
while (1)
{
// Place your code here
for (i=1;i=100;i++)
{

PORTB.0 = 1;
PORTB.1 = 1;
delay_ms(50);

};

PORTB.0 =0;
PORTB.1 = 0;
delay_ms(2150);

};
}

ولی ظاهرا هیچ وقت از حلقه بیرون نمیاد ، و یک وارنینگ هم میده موقع کامپایل تحت عنوان :
Warning:d\F2\abc.c(125): possibly incorrect assignment

پیوست : ا چرا کدها راست چین شدن ؟


edited : توی قسمت for باید حتما بنویسیم بزرگتر یا کوچکترومساوری فلان عدد.!!!
for (i=1;i<=10;i++)
این سی یه حالیه :((
(۲۲-مرداد-۱۳۸۹, ۰۰:۱۴:۱۶)joker نوشته است: [ -> ]امروز گفتم بیخیال بیسیک بشم و بیام سراغ کدویژن
ببینید مشکل کد من چیه
اول یک متغیر از نوع Int به اسم i تعریف کردم با مقدار 0
کد:
int i = 0;

بعد خواستم یک حلقه فور بنویسی که مثلا 100 بار یه کاری را انجام بده ، بعد که از حلفه اومد بیرون یه کار دیگه .
کد:
while (1)
{
// Place your code here
for (i=1;i=100;i++)
{

PORTB.0 = 1;
PORTB.1 = 1;
delay_ms(50);

};

PORTB.0 =0;
PORTB.1 = 0;
delay_ms(2150);

};
}

ولی ظاهرا هیچ وقت از حلقه بیرون نمیاد ، و یک وارنینگ هم میده موقع کامپایل تحت عنوان :
Warning:d\F2\abc.c(125): possibly incorrect assignment

پیوست : ا چرا کدها راست چین شدن ؟


edited : توی قسمت for باید حتما بنویسیم بزرگتر یا کوچکترومساوری فلان عدد.!!!
for (i=1;i<=10;i++)
این سی یه حالیه :((

سلام
تاحالا با کدویژن کار نکردم اما یه چیزایی از سی بلدم.
این حلقه ای که شما نوشتید دو تا ایراد داره:
- کدویژن رو نمی دونم اما در سی برای مقایسه ی دو مقدار از لحاظ تساوی باید دوتا مساوی قرار دهید یعنی == پس i=100 به i==100 تبدیل شود.
- بنا بر شرط شما متغیر i تازمانی 1 واحد افزایش خواهد یافت که مساوی 100 باشد. پس شرط حلقه اشتباه هست.

حالا اگر می خواهید تا 100 بشمارد:
کد:
for(i = 0 ; i <=100; i++)
برای بلوک for ، اگرم نمیخوای دستوری بنویسی، لااقل آکولاد باز و بسته یا سمی کالن بذار. این که نوشتی یه طوریه!! شایدم جواب بده ولی...

ضمنا حالا که داری میای سراغ c حتما winavr کار کن. حیف وقتی که بذاری واسه کدویژن...
خوبه راه افتادن بچه ها
- هیچ وقت در طول اجرای یک برنامه یه متغیر رو دوبار مقدار دهی اولیه نکن
- joker این حلقه که شما نوشتی تا بینهایت اجرا میشه چون گفتی هر بار که حلقه اجرا شد یه واحد به i اضافه بشه که حلقت شرط پایان نداره درستش همونیه که صالح گفته یعنی
(++i=1;i<=100;i)
(۲۲-مرداد-۱۳۸۹, ۰۲:۰۱:۳۴)HENAS نوشته است: [ -> ]- joker این حلقه که شما نوشتی تا بینهایت اجرا میشه چون گفتی هر بار که حلقه اجرا شد یه واحد به i اضافه بشه که حلقت شرط پایان نداره درستش

درسته که روی سخن با آقا joker هست اما تیکه ی بالایی رو قبول ندارم.
شرط اجرای دستورات حلقه true بودن شرط حلقه هست.
برای مثال وقتی شرط حلقه i<=100 باشد ، حلقه تا زمانی ادامه می یابد که i کوچکتر یا مساوی 100 باشه.(یعنی:
کد php:
(i<=100) == true 
)
ولی چون i==100 از همون اولش false هست پس دستورات حلقه اجرا نمیشه.

از دوستان کسی هست که با iar کار کرده باشه(avr)؟
والا اول تصمیم داشتم با AVR STUDIO کار کنم ( بابا بالاسر winavr ) ولی انگار مشکلات زیادی من باهاش توی لود هدر فایلها داشتم
دهن خودموسرویس کردم یک FreeRTOS را بدون استفاده از سمپلهای خودش لود کنم نشد که نشد... و الا اگه مشکلات اسلام و مسلمینش را پیدا میکردم بهتر بود
(۲۲-مرداد-۱۳۸۹, ۰۲:۱۲:۳۹)salehjg نوشته است: [ -> ]
(۲۲-مرداد-۱۳۸۹, ۰۲:۰۱:۳۴)HENAS نوشته است: [ -> ]- joker این حلقه که شما نوشتی تا بینهایت اجرا میشه چون گفتی هر بار که حلقه اجرا شد یه واحد به i اضافه بشه که حلقت شرط پایان نداره درستش

درسته که روی سخن با آقا joker هست اما تیکه ی بالایی رو قبول ندارم.
شرط اجرای دستورات حلقه true بودن شرط حلقه هست.
برای مثال وقتی شرط حلقه i<=100 باشد ، حلقه تا زمانی ادامه می یابد که i کوچکتر یا مساوی 100 باشه.(یعنی:
کد php:
(i<=100) == true 
)
ولی چون i==100 از همون اولش false هست پس دستورات حلقه اجرا نمیشه.

از دوستان کسی هست که با iar کار کرده باشه(avr)؟
بله ایشون درست میگن
من اون نقطه سمی کالن(;) رو با سمی کالن تنها (,) اشتباه گرفتم

اما اجرا نشدن حلقه در اثر خطاست نه اشتباه بودن شرط!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

یک سورسی دارم که البته معتبره ولی یه جاش مشکل دارم نمیفهمم چرااینطوری مینویسن:

کد:
// LED
/* enable PB1, LED as output */
DDRC|= (1<<DDC0);

/* set output to Vcc, LED off */
PORTC|= (1<<PC0);

// the transistor on PD7
DDRD|= (1<<DDD7);
PORTD &= ~(1<<PD7);// transistor off
خط آخر خب درست پورت d را داره کنترل میکنه
ولی خط اول چطوری PB1 را با رجیستر DDRC دست خودش گرفته ؟

سوال دوم
کلا توی سورسهای سی چرا اینطوری مینویسن : مثلا : 1<<DDD7
؟

و این یکی چرا اینطوری مینویسن :
کد:
PORTD &= ~(1<<PD7);// transistor off

این &=~ منظورمه :)
تاپیکی که لینکش پائین گذاشتم فکر کنم مشکلتون رو حل میکنه کامل.

آموزش سی

{
چندتا مثال:(همین طوری نوشتم)
کد:
1<<2 = 100
1<<4 = 10000
کد:
a = 101011
b = 010001

c= a|b
d= a&b

c = 111011
d = 000001

خلاصه:
" | " : or بیتی
" & " : and بیتی
" ~ " : not بیتی
"<< و >> " : شیفت

& و && باهم فرق دارند همان طوری که | و || باهم فرق می کنند.
&& : and منطقی : 10 && 0 = 0 و 10 && 10 = 1
|| : or منطقی : 10 || 0 = 1 و 10 || 10 = 1 و 0 || 0 = 0
مثال | و & هم بالا نوشتم(توی کد)

}
کد php:
for (i=1;!= 100;i++) 

joker تکلیف خودتو روشن کن! میخوای کدویژن کار کنی یا winavr (avr studio)

می بینم که حسابی با c حال میکنی! Biggrin

نگران نباش اوایل یکم تلخ هست اما کم کم اونقدر برات شیرین میشه که تشویق میشی همینطوری جلوتر بری و بیشتر یاد بگیری. مخصوصا اگه winavr کار کنی

حقیقت اینه که دستورات به ظاهر خوش آب و رنگ بیسکام و در مواردی کدویژن، در نهایت تبدیل به همین کدها میشن!
بیبین مثلا تو کدویژن مینویسیم PORTA.2=1
اما درحقیقت میکرو همچین امکانی نداره که بتونه مستقیم به بیت از رجیستر رو یک کنه و اصلا این دستور که با نقطه به یه بیت دسترسی پیدا کرده در c استاندارد نیست! میکرو برای یک کردن اون پایه میاد PORTA رو با 100 باینری or میکنه. دقت کن که هر بیت که با صفر or بشه تغییر نمیکنه و or شدن با 1 نتیجه 1 شدن میده. این باعث میشه بیت شماره 2 یک بشه و بقیه بیت ها تغییر نکنن.
این کد رو درنظر بگیر : PORTA.2=0
برای صفر کردن بیت شماره 2، PORTA با 1111011 باینری and میشه. بیتی که با 0 and بشه، صفر میشه. این نکته مهمه که باید سمت چپ اونقدر 1 داشته باشیم که کامل رجیستر رو پوشش بده. یعنی اگه مثلا PORTA 8 بیتی باشه و با 011 AND بشه، چهار بیت بالا هم صفر میشن. پس باید همه بیت ها رو با 1 and کنیم به جز بیت مورد نظرمون که میخوایم صفر بشه.
با این توصیفات، برای یک کردن از or و برای صفر کردن از and استفاده میکنیم.
خب حالا ببینیم کدهایی که تو c مخصوصا تو winavr میبینم چطوری عمل میکنن
دستور PORTA.2=1 رو با توجه به توضیحاتی که دادم میتونیم اینطوری بنویسیم:
PORTA = PORTA | 0b100
یا
PORTA |= 0b100
مقدار 0b100 رو میتونیم با شیفت به چپ درست کنیم. عدد 1 رو 2 بیت به چپ شیف میدیم
کد:
1<<2
کدمون اینطوری میشه:
کد:
PORTA |= (1<<2);
دلیلش چیه؟
توی هدرهای هر میکرو اومدن یه سری ثابت معرفی کردن که مکان هر بیت در رجیسترها رو مشخص میکنن. مثل PA2 یعنی بیت 2 از پورت A . اینطوری لازم نیست مکان بیت ها رو حفظ کنیم و کد خواناتر میشه. البته اینجا که مکشلی نیست. بهرحال کد اینطوری میشه:
کد:
PORTA |= (1<<PA2);
فرض کن میخوایم بیت OCIE3A از رجیستر ETIMSK مربوط به وقفه تایمر هست رو یک کنیم. اینطوری :
کد:
ETIMSK |= 1<<OCIE3A;
خب حالا این کد رو در نظر بگیر :
PORTA.2=0
باید and کنیم تا صفر بشه دیگه
کد:
PORTA &= ...
باید با عددی and بشه که بیت شماره 2 اون صفر و بقیه بیت ها 1 باشن. (همه بیت های سمت چپ یا بیت های پر ارزش باید تا بینهایت 1 باشه)
خیلی ساده از همون شیفت به چپ عدد 1 استفاده میکنیم. با این تفاوت که یه not بیتی هم پشتش میذاریم
کد:
PORTA &= ~(1<<PA2);

اگه یه گشتی تو کتابخونه ها بزنی یه دستور دیگه هم میبینی که زیاد استفاده شده: _BV
این ماکرو همون عمل شیفت 1 به چپ رو انجام میده
کد:
PORTA |= _BV(PA2);

خلاصه اینکه هرجا |= دیدی بدون که میخواد 1 کنه و &= هم یعنی صفر کردن.

عجب طوماری نوشتم!! شرمنده اگه زیاد ابتدایی و سطح پایین گفتم. میخواستم اگه کسی میخواد بیاد طرف c و مخصوصا winavr، سردرگم نباشه و شکل علامت تعجب نشه!! چیز عجیبی نداریم! Biggrin
صفحه‌ها: 1 2