27
This program was produced by the CodeWizardAVR V2.04.1 Evaluation Automatic Program Generator © Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 6/12/2009 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega32 Program type : Application AVR Core Clock frequency: 8.000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 512 ************************************************** ***/ #include <mega32.h> // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Place your code here } // Timer 0 output compare interrupt service routine interrupt [TIM0_COMP] void timer0_comp_isr(void) { // Place your code here }

ngat

Embed Size (px)

Citation preview

Page 1: ngat

This program was produced by theCodeWizardAVR V2.04.1 EvaluationAutomatic Program Generator© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.http://www.hpinfotech.com

Project : Version : Date : 6/12/2009Author : Freeware, for evaluation and non-commercial use onlyCompany : Comments:

Chip type : ATmega32Program type : ApplicationAVR Core Clock frequency: 8.000000 MHzMemory model : SmallExternal RAM size : 0Data Stack size : 512************************************************** ***/

#include <mega32.h>

// Timer 0 overflow interrupt service routineinterrupt [TIM0_OVF] void timer0_ovf_isr(void){// Place your code here

}

// Timer 0 output compare interrupt service routineinterrupt [TIM0_COMP] void timer0_comp_isr(void){// Place your code here

}

// Declare your global variables here

void main(void){// Declare your local variables here

// Input/Output Ports initialization// Port A initialization

Page 2: ngat

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00;DDRA=0x00;

// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T PORTB=0x00;DDRB=0x08;

// Port C initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00;DDRC=0x00;

// Port D initialization// Func7=Out Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=0 State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T PORTD=0x00;DDRD=0xB0;

// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 125.000 kHz// Mode: Phase correct PWM top=FFh// OC0 output: Inverted PWMTCCR0=0x73;TCNT0=0x00;OCR0=0x7f;

// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: 31.250 kHz// Mode: Fast PWM top=03FFh// OC1A output: Inverted// OC1B output: Non-Inv.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: Off// Compare B Match Interrupt: OffTCCR1A=0xE3;TCCR1B=0x0C;

Page 3: ngat

TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x08;OCR1AL=0xe2;OCR1BH=0x0f;OCR1BL=0x0f;

// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: 7.813 kHz// Mode: Fast PWM top=FFh// OC2 output: Non-Inverted PWMASSR=0x00;TCCR2=0x6F;TCNT2=0x00;OCR2=0x00;

// External Interrupt(s) initialization// INT0: Off// INT1: Off// INT2: OffMCUCR=0x00;MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x03;

// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: OffACSR=0x80;SFIOR=0x00;

// Global enable interrupts#asm("sei")

while (1){// Place your code here

Page 4: ngat

};

}

Page 5: ngat

Fast pwm

// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 4000.000 kHz // dùng thạch anh 4MHz, PWM tốc độ cao nhất// Mode: Fast PWM top=FFh // chon chế độ fast PWM 8bit// OC0 output: Inverted PWM // lối ra đảo !TCCR0=0x79;TCNT0=0x00;OCR0=0x00;

DDRB.3=1 // Portb3 là lối ra PWM

//Để tạo ra điện áp lối ra PWM theo ý muốn, bạn đặt giá trị cho OCR0

OCR0=0x7f ; //qua bộ lọc RC tạo ra điện áp Vcc/2 .

//Nếu lối ra đảo, nếu OCR0=0xff -> V tạo ra là 0V, ngược lại OCR0=0x0 V tạo ra là Vcc.Bạn có thể chọn lối ra không đảo( trong Wizard của CV hoặc nếu dùng ASM thì xem lại trong datasheet để set các bit WGM00,WGM01,COM00,COM01)

PWM (pulse width modulation) là biến điệu độ rộng xung. Trong các thiết bị cơ điện tử, thường dùng PWM để điều tốc, mô-men của động cơ DC rất có iệu quả. Mẫu cơ bản là dùng PWM để điều khiển động cơ DC có điện áp 3-12V, dòng tới 500mA, nhưng có thể mở rộng với điện áp cao hơn!

