مدیریت نشانگر پویا در اسمبلر تصویر میکروکنترلر. نشانگر هفت قسمتی راه های پیاده سازی نرم افزار

در ادامه درس، نشانه پویا را در نظر خواهیم گرفت. اگر نشانگر استاتیک را به دقت مطالعه کرده باشید، می دانید که نشانگر قطعه مجموعه ای از LED است. برای اتصال نشانگر به 7 پین میکروکنترلر نیاز دارید. اما ناگهان نیاز به استفاده از چندین شاخص، به عنوان مثال 2، 3، 4…

سپس ما در حال حاضر به 14، 21، 28 پا نیاز خواهیم داشت، و پاهای کمی وجود دارد ... در اینجا نشانه پویا به کمک ما می آید. وظیفه اصلی نشانگر پویا کاهش تعداد پایه های میکروکنترلر استفاده شده است. به طرح شامل 9، نه 14 پا توجه کنید. پایه های کنترل همه به صورت موازی به هم متصل شده اند.

در یک مفهوم کلی، این طراحی به صورت زیر عمل می کند: ابتدا پیکربندی شماره اول به یک اتوبوس معمولی خروجی می شود و PB1 را روشن می کند. اولین نشانگر با عدد دلخواه روشن می شود. سپس آن را خاموش می کنیم، پیکربندی شماره دوم را به گذرگاه داده خروجی می دهیم، نشانگر دوم را روشن می کنیم، آن را خاموش می کنیم.

با جزئیات بیشتر. در لحظه اول همه چیز خاموش است PORTB=0x00; PORTD=0xFF; از آنجا که مدار با یک "+" مشترک، آند. در مرحله بعد، پیکربندی شماره اول به PORTD ارسال می شود، به عنوان مثال "0". از نشانه ایستا به یاد می آوریم:

مورد 0 : ( PORTD= 0xC0 ؛ شکست ؛ )

مورد 0: (PORTD=0xC0؛ شکست؛ )

اما توجه داشته باشید، "+" به PORTB.1 متصل است، یعنی. برای روشن کردن بخش باید پا را روشن کنید PORTB.1=1;

در لحظه دوم، دوباره همه چیز را خاموش می کنیم، پیکربندی شماره دوم را ارسال می کنیم و این بار نشانگر دوم را روشن می کنیم. سپس تکرار می کنیم.

در فرکانس های بالا، چشم انسان قادر به دیدن این کلیدها نیست و به نظر می رسد که نشانگر دائما روشن است. توصیه می شود از فرکانس هایی که مضرب 50 هرتز هستند استفاده نکنید. در پروژه آزمایشی خود از 120 هرتز استفاده کردم. تایمر روی 1 مگاهرتز تنظیم شده است. کد در وقفه Timer1 پردازش می شود. وقفه 240 بار در ثانیه فراخوانی می شود، زیرا دو نشانگر وجود دارد، بنابراین ما 1000 000/240=4166 یا 0x1046 را وارد ثبات مقایسه می کنیم. Proteus نتوانست با یک نشانگر پویا دوست شود، اما بلافاصله روی سخت افزار کار کرد.

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

برای مدار آند مشترک

برای یک مدار کاتدی مشترک

به عنوان یک سیستم عامل آزمایشی، از یک تایمر پروژه قبلی استفاده کردم.

ویدئو از سیستم عامل

یکی از رایج ترین راه های نمایش اطلاعات، نشانگر 7 قسمتی است. به راحتی به شما امکان نمایش اطلاعات دیجیتال و شبه متن را می دهد (همچنین یک نشانگر چند بخش متن ویژه وجود دارد)، اما به تعداد زیادی خروجی رایگان از کنترلر نیاز دارد. دو راه برای کاهش تعداد پین های استفاده شده وجود دارد: استفاده از یک درایور خاص (یا عنصر بافر) یا استفاده از نشانگر پویا. جایی که 7 پین برای هر یک از بخش ها و یک پین برای هر کاراکتر به نمایشگر می رود و کاراکترها به نوبه خود با سرعت بالایی روشن می شوند که فرد آن را تشخیص نمی دهد و به نظر می رسد که نشانگر یکنواخت است. سوزش.

OPTION=0b00000000; // تنظیم TMR0 INTCON=0b10100000; // وقفه ها و فقط از TMR0 فعال هستند

برای کار کردن، به متغیرهای جهانی زیر نیاز دارید:

char بدون علامت v1,v2,v3, vn;

سه مورد اول مسئول مقادیر بخش های مربوطه هستند و آخرین مورد برای تعداد بخش در حال سوختن در لحظه (نشانگر پویا) است.

کنترل کننده وقفه مشغول پردازش یک تایمر است که به طور مداوم بخش ها را به نوبه خود تغییر می دهد.

