AVR Microcontrollers Firsrt Session
منابع : نرم افزارها : CodeVisionAVR Proteus AVR Studio منابع موجود در www.atmel.com مرجع كامل ميكروكنترلرهاي AVR - انتشارات نص - محمد مهدي پرتوي فر و .. ميكروكنترلرهاي AVR و كاربردهاي آنها - انتشارات نص - امير ره افروز نرم افزارها : CodeVisionAVR Proteus AVR Studio
ميان ترم : 5 نمره تمرين : 3 نمره پروژه : 3 نمره پايان ترم : 10 نمره
Introduction ATMEL 8 bit Microcontroller Families Tiny 90S (CLASSIC) Mega LCD AVR Execute One Instruction Per Cycle (MIPS)
جایگزینی تراشه های قدیمی تراشه قدیمی جایگزین مناسب AT90S2313 AT90S2323 AT90S4433 AT90S8515 ATMEGA103 ATMEGA161 ATMEGA163 ATMEGA323 ATTINY2313 ATTINY25 ATMEGA8 ATMEGA8515 ATMEGA128 ATMEGA162 ATMEGA16 ATMEGA32
نام میکروکنترلر از دو یا سه قسمت تشکیل شده است ATMEGA 16 ATMEGA 8 ATTINY 28L ATTINY 28 V قسمت اول نوع و سری میکرو و قسمت دوم حافظه flash را بیان می کند. قسمت سوم مخفف low power و very low power است. که در جدول زیر شرح داده شده است:
فرکانس قابل قبول کریستال محدوده ولتاژ تغذیه نام میکروکنترلر 0-16 MHZ 0-8 MHZ 0-4 MHZ 4-5.5 v 2.7-5.5 v 1.8-5.5 v میکروکنترلر AVR بدون پسوند میکروکنترلر AVR با پسوند L میکروکنترلر AVR با پسوندV
PDIP-Package – Mega32
TQFP/MLF Package – Mega32
Architecture RISC: Reduced Instruction Set Computer ==> AVR CISC: Complex Instruction Set Computer
CPU Structures
Memory Types Data Program SRAM (Static Random Access Memory) EEPROM (Electrically Erasable Programmable Read Only Memo) Program Flash
Program Memory Flash (for mega32) 32K Bytes of In-System Self-Programmable Flash Endurance: 10,000 Write/Erase Cycles
Data Memories SRAM (for mega32) EEPROM (for mega32) 2K Byte Internal SRAM- Register file, I/O Register, Data Address. EEPROM (for mega32) 1024 Bytes EEPROM Endurance: 100,000 Write/Erase Cycles
Program Counter (PC) Instruction Register (IR) Instruction Decoder (ID)
REGISTER FILES
X-Y-Z Registers
ALU Logic Arithmetic And Logic Unit Arithmetic R1R1+R2 R1R1 AND R2 ADD R1,R2 R1R1+R2 Logic AND R1,R2 R1R1 AND R2
فیوز بیت ها قسمتی از حافظه میکرو کنترلر ها هستند که امکاناتی را در اختیار کاربر قرار می دهند و با پاک شدن حافظه میکرو تنظیمات آنها از بین نمی رود
Clock Source
Clock Sources
PDIP-Package – Mega32
External Crystal Oscillator
Low Frequency Crystal Oscillator
External RC Oscillator
Calibrated Internal RC Oscillator
External Clock
Timer/Counter Oscillator For AVR microcontrollers with Timer/Counter Oscillator pins (TOSC1 and TOSC2), the crystal is connected directly between the pins. No external capacitors are needed. The Oscillator is optimized for use with a 32.768 kHz watch crystal. Applying an external clock source to TOSC1 is not recommended.
Clock Distribution
AVR Microcontrollers Second Session
SRAM Management
SRAM Data Memory (mega32)
Programming With CodevisionAVR
Prototype #include <mega32.h> global definition main() { } local variable; statements; } function1() Statements; function2()
Prototype چون میکرو همیشه باید در حال فعالیت باشد، درون تابع main یک حلقه دائم قرار داده می شود. #include <mega32.h> global definition main() { local variable; دستوراتی که باید یک بار اجرا شوند While (1) دستورات و کدهای اصلی برنامه که دائما اجرا می شوند }
نکاتی در مورد برنامه نویسی خط اول همیشه دستور فراخوانی فایل های حاوی توابع header است در انتهای هر عبارت یک سمی کالن قرار داده می شود } و { در ابتدا و انتهای هر حلقه، عبارت شرطی و یا بلوک قرار داده می شود از // یا ( /* و */) برای نوشتن توضیح در برنامه استفاده می شود
Data Type Type Size (Bits) Range bit 1 0 , 1 char 8 -128 to 127 unsigned char 8 0 to 255 signed char 8 -128 to 127 int 16 -32768 to 32767 short int 16 -32768 to 32767 unsigned int 16 0 to 65535 signed int 16 -32768 to 32767 long int 32 -2147483648 to 2147483647 unsigned long int 32 0 to 4294967295 signed long int 32 -2147483648 to 2147483647 float 32 ±1.175e-38 to ±3.402e38 double 32 ±1.175e-38 to ±3.402e38
متغیر ها و ثابت ها ابتدا باید معرفی شوند نام متغیر نوع متغیر حافظه مورد نیاز برای متغیر eeprom int temp; flash int temp=10; eeprom char str; float a; int b=30; نام متغیر ها می تواند ترکیبی از حروف و اعداد باشد، فقط نام متغیر نباید با عدد شروع شود.
Constants flash int x=123; const char y=‘a’; #define C 100;
آرایه ها int str[10]; int i[3]= {2,5,6} رشته(string): تعدادی متغیر دلخواه از یک نوع و یک نام که با اندیس های شماره دار از هم جدا هستند int str[10]; int i[3]= {2,5,6} رشته(string): به آرایه هایی که حروف اسکی را درون خود نگه می دارند، رشته می گوییم. Char t[5]= “temp”;
bit Data type bit x,y; x=1; from R2.0 to R14.7 max=104 Set in following menu: Project/Configure/C Compiler/Code Generation/Bit Variable size
Operators + - * / % ++ -- = == ~ ! != < > <= >= & && | || ^ ? << >> -= += /= %= &= *= ^= |= >>= <<=
Variables [<storage modifier>] <type definition> <identifier>; auto int i; static char x[10]; register int y; The volatile modifier must be used in order to prevent a variable to be allocated to registers and to warn the compiler that it may be subject to outside change during evaluation. volatile int abc;
Specifying the SRAM Storage Address for Global Variables int a @0x80; struct x { int a; char c; } alfa @0x90;
Structures [<storage modifier>] struct [<structure tag-name>] { [<type> <variable-name>[,<variable-name>, ...]]; [<type> [<bitfield-id>]:<width>[,[<bitfield-id>]:<width>, ...]]; ... } [<structure variables>]; struct ram_structure { char a,b; int c; char d[30],e[10]; char *pp; } sr;
Accessing the EEPROM eeprom char beta; int eeprom *ptr_to_eeprom; Pointers to the EEPROM always use 16 bits.
Including Assembly Language in Your Program while (i--) { /* Assembly language code sequence */ #asm nop #endasm }; }
AVR Microcontrollers 3th Session
Decision and loops if –else while do-while for Switch - case
توابع و فرم تابع نویسی (داده های ورودی) نام تابع نوع داده خروجی } (داده های ورودی) نام تابع نوع داده خروجی } تعریف متغیر های محلی دستورات بازگرداندن مقدار خروجی در صورت وجود {
مثال: برنامه ای بنویسید که عدد ورودی را به توان 3 برساند long int func( int x) { long int s; s=x*x*x; return s; }
جایگاه نوشتن توابع توابع را در دو جا می توان نوشت: 1- قبل از تابع main 2- در زیر کل برنامه #include<header> Void func(void) { دستورات Void main()
#include<header> Void func(void); Void main(void) { دستورات While(1) } Void func()
Libraries math.h stdio.h delay.h Mega16.h And …
PORTS
Direction Input= 0 Output=1 DDRA.0=0; // PA.0 input DDRA.5=1; // PA.5 output DDRC=0xff ; // PORTC
Output Latch
Input register
Example-1 برنامه ای بنویسد که بر روی پورت B مقدار 0x28 را بنویسد. #include <mega32.h> void main(void) { DDRB=0xFF; while (1) PORTB=0x28; }; }
سبز : PORTA.0 زرد: PORTA.1 قرمز : PORTA.2 Example-2 تابعي بنويسيد كه يك چراغ راهنمايي را بصورت زير پياده سازي كند: سبز : 15ثانيه زرد: 3ثانيه قرمز: 15ثانيه ------------------------------------------------------------------- نام تابع : trafficsignal ورودي : ندارد خروجي : ندارد سبز : PORTA.0 زرد: PORTA.1 قرمز : PORTA.2
Example-2 Header file : delay.h void delay_us(unsigned int n); void delay_ms(unsigned int n); مثال : تاخير 100 ميكروثانيه ==< delay_us(100) مثال : تاخير 5 ثانيه == < delay_ms(5000)
Example-2 #include <mega32.h> #include <delay.h> void traficsignal(void); void main(void) { DDRA=0x07; while (1) traficsignal(); }; } void traficsignal(void) PORTA.0=1;PORTA.1=0;PORTA.2=0; delay_ms(15000); PORTA.0=0;PORTA.1=1;PORTA.2=0; delay_ms(3000); PORTA.0=0;PORTA.1=0;PORTA.2=1;
Exercise-1 1- تابعي بنويسد كه يك چراغ راهنمايي را با دريافت تاخيرها توسط برنامه زير، راه اندازي كند. سبز : Gdelay ثانيه زرد: Ydelay ثانيه قرمز: Rdelay ثانيه -----------------------------------
Exercise-1 #include <mega32.h> void traficsignal(int gdelay,int ydeay,int rdelay); void main(void) { DDRA=0x07; while (1) traficsignal(x,y,z); }; } void traficsignal(int gdelay, int ydelay, int rdelay) PORTA.0=1;PORTA.1=0;PORTA.2=0; delay_ms(gdelay); PORTA.0=0;PORTA.1=1;PORTA.2=0; delay_ms(ydelay); PORTA.0=0;PORTA.1=0;PORTA.2=1; delay_ms(rdelay);
Example-3 تابعی بنویسید که یک عدد بی علامت را از پورت A خوانده و بر روی پورت B نشان دهد. #include <mega32.h> void in_out_port(void); void main(void) { DDRA=0x00; DDRB=0xff; while (1) in_out_port(); }; } void in_out_port(void) unsigned char x; x=PINA; PORTB=x;
7segment
Common Anode
Common Cathode
Example-4 برنامه ای بنویسید که اعداد 0 تا 9 را بر روي 7segment آند مشترك به فاصله يك ثانيه نشان دهد . #include <mega32.h> #include <delay.h> unsigned char seven_seg_code(unsigned char num); void main(void) { unsigned char i; DDRA=0xff; while (1) for (i=0;i<10;i++) PORTA=seven_seg_code(i); delay_ms(1000); } };
Coding num h g f e d c b a code 1 0xC0 0xF9 2 0xA4 3 0xB0 4 0x99 5 1 0xC0 0xF9 2 0xA4 3 0xB0 4 0x99 5 0x92 6 0x83 7 0xF8 8 0x80 9 0x98
Example-4 unsigned char seven_seg_code(unsigned char num) { unsigned char out; switch(num) case 0:out=0xc0;break; case 1:out=0xf9;break; case 2:out=0xa4;break; case 3:out=0xb0;break; case 4:out=0x99;break; case 5:out=0x92;break; case 6:out=0x83;break; case 7:out=0xf8;break; case 8:out=0x80;break; case 9:out=0x98;break; } return out;
Exercise 2- مثال قبل را براي يك 7seg كاتد مشترك پياده سازي كنيد. 3- مثال قبل را با استفاده از IC مبدل BCD به 7segment ، 7447 پياده سازي كنيد. 4- با استفاده از 7segment كاتد مشترك و IC ، 7448 يك شمارنده 0 تا 9 با فاصله زماني 1 ثانيه بسازيد. 5- برنامه اي بنويسيد كه عددي را از پورت B خوانده و برروي 7seg نمايش دهد. 6- يك شمارنده 0 تا 99 با فاصله زماني 1 ثانيه بسازيد
Double 7Segment
AVR Microcontrollers 4th Session
LCD
شماره پین نشانه نام توصیف 1 VSS Power supply 0V (GND) 2 VDD Power supply for logic circuit and LCD (+4. 5V~+5. 5V) 3 VEE LCD Supply Voltage Bias voltage level for LCD driving 4 RS Register select Register select input When RS= “High”, data register is selected. When RS= “Low”, instruction register is selected. 5 RW Read/Write Read/Write selection input. When RW= “High”, read operation. When RW= “Low”, write operation. 6 E Read Write enable Start enable signal to read or write the data 7 8 9 10 DB0 DB1 DB2 DB3 Data bus 0-7 DB0-DB3, in 8-bit bus mode, used as low order bi-directional data bus. During 4-bit bus mode, open these pins 11 12 13 14 DB4 DB5 DB6 DB7 DB4-DB7, in 8-bit bus mode, used as high order bi-directional data bus. In case of 4-bit bus mode, used as both high and low order. DB7 used for Busy Flag output 15 A back-light anode 16 K back-light cathode
Initialization /* the LCD module is connected to PORTC */ #asm . equ __lcd_port=0x15 #endasm /* now you can include the LCD Functions */ #include <lcd. h> Lcd_init(20);
PORT ADDRESS
LCD Configuration With CodeWizard
lcd.h – High Level unsigned char lcd_init(unsigned char lcd_columns) void lcd_clear(void) void lcd_gotoxy(unsigned char x, unsigned char y) void lcd_putchar(char c) void lcd_puts(char *str) void lcd_putsf(char flash *str)
unsigned char lcd_init(unsigned char lcd_columns) Example: lcd_init(16)
صفحه ال سی دی را پاک می کند void lcd_clear(void) صفحه ال سی دی را پاک می کند void lcd_gotoxy(unsigned char x, unsigned char y) مکان نما را به سطر و ستون دلخواه می برد Lcd_gotoxy(4,2)
void lcd_putchar(char c) Example : lcd_putchar('a'); void lcd_putsf(char flash *str) lcd_putsf(”Hello World");
void lcd_puts(char *str) Example: sprintf(buffer, “tempreture= %d”, temp); lcd_puts(buffer);
Example - 7 در سطر اول ستون پنجم كاراكتر ‘a’ و در سطر دوم ستون اول عبارت “CodeVisionAVR” را بر روي يك LCD 2x16 نمايش دهيد. #include <mega16.h> #asm .equ __lcd_port=0x1B ;PORTA #endasm #include <lcd.h> #include <delay.h> void main(void) { lcd_init(16); while (1) lcd_clear(); lcd_gotoxy(5,0); lcd_putchar('a'); lcd_gotoxy(0,1); lcd_putsf("CodeVisionAVR"); delay_ms(200); }; }
Example-8 تابعي بنويسيد كه بصورت روان كلمه CodeVision را بر روي LCD نمايش دهد. #include <mega16.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x1B ;PORTA #endasm #include <lcd.h> #include <delay.h> void main(void) { int i; lcd_init(16); while (1) for (i=0;i<7;i++) lcd_clear(); lcd_gotoxy(i,0); lcd_putsf("CodeVision"); delay_ms(400); } };
PULL UP
example5 برنامه اي بنويسيد كه پين پنجم پورت A را pull up كرده و ورودي آن را بخواند چنانچه ورودي صفر شد يك led را روشن نمايد. #include <mega32.h> void main(void) { bit x; DDRA.5=0; PORTA.5=1; DDRA.0=1; PORTA.0=0; SFIOR=0x00; while (1) x=PINA.5; if (x==0) PORTA.0=1; else }; }
Keypad
Initialization void initial_keypad_port() { SFIOR=SFIOR&0xFB; }
unsigned char key, butnum; int s; unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb, 0xb7, 0x7e, 0x7d, 0x7b, 0x77}; DDRC = 0x0f; PORTC = 0xf0; delay_us(5); key = PINC; DDRC = 0xf0; PORTC = 0x0f; key = key | PINC;
if (key != 0xff) { for (butnum=0; butnum<16; butnum++) if (keytbl[butnum]==key) break; }
Key Press int key_press() { if ( (PINA & 0xF0)!=0xF0 ) delay_ms(T_DEB); // repeat return 1; // key press else return 0; // parasite } return 0;
Find Key int find_key() { int code, key; // pressed key is in ROW_1 PORTA=0b11111110; delay_ms(50); if ((PINA&0xf0)!=0xf0) goto find; // pressed key is in ROW_2 PORTA=0b11111101; // pressed key is in ROW_3 PORTA=0b11111011; // pressed key is in ROW_4 PORTA=0b11110111;
Find Key // create code find: code = ( PINA & 0xF0 ) | ( PORTA & 0x0F ); // COLUMNS value Link With ROWS value switch(code) { case 0xEE : key = R1_C1; break; case 0xDE : key = R1_C2; break; case 0xBE : key = R1_C3; break; case 0x7E : key = R1_C4; break; case 0xED : key = R2_C1; break; case 0xDD : key = R2_C2; break; case 0xBD : key = R2_C3; break; case 0x7D : key = R2_C4; break; case 0xEB : key = R3_C1; break; case 0xDB : key = R3_C2; break; case 0xBB : key = R3_C3; break; case 0x7B : key = R3_C4; break; case 0xE7 : key = R4_C1; break; case 0xD7 : key = R4_C2; break; case 0xB7 : key = R4_C3; break; case 0x77 : key = R4_C4; break; default : key = NO_PRS; break; }; PORTA=0xF0; return key; }
Key Release void wait_release() { while ((PINA & 0xF0)!=0xF0); delay_ms (T_DEB); // release debounce pass after 20ms }
Read Keypad int read_keypad() { int key; initial_keypad_port(); while ( key_press()== 0); key = find_key(); wait_release(); return key; }
ٍExample-9 برنامه اي بنويسيد كه عددي را از keypad خوانده برروي 7segنمايش دهد.
#include<mega16. h> #include<delay #include<mega16.h> #include<delay.h> int key(); display(int x); int a; main() { DDRB=0xff; a=key(); display(a); }
int key() { unsigned char key, butnum; int s; unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb, 0xb7, 0x7e, 0x7d, 0x7b, 0x77}; DDRC = 0x0f; PORTC = 0xf0; delay_us(5); key = PINC; DDRC = 0xf0; PORTC = 0x0f; key = key | PINC; if (key != 0xff) for (butnum=0; butnum<16; butnum++) if (keytbl[butnum]==key) break; } s=butnum; else s=17; return s;
display(int x) { char str[16]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D, 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; PORTB=str[x]; }
نمایش دهدLCD برنامه بالا را طوری تغییر دهید که عدد را بر روی یک
Programmer STK 200/300