1/. PWM (Pulse Width Modulation) đang đóng vai trò gân như tuyệt đối trong các hệ công suất chuyển mạch SMPS (Switch Mode Power Supply) còn gọi là nguôn xung. Nói một cách khác, nhăc tới nguôn xung thì người ta nghi ngay đến PWM.

Page 6: ngat

2/. PWM tạo dưng trên nguyên tăc chuyển lải năng lượng tư A đến B dưới dạng các xung vuông toàn áp (biên độ xung gân với điện áp nguôn cung cấp) liên tiếp. Trong đó mưc năng lượng ty lệ thuân với thời gian mở xung (độ rộng xung tinh trên đơn vị thới gian.

3/. Tân số xung trong PWM có thể cố định hay biến đôi (thường là cố định tân số xung chuyển mạch). Với tân số cố định, chu ky t băng tông thời gian mở xung t(on) với thời gian tăt xung t(off).

t = t(on) + t(off).

Ty lệ của thời gian mở trên chu ky xung chinh là độ sâu điều biến độ rộng xung, đặc trưng thành thuât ngư "% duty".

Vi du, tân số xung 1 KHz --> t = 1 ms.

với t(on) = 0,5 ms --> ta có độ điều biến 50% duty.

4/. Để tạo ra xung PWM có điều khiển (CPWM / Controled PWM), người ta giao hội giưa một xung hình tam giác với điện áp điều khiển trong một hệ khuếch đại tuyến tinh (Op-Amp).

Read more: http://www.ant7.com/forum/forum_post.asp?TID=7026&PN=3#ixzz1OZpsKTc7

-Phân VDK phải trình bày PWM- Phân mô hình phải có sơ đô khối, trong đó có sử dung PWM của VDK- Giải thich sơ đô khối- Phân lưu đô giải thuât phải vẽ dưới dạng các khối chuẩn của một lưu đô giải thuât

//chuong trinh dung cac ngat ngoai trong AVR#include<mega8.h>#define xtal 4000000//thach anh 4Mhz int dem=0; //trinh phuc vu ngat cua INT0interrupt [EXT_INT0] void ext_int0_isr(void){ dem++;if (dem==1){ PORTB.1=1; PORTC.1=0;

Page 7: ngat

PORTC.0=0; }if (dem==2){ PORTB.1=0; PORTC.1=1; PORTC.0=0; }if (dem==3){ PORTB.1=0; PORTC.1=0; PORTC.0=1; dem=0; } } // Trinh phuc vu ngat cua INT1interrupt [EXT_INT1] void ext_int1_isr(void){if (dem==2){ PORTB.1=0; PORTC.1=1; PORTC.0=0; }if (dem==1){ PORTB.1=1; PORTC.1=0; PORTC.0=0; }if (dem==0){ PORTB.1=0; PORTC.1=0; PORTC.0=1; dem=3; } dem--;}void main(void){DDRB.1=1;DDRC.1=1; DDRC.0=1;PORTB.1=0;PORTC.1=0;PORTC.0=0; #asm("cli")//thiet lap hoat dong cho ngat ngoai 0 (INT0) va ngat ngoai 1 (INT1): GICR=0xC0;//cho phep ngat ngoai 0 va ngat ngoai 1MCUCR=0x0A; //xay ra ngat khi co canh xuong o chan INT0 hoac chan INT1GIFR=0xC0;//cho cac co ngat len 1 de thuc hien cac ngat khoi dau#asm("sei")//cho ngat}

Dieu rong xung pwm voi avr

Page 8: ngat

TCCR0=(0<<WGM01)|(1<<WGM00)|(1<<CS01)|(1<<COM01); //dat CLK preceal to 8, compare modeDDRB=0xFF;OCR0=50;TCNT0=150;

số lân ngăt / giây: T=clock tỉmer /255*n (với n là số chia 8, 32 , 64 .. tùy tưng bộ timer )