وقفه خالی isr(void) ( if(T0IF) // هنگامی که TMR0 سرریز می شود (vn++؛ // سوئیچ قطعه سوئیچ(vn) // انتخاب بخش ( case 1:seg7(v1,1); break; case 2:seg7(v2 ,2); break; case 3:(seg7(v3,3);vn=0;)break; ) TMR0=100; // تنظیم تایمر روی چیزی غیر از ابتدای T0IF=0؛ // تنظیم مجدد پرچم ) )

تابع زیر برای نمایش مقدار نماد یک نمایشگر هفت بخش با یک آند مشترک استفاده می شود:

seg7 خالی (کاراکتر بدون علامت، کاراکتر بدون علامت) ( کاراکتر بدون علامت t=0؛ // g قطعه PORTA=0b00000000؛ // پورت بازنشانی سوئیچ(های) // انتخاب آند (مورد 1:(t=1;)شکست ؛ مورد 2:(t=2;)شکست؛ مورد 3:(t=32;)شکست؛ ) سوئیچ (c%10) // انتخاب قطعه (کاتد) (// 00bfaed g مورد 0: (PORTC=0b00000000; PORTA=t+4;)شکن =t;)شکست;مورد 4: (PORTC=0b00001110;PORTA=t;)شکست;مورد 5: (PORTC=0b00100100;PORTA=t;)شکست;مورد 6: (PORTC=0b00100000;PORTA=t;)شکست ;مورد 7: (PORTC=0b00010110;PORTA=t+4;)شکست;مورد 8: (PORTC=0b00000000;PORTA=t;)شکست;مورد 9: (PORTC=0b00000100;PORTA=t;)شکست; )

PIC16F676 دارای پورت‌های خروجی ناقص است، بنابراین تمام سگمنت‌ها روی پورت C قرار نمی‌گرفتند، قطعه g باید روی پورت A قرار می‌گرفت و نقطه باید به صورت شماتیک به یکی از آندهای رایج از طریق یک اینورتر متصل می‌شد. طرح چنین اتصالی به شرح زیر است:

اگر از میکروکنترلر دیگری استفاده می کنید که حداقل یک پورت کامل دارد، به عنوان مثال PIC16F628A

تابع به شکل زیر خواهد بود:

seg7 خالی (کاراکتر بدون علامت، نویسه بدون علامت) ( کاراکتر بدون علامت t=0؛ سوئیچ (c%10) // انتخاب بخش‌ها (کاتدها) (// gcPdeafb مورد 0: (t=0b10100000;) شکست؛ مورد 1: ( t=0b10111110;) شکست؛ مورد 2: (t=0b01100010;) شکست؛ مورد 3: (t=0b00101010;) شکست؛ مورد 4: (t=0b00111100;) شکست؛ مورد 5: (t=0b0010;) شکست ;مورد 6: (t=0b00100001;)شکست;مورد 7: (t=0b10111010;)شکست;مورد 8: (t=0b00100000;)شکست;مورد 9: (t=0b00101000;)شکستگی; PORTA=0000; // بازنشانی پورت سوئیچ(های) // آند را انتخاب کنید ( مورد 1:( PORTA =4;) شکست؛ مورد 2:( PORTA =8;) شکست؛ مورد 3:( PORTA =64;) شکست؛ ) PORTB= t؛ if(c>9) (PORTB=t ) )

نقطه کنار نماد روشن می شود اگر بابزرگتر از 9، مقدار همچنان روی نشانگر نمایش داده می شود، یعنی. تنها رقمی که کمترین اهمیت را دارد، خروجی می‌شود، هر چیز دیگری کنار گذاشته می‌شود (مثلاً: 1 9 , 39 = 9. ).

در تابع اصلی (اصلی) MK بی سر و صدا کار خود را برای خروجی انجام می دهد اطلاعات جدیدروی صفحه نمایش کافی است که مقادیر متغیرها را تغییر دهد v1,v2,v3، اما برای جلوگیری از سردرگمی در نشانگر باید همزمان آنها را تغییر داد.

نشانگر پویا به طور گسترده ای برای نمایش اطلاعات مختلف مانند دما، ولتاژ، زمان یا تعداد محرک های هر دستگاه یا سنسور استفاده می شود. نشانگر دینامیکی روی پایه با همکاری میکروکنترلرها کاملاً هماهنگ است. با این حال، در ادبیات برنامه نویسی میکروکنترلرهای AVRاین موضوع بسیار سطحی و نه در هر کتابی در مورد موضوع مربوطه مورد توجه قرار گرفته است. بنابراین، نحوه اتصال یک نشانگر هفت بخش با نشانگر پویا به یک میکروکنترلر، در این مورد، به ATmega8 را با جزئیات بیشتری در نظر خواهیم گرفت، اما این قیاس برای AVR MK هر سری حفظ می شود.

با تعداد ارقام (رقم)، نشانگرهای هفت بخش پویا تک رقمی، دو رقمی، سه رقمی، چهار رقمی و به ندرت شش رقمی هستند. ما بر روی شاخص های هفت بخش چهار رقمی، به عنوان پر استفاده ترین نوع نشانگر پویا تمرکز خواهیم کرد. آنها با یک آند مشترک و یک کاتد مشترک ساخته می شوند. نمودارهای اتصال LED های بخش های جداگانه در شکل ها نشان داده شده است.

همانطور که از شکل ها مشخص است، هر رقمی که رقم نامیده می شود، خروجی جداگانه خود را دارد که در داخل رقم مشترک است. از آنجایی که یک نشانه دینامیکی 4 رقمی در نظر گرفته شده است، چهار خروجی وجود دارد - digit1، digit2، digit3، digit4.

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

نحوه عملکرد نشانگر پویا

حال بیایید ببینیم که نشانگر دینامیکی با یک کاتد مشترک چگونه کار می کند. به عنوان مثال، باید عدد 1987 را نمایش دهیم. برای انجام این کار، در لحظه اول باید یک پتانسیل بالا به آندهای بخش هایی که یک واحد را تشکیل می دهند - b و c اعمال شود و یک پتانسیل کم باید اعمال شود. به کاتد مشترک دسته اول. کاتدهای مشترک سه رقم باقیمانده - digit2، digit3 و digit4 بدون اتصال باقی می مانند.

در لحظه دوم، بخش هایی که عدد 9 را تشکیل می دهند، توان دریافت می کنند، کاتد مشترک رقم دوم به منفی متصل می شود و رقم 1 قدرت را از دست می دهد. digit2، digit3، مانند قبل، بدون اتصال باقی می مانند.

در لحظه سوم، عدد 8 در نشانگر سوم روشن می شود و نشانگرهای باقی مانده خاموش می شوند.

در لحظه چهارم آخرین نشانگر برق دریافت می کند و عدد 7 نمایش داده می شود.

سپس همه چیز دوباره تکرار می شود. با فرکانس سوئیچینگ از دشارژ به دشارژ بیش از 25 هرتز، به دلیل اینرسی نور LED ها، چشمان ما زمانی را ندارند که متوجه چگونگی سوئیچینگ شوند، بنابراین از نظر بصری درخشش یکپارچه همه تخلیه ها را به طور همزمان درک می کنیم. .

طرحی برای اتصال نشانگر دینامیکی به میکروکنترلر ATmega 8

ما بخش‌های نشانگر پویا را از طریق قطعات محدودکننده جریان با مقدار اسمی 330 اهم به پین‌های پورت D میکروکنترلر ATmega8 متصل می‌کنیم. نتایج مربوط به digit1، digit2، digit3، digit4 از طریق ترانزیستورها متصل می شوند نوع n-p-n، مانند BC547 یا 2n2222 به پین ​​های پورت B.

الگوریتم برای نوشتن کد برای اتصال نشانه پویا

برای اقدامات خاص تر، از یک نشانگر هفت قطعه ای 4 رقمی با یک کاتد مشترک استفاده می کنیم. اولین قدم ایجاد آرایه ای از اعداد از 0 تا 9 است. قبلاً این را یاد گرفته بودیم، . در مرحله بعد، باید عدد 4 رقمی را به چهار رقم جداگانه تقسیم کنید. به عنوان مثال، شماره 1987 باید به 1، 9، 8 و 7 تقسیم شود. سپس واحد باید در رقم اول نشانگر، نه در دوم، هشت در سوم و هفت در چهارم نمایش داده شود.

در میان الگوریتم های متعدد برای تقسیم یک عدد چند رقمی به اعداد جداگانه، از عملیات تقسیم و باقیمانده تقسیم استفاده خواهیم کرد. به یک مثال توجه کنید:

1987/1000 → 1

1987%1000/100 → 9

1987%100/10 → 8

1987%10 → 7

در C، هنگام استفاده از نوع داده عدد صحیح بین المللی هنگام انجام تقسیم، تمام دهم ها، صدم ها و غیره، یعنی همه اعداد کوچکتر از یک، کنار گذاشته می شوند. فقط اعداد کامل باقی مانده است. گرد کردن ریاضی در اینجا کار نمی کند، بنابراین 1.9 در این مورد 1 خواهد بود، نه 2.

دستور "باقی مانده تقسیم" با علامت درصد نشان داده می شود. % ". این دستور همه اعداد صحیح را حذف می کند و بقیه اعداد را باقی می گذارد. به عنوان مثال، 1987%1000 → 987; 1987%100 → 87; 1987% 10 → 7.

در مرحله بعد باید دستوری بنویسید که ابتدا رقم اول و عدد مربوط به آن را نشان دهد و بعد از مدت زمان مشخصی رقم دوم و عدد مربوط به آن را نمایش دهد. و غیره در زیر کد با نظرات است.

کد

#تعریف کردن F_CPU 1000000 لیتر

#عبارتند از

#عبارتند از

#تعریف CHISLO PORTD

#تعریف RAZRIAD PORTB

int بدون علامت razr1 = 0، razr2 = 0، razr3 = 0، razr4 = 0.

عدد int بدون علامت = (

// اعداد از 0 تا 10

0x3f، 0x6، 0x5b، 0x4f، 0x66، 0x6d، 0x7d، 0x7، 0x7f، 0x6f

};

void vse_chislo (بدون امضا int rabivka_chisla)

{

razr1 = rabivka_chisla/1000; // هزاران

razr2 = rabivka_chisla%1000/100; // صدها

razr3 = rabivka_chisla%100/10; // ده ها

razr4 = rabivka_chisla%10; // واحدها

}

int main (void)

{

DDRB = 0b00001111;

DDRD = 0b11111111;

RAZRIAD = 0b00000001; // در ابتدا رقم اول

CHISLO=0x3f; // شماره 0

در حالی که (1)

{

vse_chislo (1987); // نمایش شماره

RAZRIAD = 0b00000001; // بیت اول را روشن کنید، بقیه را خاموش کنید

CHISLO=chisla ; // نمایش رقم 1

_delay_ms(3);

RAZRIAD = 0b00000010; // بیت دوم را روشن کنید، بقیه را خاموش کنید

CHISLO=chisla ; // رقم دوم را نمایش می دهد

_delay_ms(3);

RAZRIAD = 0b00000100; // بیت سوم را روشن کنید، بقیه را خاموش کنید

CHISLO=chisla ; // رقم 3 را نمایش می دهد

_delay_ms(3);

RAZRIAD = 0b00001000; // بیت 4 را روشن کنید، بقیه را خاموش کنید

CHISLO=chisla ; // رقم 4 را نمایش می دهد

_delay_ms(3);

}

}

بهبود برنامه برای نشان دادن پویا

الگوریتم فوق بیشتر یک الگوریتم یادگیری است، بنابراین تا حدودی ساده شده است، اما در برنامه هایی که هیچ محاسبات بلادرنگ سریعی انجام نمی دهند نیز جایگاهی دارد. تنها نقطه ضعف این الگوریتماستفاده از تأخیر است که قبلاً درباره تأثیر منفی آن صحبت شد. برای رهایی از استفاده از تاخیر، می توانید از وقفه های تایمر شمار استفاده کنید. در کد زیر، تأخیرها با استفاده از تایمر شمار صفر و فراخوانی وقفه در سرریز این شمارنده تشکیل شده است.

برای اینکه اعداد به صورت متوالی در هر رقم نشانگر در هر وقفه نمایش داده شوند، متغیر bc547 اضافه شده است که در تماس بعدی وقفه ISR (TIMER0_OVF_vect) یک عدد افزایش می یابد. سپس مقدار متغیر bc547 بررسی شده و بیت مربوطه با برق تامین می شود. وقتی bc547 بزرگتر از چهار شد، به یک بازنشانی می‌شود.

Dبرای نمایش یک عدد چند رقمی روی نشانگر، ابتدا باید یک دستکاری پیچیده با آن انجام دهید، که شامل شکستن عدد به اجزای آن است. به عنوان مثال، من نمایش عدد 1234 را روی یک نشانگر چهار قطعه ای با یک آند مشترک ارائه می دهم.


برای نمایش یک عدد چهار رقمی، باید یک متغیر مشترک ایجاد کنید که حاوی عددی باشد که می خواهید نمایش دهید (متغیر دبلیو)، چهار متغیر که داده ها را برای هر کاراکتر ذخیره می کند (ن) و چهار متغیر دیگر برای تبدیل های میانی (م) تا به متغیر اصلی دست نزنید. متغیر باید با مقداری که در آن ذخیره می شود مطابقت داشته باشد.من. بنابراین برای یک متغیردبلیونوع کافی خواهد بودعدد صحیح ، از آنجایی که متغیری از این نوع قابلیت xp را داردمتحرک کردن مقادیر از -32768 تا +32767 (یاکلمه مگر اینکه قصد استفاده از اعداد منفی را داشته باشید). در متغیرهاناعداد از 0 تا 9 را نشان می دهد، بنابراین استفاده از یک متغیر از نوع کافی استبایت
. و در متغیرهام خواهد بودهمان مقادیر موجود در متغیردبلیو، بنابراین نوع را تنظیم می کنیم عدد صحیح .

کم نور W به عنوان عدد صحیح
کم نور N1 به عنوان بایت
کم نور N2 به عنوان بایت
کم نور N3 به عنوان بایت
کم نور N4 به عنوان بایت
کم نور M1 به عنوان عدد صحیح
کم نور M2 به عنوان عدد صحیح
کم نور M3 به عنوان عدد صحیح
کم نور M4 به عنوان عدد صحیح


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

DDRC = &B11111111
DDRD = &B11111111


DDRC=&B 00001111 و DDRD=&B 01111111 (چهار پایه اول پورت Cبرای آندها و شش پورت اولبخش های فرعی D).

سپس به یک متغیر اختصاص دهیددبلیو مقداری که قرار است روی نشانگر نمایش دهیم:

W=1234

"Arial", "sans serif""> در حلقه اصلی برنامه به متغیرهای M مقدار متغیر را نسبت می دهیمW ، من این کار را انجام می دهم:

M1=W
M2 = M1
M3 = M1
M4 = M1


"Arial", "sans serif""> این پارانویا نیست))، این کار با این هدف انجام می شود که در همه متغیرهای M تعداد یکسانی وجود داشته باشد، زیرا در حین عملیات تخصیص یک وقفه (اگر وجود داشته باشد و غیرفعال نباشد) می تواند به راحتی وارد شود که در کنترل کننده آن متغیردبلیو می تواند تغییر کند. و اگر انتساب به این صورت بود: М1= W , M 2 = W , M 3 = W , M 4 = W در متغیرهای M قرار خواهد گرفت معانی مختلفکه منجر به آشفتگی در خواندن خواهد شد.

پس از تخصیص مقادیر به متغیرها، شروع به کار می کنیم
هر یک از آنها به گونه ای تبدیل می شوند که به یک متغیر تبدیل می شوندن به ارزشی که خواهد بود رسید
روی نشانگر نمایش داده می شود: در یک متغیر
ن 1 باید "1" باشد، در N 2 - "2"، در N 3 - "3" و در N 4 - "4".

M1=M1/1000" M1=1234/1000=1.234
N1=Abs(m1)" N1=Abs(1.234)=1

عضلات شکم – تابعی که یک عدد صحیح از یک متغیر را به یک متغیر برمی گرداندن 1 ضربه به واحد، که در واقع مورد نیاز بود.

برای اختصاص دو به یک متغیرن 2 عملیات کمی پیچیده تر خواهد بود:

M2= M2 Mod 1000 "M2 =1234 Mod 1000 = 234
M2=M2/100"M2=234/100=2.34
N2 = Abs (m2) "N2 = Abs (2.34) = 2

"Arial", "sans serif""> برای شروع با تابعمد ما سه مورد اول را برمی گردانیم
ارقام عدد (باقی مانده تقسیم بر 1000) و سپس همه چیز مانند حالت اول است.

با دو رقم آخر، تقریباً یکسان است:

M3 = M3 Mod100
M3=M3/10
N3 = Abs (m3)

M4 = M4 Mod 10
N4 = شکم (m4)


اکنون متغیرهای ما حاوی مقادیری هستند که می خواهیم نمایش دهیم، زمان آن رسیده است که میکروکنترلر پاهای خود را به پا کند و این مقادیر را روی نشانگر نمایش دهد، برای این کار ما زیر روال پردازش نمایشگر را می نامیم:

"Arial", "sans serif"">

Gosub Led

"Arial", "sans serif""> پردازنده به زیربرنامه برچسب زده شده می پردرهبری:

رهبری:

پورت = &B00001000

"Arial", "sans serif""> در اینجا ما در سطح بالایی خدمت می کنیمPORTC .3، آند دسته اول را به این پایه متصل کرده ایم. سپس انتخاب می کنیم که کدام بخش ها را روشن کنیم تا مقدار متغیر اول نمایش داده شود. او یکی از ماست، پس صفر روی پایش خواهد بود Portd .1 و Portd .2 که مربوط به بخش هاستنشانگر B و C

مورد N1 را انتخاب کنید









پایان انتخاب کنید
منتظر 5

"Arial", "sans serif""> پس از روشن شدن بخش های لازم، 5 میلی ثانیه صبر می کنیم و اعداد زیر را نمایش می دهیم:

پورت = &B00000100
مورد N2 را انتخاب کنید
مورد 0: Portd = &B11000000
مورد 1: Portd = &B11111001
مورد 2: Portd = &B10100100
مورد 3: Portd = &B10110000
مورد 4: Portd = &B10011001
مورد 5: Portd = &B10010010
مورد 6: Portd = &B10000010
مورد 7: Portd = &B11111000
مورد 8: Portd = &B10000000
مورد 9: Portd = &B10010000
پایان انتخاب کنید

منتظر 5

پورت = &B00000010

Case N3 را انتخاب کنید
مورد 0: Portd = &B11000000
مورد 1: Portd = &B11111001
مورد 2: Portd = &B10100100
مورد 3: Portd = &B10110000
مورد 4: Portd = &B10011001
مورد 5: Portd = &B10010010
مورد 6: Portd = &B10000010
مورد 7: Portd = &B11111000
مورد 8: Portd = &B10000000
مورد 9: Portd = &B10010000
پایان انتخاب کنید

منتظر 5

پورت = &B00000001

Case N4 را انتخاب کنید
مورد 0: Portd = &B11000000
مورد 1: Portd = &B11111001
مورد 2: Portd = &B10100100
مورد 3: Portd = &B10110000
مورد 4: Portd = &B10011001
مورد 5: Portd = &B10010010
مورد 6: Portd = &B10000010
مورد 7: Portd = &B11111000
مورد 8: Portd = &B10000000
مورد 9: Portd = &B10010000
پایان انتخاب کنید

منتظر 5

"Arial", "sans serif""> پس از نمایش اطلاعات روی نشانگر، باید به حلقه اصلی برنامه برگردید، جایی که باید حلقه را کامل کنید و پایان برنامه را علامت بزنید.

"Arial", "sans serif""> این چیزی است که در پایان به دست می آوریم:

"Arial", "sans serif"">

"Arial", "sans serif""> به دلیل تاخیر کم، سوئیچینگ برای چشم انسان قابل مشاهده نخواهد بود و عدد صحیح 1234 را خواهیم دید.

می توانید کد منبع و پروژه را در Proteus در زیر دانلود کنید:"Arial", "sans serif"">

گاهی اوقات لازم است چندین نشانگر هفت بخش یا یک ماتریس LED به میکروکنترلر متصل شود، در حالی که از نشانگر دینامیکی برای نمایش اطلاعات استفاده می شود. ماهیت نشانه پویا نمایش متوالی اطلاعات روی نشانگرها است. نمودار زیر نمونه ای از اتصال چندین نشانگر هفت قطعه ای (مثلاً با یک کاتد مشترک) برای پیاده سازی یک نشانگر دینامیکی را نشان می دهد، به طور کلی با در نظر گرفتن نقطه، 8 قطعه به دست می آید، اما به روش قدیمی. به این ترتیب نامیده می شود. تمام نتایج (آند) قطعاتی به همین نام به هم متصل می شوند، در مجموع 8 خط که از طریق مقاومت به میکروکنترلر متصل می شوند. کاتد مشترک هر نشانگر از طریق یک ترانزیستور به میکروکنترلر متصل می شود.


الگوریتم نشانگر به شرح زیر است: ابتدا سطوح منطقی مورد نیاز را بر روی خطوط تنظیم می کنیم، بسته به اینکه کدام بخش باید در اولین نشانگر روشن شود (نشان از چپ به راست)، با سطح منطقی بالا برای روشن کردن، پایین برای خاموش کردن بخش در مرحله بعد، سطح منطقی بالایی را به پایه ترانزیستور VT1 اعمال می کنیم، در نتیجه کاتد مشترک اولین نشانگر به سیم مشترک متصل می شود، در این لحظه آن بخش ها روشن می شوند که روی آندهای آن یک واحد منطقی وجود دارد. از طریق زمان مشخص(مکث) نشانگر را با اعمال یک سطح منطقی پایین به پایه ترانزیستور خاموش کنید، سپس مجدداً سطوح منطقی خطوط را مطابق با اطلاعات خروجی در نظر گرفته شده برای نشانگر دوم تغییر دهید و یک سیگنال روشن را به دستگاه اعمال کنید. ترانزیستور VT2. بنابراین، به ترتیب در یک چرخه دایره‌ای، همه نشانگرها را تغییر می‌دهیم، این کل نشانه پویا است.

برای گرفتن یک تصویر جامد بدون سوسو زدن، سوئیچینگ باید با سرعت بالا انجام شود، برای از بین بردن سوسو زدن LED ها، نرخ تجدید باید از 70 هرتز یا بیشتر تنظیم شود، من معمولا آن را روی 100 هرتز تنظیم می کنم. برای ساخت فوق، مکث به صورت زیر محاسبه می شود: برای فرکانس 100 هرتز، دوره 10 میلی ثانیه است، به ترتیب تنها 4 نشانگر وجود دارد، زمان درخشش هر نشانگر 10/4 = 2.5 میلی ثانیه تنظیم شده است. در یک مسکن نشانگرهای هفت قسمتی چند رقمی وجود دارد که در آنها قطعاتی به همین نام در داخل خود هوزینگ به هم متصل می شوند که البته برای استفاده از آنها باید از نشانگر دینامیک استفاده کرد.

برای پیاده سازی نشانگر پویا، لازم است از وقفه در سرریز یکی از تایمرها استفاده شود. در زیر کد با استفاده از تایمر TMR0 آمده است:

;اجرای اندیکاسیون پویا برای 4 اندیکاتور هفت قطعه ای ;;;;;;;;;;;;;; swapf STATUS,W ; وضعیت clrf ; movwf STATUS_TEMP ; ; bcf ind1 ;نشانگر 1 را خاموش کنید bcf ind2 ;نشانگر دوم را خاموش کنید bcf ind3 ;نشانگر سوم را خاموش کنید bcf ind4 ;نشانگر چهارم را خاموش کنید. incf shet,F ;increment register shet movlw .5 ;برگ محتویات ثبت را بررسی کنید shet xorwf,W ;بررسی کنید که برابر با 5 btfss STATUS,Z ; goto met1 ;تعداد در شیت رجیستر برابر با 5 movlw نیست .1 ;عدد در شیت رجیستر 5 است: شماره 1 را بنویسید movwf shet ;into shet register ; met1 movlw .1 ؛ بررسی رجیستر محتویات shet xorwf shet,W ؛ برابر با شماره 1 btfss STATUS,Z ; goto met2 ؛ عدد در رجیستر شیت برابر با 1 نیست: پرش به met2 movf datind1، W ؛ تعداد در رجیستر شیت برابر با 1 است: movwf PORTB را کپی کنید؛ محتویات ثبت نام datind1 را در رجیستر PORTB bsf ind1؛ اولین اندیکاتور met2 را روشن کنید. movlw .2 ;بررسی محتویات شیت ثبت xorwf shet,W ؛ برابر با 2 btfss STATUS,Z ; goto met3 ؛ شماره در رجیستر شیت برابر با 2 نیست: پرش به met3 movf datind2، W ؛ شماره در رجیستر شیت 2 است: movwf PORTB را کپی کنید ؛ محتویات datind2 را در ثبت PORTB ثبت کنید bsf ind2 ؛ نشانگر دوم را روشن کنید باید خروج کنید ؛ پرش به label exit met3 movlw .3 ؛ بررسی رجیستر محتویات shet xorwf shet,W ؛ برابر با 3 btfss STATUS,Z . goto met4 ؛ شماره در رجیستر شیت برابر با 3 نیست: پرش به met4 movf datind3، W ؛ شماره در رجیستر شیت 3 است: movwf PORTB را کپی کنید؛ محتویات ثبت نام datind3 را در رجیستر PORTB bsf ind3 روشن کنید؛ نشانگر 3 را روشن کنید، خروج را انتخاب کنید؛ پرش به label exit met4 movf datind4,W ;محتویات رجیستر datind3 movwf PORTB را کپی کنید ;در رجیستر PORTB bsf ind4 ;نشانگر چهارم را روشن کنید. movlw .100 ;نوشتن 156 به ثبت زمان سنج TMR0 movwf TMR0 ; ; وضعیت movwf ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; ;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;; برنامه اصلی ................. movlw b"11010011"؛ OPTION_REG، در نتیجه داخلی را تنظیم می کند؛ نسبت پیش مقیاس کننده را 1:16 تنظیم می کند. صفحه clrf، تنظیم مجدد برگه ثبت، قبل از شروع، وقفه در سرریز TMR0، انجام شده. clrf datind1 ;پاک کردن رجیسترها برای خروجی اطلاعات به clrf datind2 ;نشانگرها، معادل خاموش کردن clrf datind3 ;نشانگرها به عنوان اندیکاتورهایی با clrf datind4 ;کاتد مشترک است. bcf INTCON,T0IF؛ پاک کردن وقفه سرریز TMR0 پرچم bsf INTCON,T0IE؛ فعال کردن وقفه های سرریز TMR0 bsf INTCON,GIE؛ فعال کردن وقفه های سراسری. movlw b"00000110" ؛ خروجی 13.52 نمونه movwf datind1 ; movlw b"11001111" ; movwf date2 ; movlw b"01101101" ; movwf date3 ; movlwb"01011011" ; movwf date4 ; ; . ................ .................; .................; ; پایان ؛ پایان کل برنامه

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;اجرای نشانگر پویا برای 4 اندیکاتور هفت بخش

فرکانس ساعت نمونه 4 مگاهرتز، چرخه ماشین 1 میکرو ثانیه

org 0000h؛ اجرای برنامه را در آدرس 0000h شروع کنید

goto Start ;به برچسب Start بروید

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

؛ وقفه در روال

org 0004h ;شروع اجرای زیربرنامه در آدرس 0004h

movwf W_TEMP ;مقادیر ثبت کلید را ذخیره کنید

swapf STATUS,W ;

movwf STATUS_TEMP ;

bcf ind1 ;نشانگر 1 را خاموش کنید

bcf ind2 ;نشانگر دوم را خاموش کنید

bcf ind3 ؛ نشانگر سوم را خاموش کنید

bcf ind4 ؛ نشانگر چهارم را خاموش کنید

incf shet,F ;ورق ثبت افزایشی

movlw .5 ؛ محتویات شیت ثبت را بررسی کنید

ورق xorwf، W ؛ برابر با 5

btfss STATUS,Z ;

goto met1 ؛ عدد در شیت رجیستر برابر با 5 نیست

movlw .1 ؛ عدد در شیت رجیستر 5 است: عدد 1 را بنویسید

برگه movwf ;ثبت برگه

met1 movlw .1 ؛ محتویات ثبت شیت را بررسی کنید

shet xorwf,W ؛ برابر با عدد 1

btfss STATUS,Z ;

goto met2 ؛ عدد در رجیستر 1 برابر نیست: به met2 بروید

movf datind1,W ؛ شماره در رجیستر 1 است: کپی

movwf PORTB ؛ محتویات datind1 در رجیستر PORTB ثبت نام کنید

bsf ind1 ;نشانگر 1 را روشن کنید

goto exit ;برو به label exit

met2 movlw .2 ؛ محتویات ثبت شیت را بررسی کنید

shet xorwf,W ؛ برابر با عدد 2

btfss STATUS,Z ;

goto met3 ؛ عدد در رجیستر 2 برابر نیست: به met3 بروید

movf datind2,W ؛ شماره در رجیستر 2 است: کپی

movwf PORTB ؛ محتویات datind2 در رجیستر PORTB ثبت نام کنید

bsf ind2 ;نشانگر دوم را روشن کنید

goto exit ;برو به label exit

met3 movlw .3 ؛ محتویات ثبت شیت را بررسی کنید

shet xorwf,W ؛ برابر با عدد 3

btfss STATUS,Z ;

goto met4 ؛ عدد در رجیستر برابر با 3 نیست: به met4 بروید

movf datind3,W ؛ شماره در رجیستر 3 است: کپی

movwf PORTB؛ محتویات datind3 به رجیستر PORTB ثبت نام کنید

bsf ind3 ؛ نشانگر 3 را روشن کنید

goto exit ;برو به label exit

met4 movf datind4,W ؛ محتویات ثبت datind3 را کپی کنید

movwf PORTB ;به PORTB ثبت نام کنید

bsf ind4 ؛ نشانگر چهارم را روشن کنید

خروج از bcf INTCON,T0IF ؛ بازنشانی پرچم وقفه سرریز TMR0

movlw .100 ؛ عدد 156 را برای ثبت زمان سنج TMR0 بنویسید

swapf STATUS_TEMP،W؛ بازیابی محتویات رجیسترهای کلید

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;خروج از روال وقفه

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

؛ برنامه اصلی

شروع ................. ؛تنظیم اولیه رجیسترها

................. ؛هدف خاص

.................

bsf STATUS,RP0 ;نوشتن عدد باینری 11010011 جهت ثبت نام

movlw b"11010011" ;OPTION_REG، در نتیجه تنظیمات داخلی

movwf OPTION_REG؛ منبع ساعت برای TMR0

bcf STATUS,RP0 ;پیش مقیاس کننده را قبل از TMR0 فعال کنید

؛ نسبت پیش مقیاس کننده را روی 1:16 تنظیم کنید

clrf shet؛ رجیستر شیت را قبل از شروع بازنشانی کنید

وقفه سرریز TMR0، انجام شد

؛ یک بار پس از روشن شدن

clrf datind1؛ رجیسترهای روشن برای خروجی اطلاعات به

clrf datind2 ;شاخص ها، معادل خاموش

clrf datind3 ;شاخص‌ها، زیرا شاخص‌هایی با یک مشترک

clrf datind4 ;کاتد

bcf INTCON,T0IF ;پرچم وقفه سرریز TMR0 را بازنشانی کنید

bsf INTCON,T0IE ؛ وقفه های سرریز TMR0 را فعال کنید

bsf INTCON,GIE ؛ وقفه های سراسری را فعال کنید

movlw b"00000110"؛ نمونه خروجی 13.52

movlw b"11001111" ;

movlw b"01101101" ;

movlwb"01011011" ;

................. ;

................. ;

................. ;

پایان؛ پایان کل برنامه

در برنامه اصلی، ابتدا با استفاده از رجیستر OPTION_REG یک تایمر تنظیم کردیم، قبلاً در مورد استفاده از تایمر برای . در مرحله بعد، ثبت شیت را که برای وارد کردن تعداد از 1 تا 4 در نظر گرفته شده است، برای هر نشانگر پاک می کنیم. این رجیستر در روال سرویس وقفه افزایش می یابد و در آنجا تنظیم می شود (از 1 تا 4 به حساب می آید)، بنابراین این پاکسازی یک بار پس از روشن شدن انجام می شود. بر اساس این رجیستر، ما تعیین خواهیم کرد که کدام اندیکاتور را شامل و داده های مربوط به آن را صادر کنیم. مرحله بعدی پاک کردن رجیسترهای ذخیره اطلاعات است، چهار رجیستر dataind1،2،3،4 مربوط به چهار شاخص. پاک کردن معادل خاموش کردن نشانگرها است، زیرا در روال سرویس وقفه، محتویات این رجیسترها به رجیستر PORTB منتقل می شود که آندهای نشانگر به آن متصل می شوند. این امر ضروری است تا پس از فعال شدن وقفه ها، هر گونه زباله روی نشانگرها نمایش داده نشود، در اصل اگر اطلاعات صحیح بلافاصله برای خروجی نوشته شود، نمی توان این کار را انجام داد. در مرحله بعد، پرچم وقفه سرریز تایمر را بازنشانی کنید، وقفه های سرریز TMR0 را فعال کنید و در نهایت وقفه های سراسری را فعال کنید.

در روال وقفه ابتدا همه نشانگرها را خاموش می کنیم (با اعمال سطوح منطقی پایین به پایه های ترانزیستورها)، چون معلوم نیست کدام یک روشن است. ما رجیستر برگ را افزایش می دهیم و برابری را با عدد 5 بررسی می کنیم، اگر چنین تطابقی وجود دارد، عدد 1 را در رجیستر بنویسید، زیرا لازم است تعداد را از 1 تا 4 نگه دارید. سپس بررسی می کنیم که کدام عدد در رجیستر است. shet register، که به وسیله آن داده ها را از PORTB در رجیسترهای ذخیره اطلاعات PORTB (dataind) برای نشانگر مربوطه بارگذاری می کنیم و آن را روشن می کنیم. پس از آن، پرچم وقفه سرریز TMR0 را بازنشانی می کنیم، عدد 100 را در تایمر می نویسیم (محاسبه این مقدار در زیر آورده شده است)، برای یک تاخیر زمانی، و از کنترل کننده وقفه خارج می شویم. در اولین وقفه، نشانگر اول روشن می شود، در وقفه دوم، وقفه دوم، و غیره در یک چرخه دایره ای. در برنامه اصلی، فقط بارگذاری داده ها در ثبت های ذخیره سازی اطلاعات برای هر نشانگر باقی می ماند. در زیربرنامه وقفه، ذخیره و بازیابی مقادیر رجیسترهای کلید را فراموش نکنید، در مقاله ای در مورد این موضوع نوشتم.

برای خروجی اعداد بهتر است از یک مولد کاراکتر به شکل جدول داده استفاده کنید. به عنوان مثال، برای نمایش عدد 3456 روی نشانگرها، باید آن را به ارقام تقسیم کرد، در حالی که بهتر است از ثبات های جداگانه برای ذخیره اعداد ارقام (از 0 تا 9) استفاده کنید، سپس این ثبات ها را از طریق مولد کاراکتر اجرا کنید. به دست آوردن بایت های صحیح (بارگذاری شده در رجیسترهای dataind) برای احتراق بخش های مربوطه.

فرکانس مولد ساعت را 4 مگاهرتز می گیریم، سیکل ماشین 1 میکرو ثانیه است. بگذارید نرخ تازه سازی هر نشانگر 100 هرتز باشد (دوره T = 10 ms) به ترتیب، تاخیر زمانی مورد نیاز 10/4 = 2.5 میلی ثانیه است. ضریب پیش مقیاس کننده برای TMR0 روی 1:16 تنظیم شده است، در حالی که حداکثر تاخیر ممکن 256x16 = 4096 میکرو ثانیه است و به مکث 2.5 میلی ثانیه نیاز داریم. بیایید عددی را که باید روی TMR0 بنویسیم محاسبه کنیم: 256-((256x2.5)/4.096) = 256-156.25 = 99.75. پس از گرد کردن، عدد 100 را بدست می آوریم.

در زیر می توانید مدل برنامه پروتئوس، سیستم عامل و کد منبع را با اجرای نشانگر پویا روی یک نشانگر 4 رقمی با کاتد مشترک با استفاده از میکروکنترلر PIC16F628A دانلود کنید. به عنوان مثال، اعداد 0000 روی نشانگر نمایش داده می شوند. 0001; 0002; 13.52; 9764.

اکنون اتصال ماتریسی با وضوح 8x8 پیکسل (LED) را در نظر بگیرید. ساختار یک ماتریس معمولاً بر حسب ردیف و ستون در نظر گرفته می شود. در تصویر زیر در هر ستون کاتد تمام ال ای دی ها و در هر ردیف آندها به هم وصل شده اند. رشته ها (8 خط، آند LED) از طریق مقاومت ها به میکروکنترلر متصل می شوند. هر ستون (کاتدهای LED) از طریق 8 ترانزیستور به میکروکنترلر متصل می شود. الگوریتم نشانگر یکسان است، ابتدا سطوح منطقی لازم را روی ردیف ها تنظیم می کنیم، مطابق با آن LED ها باید در ستون روشن شوند، سپس ستون اول را وصل می کنیم (نشان از چپ به راست). پس از یک مکث مشخص، ستون را خاموش می کنیم و سطوح منطقی خطوط را تغییر می دهیم تا ستون دوم نمایش داده شود، سپس ستون دوم را به هم وصل می کنیم. و بنابراین به طور متناوب همه ستون ها را رفت و آمد کنید. در زیر نموداری از اتصال ماتریس به میکروکنترلر نشان داده شده است.


در مجموع برای اتصال چنین ماتریسی به 16 پین میکروکنترلر نیاز است که بسیار زیاد است بنابراین برای کاهش خطوط کنترل بهتر است از رجیسترهای شیفت سریال استفاده کنید.

رایج ترین رجیستر سریال ریزمدار 74HC595 است که شامل یک رجیستر شیفت برای بارگذاری داده ها و یک ثبات نگهدارنده است که از طریق آن داده ها به خطوط خروجی منتقل می شود. بارگذاری داده ها در آن ساده است، 0 منطقی را در ورودی ساعت SH_CP تنظیم کنید، سپس سطح منطقی مورد نیاز را در ورودی داده DS تنظیم کنید، پس از آن، ورودی ساعت را به 1 تغییر می دهیم، در حالی که مقدار سطح (در ورودی DS) است. در داخل شیفت رجیستر ذخیره می شود. در همان زمان، داده ها یک بیت جابجا می شوند. خروجی SH_CP را مجدداً روی 0 تنظیم می کنیم، سطح مورد نیاز را در ورودی DS تنظیم می کنیم و SH_CP را به 1 افزایش می دهیم. پس از بارگیری کامل رجیستر shift (8 بیت)، خروجی ST_CP را روی 1 تنظیم می کنیم، در این لحظه داده ها منتقل می شوند. به رجیستر ذخیره سازی و تغذیه به خطوط خروجی Q0 ... Q7، پس از آن ما خروجی ST_CP را تنظیم مجدد می کنیم. در طول بارگذاری متوالی، داده ها از Q0 به Q7 منتقل می شوند. پین Q7 به آخرین بیت رجیستر شیفت متصل است، این پین می تواند به ورودی تراشه دوم متصل شود، بنابراین می توانید داده ها را در دو یا چند تراشه به طور همزمان بارگذاری کنید. پین OE خطوط خروجی را به حالت سوم (مقاومت بالا) سوئیچ می کند که یک منطق 1 روی آن اعمال شود. پایه MR برای تنظیم مجدد رجیستر شیفت طراحی شده است، یعنی تنظیم سطوح منطقی پایین در خروجی های تریگرهای رجیستر. ، که معادل بارگذاری هشت صفر است. در زیر نموداری از بارگذاری داده ها در تراشه 74NS595 وجود دارد که مقدار 11010001 را در خطوط خروجی Q0 ... Q7 تنظیم می کند، به شرطی که در ابتدا صفر وجود داشته باشد:


اتصال یک ماتریس 8×8 را به میکروکنترلر PIC16F628A با استفاده از دو رجیستر شیفت 74HC595 در نظر بگیرید، نمودار زیر نشان داده شده است:


داده ها در تراشه DD2 بارگذاری می شوند (کنترل سطح منطقی روی ردیف ها، آندهای LED)، سپس از طریق پین Q7 به DD3 (کنترل ستون) منتقل می شوند، ابتدا بایت را بارگذاری می کنیم تا ستون فعال شود، سپس بایت با سطوح منطقی روی ردیف ها. ستون های ماتریس سوئیچینگ ترانزیستور (کاتدهای LED) به خطوط خروجی DD3 متصل می شوند. کد برنامه برای نمایش تصویر روی ماتریس در زیر آمده است:

;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;; ;اجرای نشانگر دینامیکی برای یک ماتریس با وضوح 8x8 ;فرکانس مولد ساعت به عنوان مثال 4 مگاهرتز، چرخه ماشین 1 μs org 0000h ;شروع اجرای برنامه از آدرس 0000h goto Start ;پرش به برچسب شروع ;;;;; ;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;; ;وقفه روتین org 0004h ;شروع اجرای زیربرنامه از آدرس 0004h movwf W_TEMP ;ذخیره مقادیر ثبت کلید swapf STATUS,W ; وضعیت clrf ; movwf STATUS_TEMP ; ; movwf FSR_osn ;به رجیستر FSR_osn movf FSR_prer,W ;بازیابی مقدار ذخیره شده قبلی movwf FSR ;رجیستر FSR از رجیستر FSR_prer ;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; محتویات رجیستر stolb را در تراشه movf stolb بارگذاری کنید، W ;محتویات رجیستر stolb را کپی کنید movwf var ;در ثبات var met2 btfsc var,0 ؛ ds خروجی را مطابق با btfss var,0 تنظیم کنید. bcf ds ; bcf sh_cp ; rrf var,F ;Shift register var به سمت راست برای آماده سازی;بیت بعدی goto met2 ;scetbit برابر با صفر نیست: پرش به برچسب met2 ;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; ؛ محتویات رجیستر INDF را در تراشه بارگذاری کنید؛ 74HC595 (رجیستر شیفت سریال) movf INDF,W؛ محتویات رجیستر INDF movwf var را کپی کنید؛ در رجیستر var movlw .8؛ عدد 8 را در ثبات scetbit بنویسید. برای شمارش movwf scetbit ;بیت های منتقل شده met1 btfsc var ,7 ;تنظیم خروجی ds بر اساس bsf ds ;مقدار بیت 7 ثبات var btfss var,7 ; bcf ds ; bsf sh_cp ;خروجی ساعت sh_cp برای اتصال داده bcf sh_cp ; rlf var,F ;Shift register var سمت چپ برای آماده سازی;بیت بعدی decfsz scetbit,F ;کاهش با شرط ثبت scetbit goto met1 ;scetbit برابر با صفر نیست: پرش به برچسب met1 ; bsf st_cp ؛ ساعت خروجی st_cp برای انتقال bcf بارگذاری شده st_cp ؛ بایت ها به خطوط خروجی تراشه های 74HC595 . bcf STATUS,C ;تنظیم بیت C وضعیت رجیستر قبل از shift rrf stolb,F ; ثبت shift چپ stolb ; incf FSR,F ;افزایش رجیستر FSR، آماده بعدی ;ثبت نام برای ارسال داده به 74HC595 decfsz shet,F ;کاهش با برگه شرط ثبت goto exit ;ثبت ثبت مساوی 0 نیست: پرش به خروج از movlw data1 ;ثبت ثبت برابر با 0: آدرس اول را بنویسید movwf FSR ;ثبت نام برای ذخیره اطلاعات در رجیستر FSR movlw .8 ;نوشتن عدد 8 در رجیستر شیت برای نگهداری ورق movwf ;شمارش ستون ها ; خروج از bcf INTCON,T0IF ;بازنشانی پرچم وقفه سرریز TMR0 movlw . 124 ;برای ​​ثبت تایمر TMR0 movwf TMR0 عدد 124 را بنویسید ; ; movf FSR,W ;ذخیره مقدار فعلی FSR movwf FSR_prer ;به FSR_prer movf FSR_osn ,W ;بازیابی مقدار ذخیره شده قبلی movwf FSR ;FSR از FSR_osn ; swapf STATUS_TEMP,W ؛ بازیابی محتویات رجیسترهای کلیدی movwf STATUS . swapf W_TEMP,F ; swapf W_TEMP,W ; ; رتفی ;خروج از زیربرنامه وقفه;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;; ;شروع برنامه اصلی ................ ;تنظیم اولیه رجیسترها ................. ;هدف ویژه..... ............ bsf STATUS,RP0 ;عدد باینری 11010011 را در register movlw b"11010010" ;OPTION_REG بنویسید و بدین ترتیب منبع ساعت داخلی movwf OPTION_REG را تنظیم کنید ;منبع ساعت برای TMR0 bcf STATUS,RP0 ;پیش مقیاس کننده را قبل از فعال کردن TMR0؛ نسبت پیش مقیاس کننده را 1:8 تنظیم کنید. movlw .8؛ نوشتن شماره 8 در ثبت شیت، قبل از شروع شیت movwf، وقفه های سرریز tmr0، اجرا می شود؛ یک بار، پس از روشن شدن movlw b"10000000"؛ نوشتن عدد باینری 10000000 در movwf stolb ;stolb1st ستون، برای فعال کردن یک بار، پس از روشن کردن برق انجام می شود. movlw data1 ;آدرس اولین رجیستر (ثبت‌های ذخیره‌سازی movwf FSR_prer ;اطلاعات) را در رجیستر FSR_prer بنویسید، یک بار پس از روشن شدن. movlw .8 ;پاک کردن 8 رجیستر خروجی اطلاعات به movwf tmp ;ماتریس معادل خاموش کردن movlw data1 ;ماتریس movwf FSR ; met3 clrf INDF ; incf FSR,F ; decfsz tmp,F ; goto met3 ; ; bcf INTCON,T0IF؛ پاک کردن وقفه سرریز TMR0 پرچم bsf INTCON,T0IE؛ فعال کردن وقفه های سرریز TMR0 bsf INTCON,GIE؛ فعال کردن وقفه های سراسری. m1 movlw data1؛ خروجی R مثال movwf FSR. movlw b"00000000" ; movwf INDF ; incf FSR,F ; movlw b"01111111" ; movwf INDF ; incf FSR,F ; movlwb"00001001" ; movwf INDF ; incf FSR,F ; movlwb"00011001" ; movwf INDF ; incf FSR,F ; movlwb"00101001" ; movwf INDF ; incf FSR,F ; movlw b"01000110" ; movwf INDF ; incf FSR,F ; movlw b"00000000" ; movwf INDF ; incf FSR,F ; movlw b"00000000" ; movwf INDF ; ; .................; .................; .................; ; پایان ؛ پایان کل برنامه

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

پیاده سازی نشانگر پویا برای یک ماتریس با وضوح 8x8

فرکانس ساعت نمونه 4 مگاهرتز، چرخه ماشین 1 میکرو ثانیه

org 0000h؛ اجرای برنامه را در آدرس 0000h شروع کنید

goto Start ;به برچسب Start بروید

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

؛ وقفه در روال

org 0004h ;شروع اجرای زیربرنامه در آدرس 0004h

movwf W_TEMP ;مقادیر ثبت کلید را ذخیره کنید

swapf STATUS,W ;

movwf STATUS_TEMP ;

movf FSR,W مقدار فعلی رجیستر FSR را ذخیره کنید

movwf FSR_osn ;به ثبت نام FSR_osn

movf FSR_prer,W ؛ مقدار ذخیره شده قبلی را بازیابی کنید

movwf FSR ;FSR از FSR_prer

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;74HC595 (رجیستر شیفت سریال)

movf stolb,W ؛ کپی محتویات stolb register

movwf var ;ثبت نام var

movlw .8 برای شمارش عدد 8 را در ثبات scetbit بنویسید

movwf scetbit ;بیت های ارسال شده

met2 btfsc var,0 ;خروجی ds را بر اساس تنظیم کنید

bsf ds ؛ ارزش بیت هفتم ثبات var

bsf sh_cp ;clock sh_cp خروجی برای چفت کردن داده ها

rrf var,F ؛ shift register var سمت راست برای آماده سازی

؛ بیت بعدی

decfsz scetbit,F ؛ کاهش با شرایط ثبت scetbit

goto met2 ;scetbit برابر با صفر نیست: به برچسب met2 بروید

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;74HC595 (رجیستر شیفت سریال)

movf INDF,W ؛ محتویات ثبت INDF را کپی کنید

movwf var ;ثبت نام var

movlw .8 برای شمارش عدد 8 را در ثبات scetbit بنویسید

movwf scetbit ;بیت های ارسال شده

met1 btfsc var,7 ;خروجی ds را بر اساس تنظیم کنید

bsf ds ؛ ارزش بیت هفتم ثبات var

bsf sh_cp ;clock sh_cp خروجی برای چفت کردن داده ها

rlf var,F ;تغییر چپ var برای آماده سازی

؛ بیت بعدی

decfsz scetbit,F ؛ کاهش با شرایط ثبت scetbit

goto met1 ;scetbit برابر با صفر نیست: به برچسب met1 بروید

bsf st_cp ؛ خروجی st_cp را برای انتقال بارگذاری شده ساعت کنید

bcf st_cp ;بایت در هر خط خروجی 74HC595

bcf STATUS،C؛ بیت C را از ثبت وضعیت قبل از شیفت پاک کنید

rrf stolb،F ؛ ثبت شیفت چپ stolb

incf FSR,F ;رجیستر FSR را افزایش دهید، بعدی را آماده کنید

؛ برای ارسال داده ها به 74HC595 ثبت نام کنید

decfsz shet,F ;کاهش با برگه شرایط ثبت

goto exit ;shet register برابر 0 نیست: پرش به خروج

movlw data1 ;shet register 0 است: آدرس اولین را بنویسید

movwf FSR ;ثبت نام برای ذخیره اطلاعات در FSR

movlw .8 برای مرجع، عدد 8 را در ثبت شیت بنویسید

ورق movwf ؛ تعداد ستون ها

movlw b"10000000"؛ عدد باینری 10000000 را بنویسید

movwf stolb ؛ stolb را ثبت کنید تا ستون 1 را شامل شود

خروج از bcf INTCON,T0IF ؛ بازنشانی پرچم وقفه سرریز TMR0

movlw .124 ;عدد 124 را برای ثبت تایمر TMR0 بنویسید

movf FSR,W مقدار فعلی رجیستر FSR را ذخیره کنید

movwf FSR_prer ;به ثبت نام FSR_prer

movf FSR_osn ,W ؛ مقدار ذخیره شده قبلی را بازیابی کنید

movwf FSR ;FSR از FSR_osn

swapf STATUS_TEMP،W؛ بازیابی محتویات رجیسترهای کلید

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;خروج از روال وقفه

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

؛ برنامه اصلی

شروع ................. ؛تنظیم اولیه رجیسترها

................. ؛هدف خاص

.................

bsf STATUS,RP0 ؛ برای ثبت نام عدد باینری 11010011 را بنویسید

movlw b"11010010" ;OPTION_REG، در نتیجه تنظیمات داخلی

movwf OPTION_REG؛ منبع ساعت برای TMR0

bcf STATUS,RP0 ;پیش مقیاس کننده را قبل از TMR0 فعال کنید

;نسبت پیش مقیاس کننده را روی 1:8 تنظیم کنید

movlw .8 ؛ قبل از اجرا، عدد 8 را در رجیستر شیت بنویسید

صفحه movwf؛ سرریز TMR0 قطع می شود، در حال اجرا است

؛ یک بار پس از روشن شدن

movlw b"10000000"؛ عدد باینری 10000000 را بنویسید

movwf stolb ؛ stolb را ثبت کنید تا ستون 1 را شامل شود

اطلاعات با سطوح منطقی برای سطرهای هر ستون در 8 رجیستر ذخیره اطلاعات ذخیره می شود که از طریق آنها قابل دسترسی است. آدرس اولین رجیستر data1 نام دارد. علاوه بر نوشتن اولیه رجیسترهای shet و stolb، باید آدرس اولین رجیستر ذخیره اطلاعات را در رجیستر FSR_prer نیز بنویسید (رجیستر data1 است، ورود در FSR_prer یک بار انجام می شود، سپس در هندلر تصحیح می شود) ، فقط پس از آن، وقفه های سرریز TMR0 را فعال کنید.

قبل از فعال کردن وقفه ها، پاک کردن رجیسترهای ذخیره اطلاعات مطلوب است، این عملیات با استفاده از ثبات tmp اضافی (به عنوان شمارنده) و آدرس دهی غیر مستقیم انجام می شود، پاکسازی معادل خاموش کردن ماتریس است.

در روال مدیریت وقفه، محتویات رجیستر stolb را در تراشه DD2 بارگذاری می کنیم (در اولین باری که بعد از فعال کردن وقفه ها وارد هندلر می شوید، همانطور که در بالا ذکر شد، رجیستر دارای عدد 10000000 است). بارگذاری از بیت پایین رجیستر stolb شروع می شود، که در جهت بارگذاری از Q0 به Q7 (داخل تراشه DD2) تغییر می کند، الگوریتم بارگذاری در بالا مورد بحث قرار گرفت، بنابراین فکر می کنم درک کد دشوار نخواهد بود. . در مرحله بعد، محتویات رجیستر INDF را در DD2 بارگذاری می کنیم، این یکی از رجیسترهای ذخیره اطلاعات است که آدرس آن در FSR است (اولین باری که بعد از فعال کردن وقفه ها هندلر را وارد می کنید، FSR حاوی آدرس اولین است. ثبت ذخیره اطلاعات به نام data1). بارگیری از بیت بالای رجیستر INDF شروع می شود. پس از بارگذاری 2 بایت در نظر گرفته شده، خروجی st_cp را کلاک می کنیم، در نتیجه داده های دانلود شده به خطوط خروجی ریز مدارهای DD2، DD3 منتقل می شوند. بنابراین، در اولین ورودی به هندلر، اولین ستون ماتریس سوئیچ می شود، که در آن LED ها روشن می شوند، که بر روی آندهای آن سطح منطقی بالایی وجود دارد، مطابق با محتوای ثبت داده 1 ( اولین ثبت ذخیره اطلاعات).

سپس، ثبات stolb را یک بیت به سمت راست منتقل می کنیم تا ستون دوم ماتریس را برای سوئیچینگ در ورودی بعدی به کنترل کننده وقفه آماده کنیم. پرچم C ثبت STATUS باید قبل از شیفت پاک شود، زیرا تغییر از طریق این پرچم انجام می شود و وضعیت آن در زمان تغییر مشخص نیست. پس از تغییر، رجیستر FSR را افزایش می دهیم و رجیستر ذخیره سازی بعدی (بعد از ثبات data1) را با سطوح سطر منطقی برای ستون دوم آماده می کنیم. در مرحله بعد رجیستر شیت را با شرط کم می کنیم و اگر برابر با صفر نبود پرچم وقفه سرریز TMR0 را ریست می کنیم و عدد را روی تایمر می نویسیم و از کنترل کننده وقفه خارج می شویم.

دفعه بعد که وارد handler می شوید، ستون دوم ماتریس فعال می شود و به همین ترتیب. هنگامی که رجیستر شیت ریست می شود (پس از تعویض ستون 8)، عدد 8 برای چرخه بعدی تعویض ستون ها روی آن نوشته می شود، علاوه بر این، مقدار ثبات stolb تصحیح می شود، آدرس اولین ثبت ذخیره اطلاعات ( data1) در رجیستر FSR نوشته می شود.

بیایید تاخیر زمانی را برای تایمر TMR0 محاسبه کنیم، فرکانس ساعت 4 مگاهرتز است، چرخه ماشین 1 میکرو ثانیه است. برای جلوگیری از سوسو زدن LED ها، اجازه دهید نرخ تازه سازی هر ستون را 100 هرتز در نظر بگیریم (دوره T=10ms)، تاخیر زمانی 10/8 = 1.25ms است. ما نسبت پیش مقیاس کننده TMR0 را روی 1:8 تنظیم می کنیم، در حالی که حداکثر تاخیر ممکن 256x8 = 2048 میکرو ثانیه است. برای مکث 1.25 میلی ثانیه، تایمر باید شمارش کند (256x1.25) / 2.048 = 156.25 بار، با گرد کردن 156 شمارش دریافت می کنیم. بر این اساس، لازم است عدد 256-156 = 100 را در تایمر بنویسید.اما این مقدار کاملاً صحیح نیست، زیرا اجرای روال وقفه مدتی طول می کشد، در این مورد حدود 190 میکرو ثانیه طول می کشد. ضریب پیش مقیاس کننده را در نظر بگیرید، 190/8 = 23.75 یا 24 شمارش دریافت می کنیم. مقدار صحیح برای نوشتن روی TMR0 این است: 100+24=124.

در برنامه اصلی، 8 رجیستر ذخیره اطلاعات، مطابق با آنچه که می خواهیم روی ماتریس نمایش دهیم، می نویسیم. در زیر نموداری است که خروجی اطلاعات به ماتریس کد بالا را توضیح می دهد.


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

در زیر لینک می‌توانید سفت‌افزار و کد منبع میکروکنترلر PIC16F628A را با پیاده‌سازی نشان‌دهنده دینامیک روی یک ماتریس 8x8 با استفاده از دو رجیستر شیفت 74HC595 دانلود کنید، نمودار اتصال در بالا مورد بحث قرار گرفت. حروف R، L، عدد 46، شکلک و فقط یک الگو به شکل ضربدر به طور متناوب روی ماتریس نمایش داده می شود، این انیمیشن در ویدیوی زیر نشان داده شده است.

با برچسب , . خواندن .