400 likes | 565 Views
پرتهای ورودی و خروجی. برای هر پورت سه ثبات 8 بیتی در منطقه رجیسترهای I/O وجود دارد که بعنوان مثال برای پورت A این ثبات ها عبارتند از:. 1- یک ثبات برای تعیین جهت پورت به نام DDRX(Port Data Direction Reg.)
E N D
برای هر پورت سه ثبات 8 بیتی در منطقه رجیسترهای I/O وجود دارد که بعنوان مثال برای پورت A این ثبات ها عبارتند از:
1- یک ثبات برای تعیین جهت پورت به نام DDRX(Port Data Direction Reg.) اگر در بیت های این ثبات مقدار 1 نوشته شود بیت پورت مورد نظر خروجی و در صورتی که 0 نوشته شود بیت پورت مذکور ورودی خواهد بود. X مشخص کننده نام پورت بوده و میتواند یکی از حروف D, C, B, A باشد. 2- یک ثبات برای نوشتن داده در پورت خروجی به نام PORTX (Port Data Reg.) 3- یک ثبات برای خواندن اطلاعات از پورت ورودی، به نام PINX(Port Input Pins Reg.) نکته 1: هر بیت از پورت ها درثبات هایDDRXPINX, PORTX, با PORTxn, DDRxn و PINxn نشان داده میشود. که x نام پورت و n شماره بیت پورت میباشد. به عنوان مثال: PORTB0, DDRC2, PORTD5 نکته 2: زمانی که یک پایه پورت بصورت ورودی تعریف شود اگر در بیت نظیر PORTxn مقدار 1نوشته شود در این صورت مقاومت Pull-up در ورودی قرار داده میشود، در غیر اینصورت پایه ورودی در حالت Tri-state قرار خواهد گرفت.
مثال: برنامهای به زبان اسمبلی AVR ATmega32 بنویسید که مرتبا از پورت D بخواند و بر پورت B بنویسد. حل:
; port0.asm ;*********************************************** ;A Section ; ;* Number :atmega32 ;* File Name :port0.asm ;* Title :Setup and Use The ports ;*********************************************** ;B Section ; .include "m32def.inc“ .org 0x000 ;* Reset-Address rjmp Reset ;1-jump reset ;***********************************************
;C Section ; Reset: ;***Initializing PORTB as output*** ser r16 ;2-r16=0FFh out DDRB,r16 ;3-PORTB output ;***Initialize PORTD as input *** clr r16 ;4-PORTD as out DDRD,r16 ;5- input ser r17 ;6-Pull-up out PORTD,r17 ;7-PORTD ;*********************************************** ;D Section ; ;***Read PORTD & write on PORTB(constantly) *** loopforever: in r8,PIND ;8- Read from PORTD out PORTB,r8 ;9- write on PORTB rjmp loopforever ;10- jump loopforever
مثال: برنامهای به زبان اسمبلی AVR ATmega16 بنویسید که مرتبا از بیت های 0و 1 پورت B بخواند و آنها را AND کرده نتیجه را در بیت 2 پورت B بنویسد. حل:
; bit_port_Atmega16.asm ;***************************************************** ;A section ; ;AVR number :atmega16 ;File name :bit_port_Atmega16.asm ;Description :This is a sample of assembly ; :structure only using registers ; : & input output ports ;* recomendation:1-use R26-R31 for pointers ; ;2-R16-up for load immediate ;**************************************************** ;B Section ; .include "m16def.inc" ;This header file is needed ; ;for all avr atmega16 ; ;assembly language ;Interrupt vectors table .org 0x000 ;Reset address rjmp Reset ;(1) Jump to reset ;****************************************************
;C Section ; ;*******Main program entry point on reset Reset: ; ;Initializing the PortB ;PB0,PB1 as Inputs & PB2 as Output LDI R16,0b00000100 ;(2) OUT DDRB,R16 ;(3) ;Pull Up PB0,PB1 LDI R16,0b00000011 ;(4) OUT PORTB,R16 ;(5) ;initialize R18 LDI R18,0X03 ;(6)R18=3 ;*************************************************** ;D Section ; loopforever: CBI PORTB,2 ;(7) Clear bit PB2 ;(turn off led) AGAIN: IN R17,PinB ;(8)Read port B AND R17,R18 ;(9)AND registers CPI R17,3 ;(10) Compare BREQ SET_PB2 ;(11)Branch if Equal RJMP loopforever ;(12)Jump loopforever SET_PB2: SBI PORTB,2 ;(13)Set Bit PB2 RJMP AGAIN ;(14)go again
مثال: برنامهای به زبان اسمبلی AVR ATmega8 و با استفاده از سابروتین بنویسید که پورت D را با یک تاخیر متناوبا 0و1 کند. حل:
; led.asm ;***************************************************** ;A section ;AVR number :atmega8 ;File name :led.asm ;Descrption: :This is a sample assembly ; :program with subroutine ;***************************************************** ;B section .include "m8def.inc" ;Header file for Atmega8 ;Interrupt vector table .org 0x000 ;Reset_address rjmp Reset ;(1) ;***************************************************** ;C section ; begin of main program reset: ;*****************initializing stack pointer********** ldi r16 ,low(RAMEND) ;(2) out SPL,r16 ;(3) ldi r16,high(RAMEND) ;(4) out SPH,r16 ;(5) ;********initializing the ports ;PortD as output ldi r16 , 0xFF ;(6) out DDRD , r16 ;(7)DDRD=0xFF ;*****************loopforever************************
;D section loopforever: ser R16 ;(8)r16=0xFF in R17,PORTD ;(9)read PORTD to R17 eor R17,R16 ;(10)XOR R17 with R16 out PORTD,R17 ;(11)write R17 to PORTD rcall Delay ;(12)call subroutine Delay rjmp loopforever ;(13)jump to loopforever ;************Write subroutine************************* ;E section ;subroutine to make a delay Delay: ldi r24,0 ;(14)r24=0 ldi r25,0 ;(15)r25=0 wait: inc r24 ;(16)increment r24 cpi r24,0xFF ;(17)compare r24 with 0xFF brne wait ;(18)branch not equal to wait inc r25 ;(19)increment r25 cpi r25,0x4F ;(20)compare r25 to 0x0F brne wait ;(21)branch not equal to wait ret ;(22)return from subroutine
نوشتن برنامه های میکروکنترلرهای AVR به زبان c در محیط نرم افزار CodeVisionAVR مزیت زبان C: مناسب برای برنامه های بزرگ و پیچیده معایب زبان C: بر خلاف زبان اسمبلی فضای زیادی از حافظه را اشغال کرده و سرعت پایینی دارد. مثال: برنامهای به زبان C برای AVR ATmega8 بنویسید که از پورت D بخواند و بر پورت B بنویسد. حل:
#include <mega8.h> //(1) void main(void) { // Input/Output Ports initialization // Port B initialization,Port B as output with initial valu // 00H DDRB=0xFF; //(2) PORTB=0x00; //(3) // Port D initialization, Port D as input with pull_up DDRD=0x00; //(4) PORTD=0xFF; //(5) while (1) { //Read port D and write on port B PORTB=PIND; //(6) }; }
مثال: برنامهای به زبان C با میکروکنترلر AVR ATmega8 و در محیط CodeVisionAVR بنویسید که پورت D را با یک تاخیر 1 ثانیه مکمل کند. حل:
#include <mega8.h> //(1) // include function dealay for using delay in //program #include <delay.h> //(2) void main(void) { // Input/Output Ports initialization // Port D initialization, Port D as output with // initial /value 00H DDRD=0xFF; //(3) PORTD=0x00; //(4) // main program loop while (1) { PORTD=~PORTD; //(5)invert Port D delay_ms(1000); //(6)make 1000 //ms delay }; }
مثال : برنامه ای بنویسید که اعداد 0 تا 9999 را بر روی چهار لامپ هفت قسمتی 1 تا 4 نشان دهد.
#include <mega16.h> //(1) Header file #include <delay.h> //(2) long int temp1, temp2, temp3, temp4, temp5, temp6, i; //(3) Define int j; //(4) Parameters flash unsigned char number[10]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //(5) Define codes in flash void main (void) //(6) Main program { DDRA = 0xff; //(8) Define port A & B as output PORTA = 0xff; //(9) DDRB = 0xff; //(10) PORTB = 0xff; //(11) while(1) //(7) Do it again {
for(i=1;i<=9999;i++) //(12)First FOR, count i from 1 to 9999 { // Calculate yekan, dahgan, sadgan, hezargan of i temp1=i/10; //(13) temp2=i-10*temp1; //(14) temp3=temp1/10; //(15) temp4=temp1-10*temp3; //(16) temp5=temp3/10; //(17) temp6=temp3-10*temp5; //(18) // Display yekan, dahgan, sadgan, heazrgan on lamp 1 to 4,60 times for(j=1;j<60;j++) //(19) { PORTB=0xfe; //(20) PORTA=number[temp2]; //(21) delay_ms(1); //(22) PORTB=0xfd; //(23) PORTA=number[temp4]; //(24) delay_ms(1); //(25) PORTB=0xfb; //(26) PORTA=number[temp6]; //(27) delay_ms(1); //(28) PORTB=0xf7; //(29) PORTA=number[temp5]; //(30) delay_ms(1); //(31) } //(32) } //(33) } //(34)Do it again for next number of i } //(35)
اطلاعات را میتوان به صورت 4 بیتی نیز برای LCD ارسال نمود. در این حالت از 4 بیت وزن بالای باس داده استفاده میکنیم.
طریقه استفاده از LCD و اتصال آن به میکروکنترلرهای AVR در محیط نرم افزاری CodeVisionAVR
مثال : برنامه ای به زبان C برای میکروکنترلرهای ATmega32 بنویسد که بر روی LCD پیغام microcontroller course را بنویسد.
#include <mega8.h> //(1) // Alphanumeric LCD Module functions #asm //(2) .equ __lcd_port=0x18 ;PORTB //(3) #endasm //(4) #include <lcd.h> //(5) void main(void) //(6) { // Input/Output Ports initialization // Port B initialization,Port B as ouput DDRB=0xFF; //(7) PORTB=0x00; //(8) // LCD module initialization lcd_init(16); //(9)LCD is 16 characters lcd_clear(); //(10)clear LCD lcd_gotoxy(0,0); //(11)go to column 0 line 0 lcd_putsf("microcontroller"); //(12)write microcontroller lcd_gotoxy(5,1); //(13)go to column 5 line 1 lcd_putsf("course"); //(14)write course while (1) { }; }
مثال: برنامه ای بنویسید که با موتور پله ای 1.8 درجه برای هر پالس مقدار 90 درجه چرخش ایجاد کند.
#include <mega8.h> //(1) #include <delay.h> //(2) unsigned int WORK; //(3) counter char DELAY; //(4) unsigned int MAX; //(5) number of iteration char STEP; //(6) void main(void) //(7) { // Port B initialization PORTB=0x00; //(8) DDRB=0x0F; //(9) //Initial values DELAY=20; //(10) STEP=0xCC; //(11) WORK=0; //(12) MAX=50; //(13) while (WORK<MAX) //(14) { PORTB=STEP; //(15) delay_ms(DELAY); //(16) STEP=STEP>>1; //(17) WORK++; //(18) if (STEP==1) //(19) { PORTB=0x09; //(20) delay_ms(DELAY); //(21) STEP=0xCC; //(22) WORK++; //(23) } //(24) }; //(25) } //(26)