tư đây ta tinh được trong 1s có bao nhiêu xung =?

Tinh được tân số :F=1/T

This program was produced by the

CodeWizardAVR V2.04.1 Evaluation

Automatic Program Generator

© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

Project :

Version :

Date : 6/12/2009

Author : Freeware, for evaluation and non-commercial use only

Company :

Comments:

Chip type : ATmega32

Program type : Application

AVR Core Clock frequency: 8.000000 MHz

Memory model : Small

External RAM size : 0

Data Stack size : 512

************************************************** ***/

#include <mega32.h>

Page 9: ngat

// Timer 0 overflow interrupt service routine

interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{

// Place your code here

}

// Timer 0 output compare interrupt service routine

interrupt [TIM0_COMP] void timer0_comp_isr(void)

{

// Place your code here

}

// Declare your global variables here

void main(void)

{

// Declare your local variables here

// Input/Output Ports initialization

// Port A initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTA=0x00;

DDRA=0x00;

// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T

PORTB=0x00;

DDRB=0x08;

// Port C initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

Page 10: ngat

PORTC=0x00;

DDRC=0x00;

// Port D initialization

// Func7=Out Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In

// State7=0 State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0xB0;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 125.000 kHz

// Mode: Phase correct PWM top=FFh

// OC0 output: Inverted PWM

TCCR0=0x73;

TCNT0=0x00;

OCR0=0x7f;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 31.250 kHz

// Mode: Fast PWM top=03FFh

// OC1A output: Inverted

// OC1B output: Non-Inv.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0xE3;

TCCR1B=0x0C;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

Page 11: ngat

OCR1AH=0x08;

OCR1AL=0xe2;

OCR1BH=0x0f;

OCR1BL=0x0f;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: 7.813 kHz

// Mode: Fast PWM top=FFh

// OC2 output: Non-Inverted PWM

ASSR=0x00;

TCCR2=0x6F;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

// INT2: Off

MCUCR=0x00;

MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x03;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;

// Global enable interrupts

#asm("sei")

while (1)

{

Page 12: ngat

// Place your code here

};

}

BÀI 3: LẬP TRÌNH NGẮT TRÊN AVR

ỨNG DỤNG NGẮT NGOÀI, BỘ ĐỊNH THỜI

I. Ngắt trên AVR.

1. Khái niệm.

Interrupts hay ngăt, là một tin hiệu khẩn cấp gởi đến bộ xử li, yêu câu bộ

xử li tạm ngưng tưc khăc các hoạt động hiện tại để “nhảy” đến một nơi khác

thưc hiện một nhiệm vu khẩn cấp nào đó, nhiệm vu này gọi là trình phuc vu

ngăt – ISR (interrupt service routine ). Sau khi kết thúc nhiệm vu trong ISR, bộ

đếm chương trình sẽ được trả về giá trị trước đó để bộ xử li quay về thưc hiện

tiếp các nhiệm vu còn dang dở. Như vây, ngăt có mưc độ ưu tiên xử li cao nhất,

ngăt thường được dùng để xử li các sư kiện bất ngờ nhưng không tốn quá nhiều

thời gian.

Các tin hiệu dẫn đến ngăt có thể xuất phát tư các thiết bị bên trong chip

(ngăt báo bộ đếm timer/counter tràn, ngăt báo quá trình gởi dư liệu băng RS232

kết thúc…) hay do các tác nhân bên ngoài (ngăt báo có 1 button được nhấn,

ngăt báo có 1 gói dư liệu đã được nhân…).

2. Ứng dụng.

Hãy tưởng tượng bạn cân thiết kế một mạch điều khiển hoàn chỉnh thưc

hiện rất nhiều nhiệm vu bao gôm: nhân thông tin tư người dùng qua các nút

nhấn, nhân tin hiệu tư cảm biến, xử li thông tin, xuất tin hiệu điều khiển, hiển

thị thông tin trạng thái…rõ ràng trong các nhiệm vu này việc nhân thông tin

người dùng, hay tin hiệu cảm biến rất hiếm xảy ra so với các nhiệm vu khác

nhưng lại rất “khẩn cấp” cân được ưu tiên hàng đâu.

Nhiệm vu theo dõi các sư kiện “khẩn cấp” có thể thưc hiện băng 1 trong

2 cách:+Viết 1 hàm thăm dò sư kiện (vi du như hàm Button read đã giới thiệu ở

bài 1) và phải gọi hàm này ra liên tuc. Tuy nhiên, nếu chương trình chinh có

quá nhiều nhiệm vu như đã nói ở trên thì cách này không hiệu quả. Lý do đưa

ra là mỗi hàm cân 1 thời gian thưc thi nhất định, nếu đang thưc thi 1 hàm khác

mà xảy ra sư kiện thì hàm thăm dò trở nên vô dung và vi điều khiển băt sót sư

kiện.

Page 13: ngat

+Sử dung ngăt, lúc này vi điều khiển sẽ không tốn thời gian cho hàm

thăm dò nưa. Vi điều khiển sẽ thưc thi nhiệm vu xử lý sư kiện khi mà có ngăt

xảy ra, khi đó mọi công việc khác được gác lại cho đến khi xử lý xong công

việc mà ngăt giao cho(trình phuc vu ngăt).

Một vi du khác cho ưng dung của ngăt là bộ định thời (ngăt tràn

timer/counter), cư sau 1 khoảng thời gian cố định thì xảy ra 1 ngăt, ta ưng dung

vào nhiệm vu quét led chẳng hạn, khi đó hàm quét led sẽ là trình phuc vu ngăt

và nó sẽ được gọi ra theo 1 chu ky xác định với mưc ưu tiên cao nhất. Như vây sẽ không có hiện

tượng led bị chớp do vi điều khiển thưc hiện quá nhiều công

việc(thời gian giưa 2 lân quét bị giãn ra).

Tóm lại, nếu thực hiện các đoạn lệnh thì vi điều khiển thực hiện công

việc 1 cách tuần tự ( từng dòng lệnh được thực thi), nếu sử dụng ngắt thì vi

xử điều khiển thực hiện công việc 1 cách ngẫu nhiên (thực hiện công việc

khi có sự kiện ngẫu nhiên).

Hình 1 minh họa cách tô chưc ngăt thông thường trong các chip

AVR. Số lượng ngăt trên mỗi dòng chip là khác nhau, ưng với mỗi ngăt sẽ có

vector ngăt, vector ngăt là các thanh ghi có địa chỉ cố định được định nghia trc nam trog phan dau

cua bo nho chuong triih

Page 14: ngat

3. Trình phục vụ ngắt – ISR.

Trong MikroC, trình phuc vu ngăt được định nghia như 1 hàm thông

thường nhưng kèm theo khai báo địa chỉ của vector ngăt.

Cú pháp khai báo như sau:

Kiểu_dữ_liệu_trả_vềTên_hàm() org địa_chỉ vector_ngăt {

Khối lệnh;

Page 15: ngat

}

Địa chỉ vector ngăt được liệt kê trong bảng 1(bỏ đi $ vì đây là ký hiệu

địa chỉ tuyệt đối, định dạng theo hệ thâp luc phân trong C).

Vi du:

// Trình phục vụ ngắt khai báo trong phần mềm MikroC

voidInterrupt() org 0x16 { // chọn ngăt có địa chỉ là $016

RS485Master_Receive(data);

}

Ngắt ngoài (External Interrupt).

1. Giới thiệu

Ngăt ngoài là loại ngăt duy nhất độc lâp với các thiết bị của vi điều

khiển, các ngăt khác thường găn với hoạt động của 1 thiết bị nào đó như

Timer/counter, USART, ADC…

Ngăt ngoài là cách rất hiệu quả để thưc hiện giao tiếp giưa người dùng

và vi điều khiển. Đối với Atmega16, ta có 3 ngăt ngoài là INT0, INT1 và INT2

tương ưng với các chân PD2, PD3, PB2.

Khi làm việc với các thiết bị ngoại vi của AVR, hâu như chúng ta chỉ

thao tác trên các thanh ghi chưc năng đặc biệt - SFR (Special Function

Registers) trên vùng nhớ IO, mỗi thiết bị bao gôm một tâp hợp các thanh ghi

điều khiển, trạng thái, ngăt…khác nhau. Với ngăt ngoài, có 3 thanh ghi liên

quan đến ngăt ngoài đó là MCUCR, GICR và GIFR. Cu thể các thanh ghi được

2. Các thanh ghi điều khiển ngắt ngoài.

a. MCUCR (MCU Control Register) và MCUCSR (MCU Control

and Status Register)

Là2 thanh ghi xác lâp chế độ ngăt cho ngăt ngoài, quan sát hình 2 trước

khi tìm hiểu 2 thanh ghi này.

Page 16: ngat

các nút nhấn dùng tạo ra các ngăt. Có 4 khả năng có thể xảy ra khi chúng ta

nhấn và thả các nút nhấn. Nếu không nhấn, trạng thái (logic) các chân INT là

cao do điện trở kéo lên, khi vưa nhấn 1 nút, sẽ có sư chuyển trạng thái tư cao

sang thấp, chúng ta gọi là cạnh xuống - Falling Edge, khi nút được nhấn và giư,

trạng thái các chân INT được xác định là thấp và cuối cùng khi thả các nút,

trạng thái chuyển tư thấp sang cao, gọi là cạnh lên – Rising Edge.Trong nhưng

trường hợp cu thể, 1 trong 4 khả năng trên đều hưu ich, vi du trong các ưng dung đếm xung (đếm

encoder của servo motor chẳng hạn) thì 2 khả năng

“cạnh” phải được dùng.

Thanh ghi MCUCR chưa các bits cho phép chúng ta chọn 1 trong 4 khả

trên để kich hoạt ngăt ngoài INT0 và INT1. Dưới đây là cấu trúc thanh ghi

MCUCR được trich ra tư datasheet của chip Atmega16

Page 17: ngat

Xung cấp cho INT2 phải có độ rộng lớn hơn50ns thì mới xuất hiện ngăt,

nếu nhỏ hơn thì không đảm bảo có ngăt xảy ra. Khi thay đôi bit ISC2, một ngăt

có thể xảy ra, vì vây trước khi thay đôi bit này, để tránh sai sót, ta cân vô hiệu

hóa chưc năng ngăt ngoài INT2 trong thanh ghi GICR sau đó mới thay đôi bit

ISC2, cuối cùng, cờ ngăt INTF2 phải được xóa trong thanh ghi GIFR trước khi

kich hoạt lại ngăt INT2

Page 18: ngat

Chú ý: Các chân ngắt PD2, PD3, PB2 khi sử dụng là các chân ngắt ngoài

thì phải thiết lập các chân này là ngõ vào thông qua thanh ghi DDRx.

Tóm tăt quá trình thiết lâp ngăt ngoài.

+Bước 1: Chọn chế độ ngăt thông qua thanh ghi MCUCR và MCUCSR

Bước 2: Khởi động ngăt ngoài thông qua thanh ghi GICR.

+Bước 3: Cho phép ngăt toàn cuc thông qua bit 7 của thanh ghi SREG.

Thực hành ngắt ngoài

Vi du : Viết chương trình sử dung ngăt điều khiển 1 led 7 đoạn băng

Page 19: ngat

phương pháp chốt. Tác động vào các chân INT băng nút nhấn, tác động băng

cạnh xuống. Khi tác động vào chân INT0 thì giá trị hiển thị tăng 1, tác động

vào chân INT1 thì giá trị hiển thị giảm 1, tác động vào chân INT2 thì giá trị

hiển thị băng 0.

Sơ đô thi nghiệm như sau

Page 20: ngat
Page 21: ngat
Page 22: ngat
Page 23: ngat