67
Bài Báo Cáo Môn Vi Xử Lý Giáo viên bộ môn: Phạm Thế Duy. Người thực hiện: Đỗ Văn Tiến Đạt. Lớp: D07VTA1. MS: 407160006. Nội Dung : Giải thích 10 bài lập trình vi điều khiển, với những đoạn code lập lại sẽ không được giải thích lại mà chỉ được giải thích một lần.

Bài Báo Cáo Môn Vi Xử Lý

Embed Size (px)

Citation preview

Page 1: Bài Báo Cáo Môn Vi Xử Lý

Bài Báo Cáo Môn Vi Xử Lý

Giáo viên bộ môn: Phạm Thế Duy.

Người thực hiện: Đỗ Văn Tiến Đạt.

Lớp: D07VTA1. MS: 407160006.

Nội Dung : Giải thích 10 bài lập trình vi điều khiển, với những đoạn code lập lại

sẽ không được giải thích lại mà chỉ được giải thích một lần.

Page 2: Bài Báo Cáo Môn Vi Xử Lý

1. Bài 1 : Điều khiển công tắc đơn và led đơn.

#include <mega16.h> // Định nghĩa thư viện

#include <delay.h>

#define sw1 PINA.0 // Định nghĩa tên thứ tự các pin

#define sw2 PINA.1 // của portA theo sw tương ứng

#define sw3 PINA.2

#define sw4 PINA.3

#define sw5 PINA.4

#define sw6 PINA.5

#define sw7 PINA.6

#define sw8 PINA.7

#define led PORTC

char ledtam1; // Khai báo các biến

char ledtam2;

int n,m;

void main(void)

{

Page 3: Bài Báo Cáo Môn Vi Xử Lý

// Input/Output Ports initialization

// Port A initialization

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

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

PORTA=0xFF; // Có điện trở kéo lên nguồn

DDRA=0x00; // Set port A là ngõ vào

// Port C initialization

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

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

PORTC=0x00; // Ngõ ra với mức 0

DDRC=0xFF; // Set port C là ngõ ra

led=0x00; // Khởi tạo giá trị led ban đầu bằng 0

while (1) //lập liên tục

{

while(sw1) // Vòng lặp thực hiện khi sw1 đc nhấn

{

led=0x01; // Cho giá trị led =1

delay_ms(200); // Đợi 200 ms

while(led) // Vòng lặp xảy ra khi led khác 0

{

led=led<<1; // Dịch thanh ghi led 8 bit sang trái 1 bít

Page 4: Bài Báo Cáo Môn Vi Xử Lý

// đèn sáng lần lược về bên trái

delay_ms(200); // Đợi 200 ms

};

led=0x80; // Gán led =1000 0000 (đèn 8 sáng còn lại tắt)

delay_ms(200); // đợi 200 ms

while(led) // Thực hiện khi led khác 0

{

led=led>>1; // Dịch led sang phải 1 (đèn sáng lần

//lược qua bền phải)

delay_ms(200); // Đợi 200 ms

};

};

while(sw2) // Khi sw2 khác 0 vòng lặp được thực hiện

{

led=0x01; // Gán led = 0000 0001 (đèn 1 sáng còn lại tắt)

delay_ms(200); // Đợi 200 ms

while(led)

{

led=(led<<1)|0x01; // Gán led bằng chính nó dịch sang trái

// đi 1 rồi hoặc bit với 0000 0001

// đèn sáng dần về bên trái

delay_ms(200);

if(led==0xff) // Nếu led = 1111 1111(khi đén sáng hết)

break; // Thoát vòng lặp

Page 5: Bài Báo Cáo Môn Vi Xử Lý

};

while(led)

{

led=(led>>1); // Dịch led sang phải 1 bit

// đèn tắt dần về bên phải

delay_ms(200);

if(led==0x00) // Nếu led = 0000 0000

break; // thoát khỏi vòng lặp khi đèn tắt hết

};

};

while(sw3) // Khi sw3 được nhấn vòng lặp sẽ thực hiện liên tục

{

led=0x81; // Gán led = 1000 0001 (đèn 8 và 1 sáng còn lại tắt)

delay_ms(200);

ledtam1=ledtam2=led; //ledtam1 và ledtam2 giữ giá trị của led

while(led)

{

ledtam1=(ledtam1>>1)|0x80; //ledtam1 đươc gán bằng chính

//nó dịch sang phải 1 bit rồi hoặc

//bit với 1000 0000

ledtam2=(ledtam2<<1)|0x01; // tương tự như ledtam1 nhưng

//dịch trái 1 bit và hoặc với

Page 6: Bài Báo Cáo Môn Vi Xử Lý

//0000 0001

led=ledtam1|ledtam2; // ledtam1 và ledtam2 hoặc bít

//với nhau rồi gán giá trị cho led

// đèn sẽ sáng từ 2 bên vào

delay_ms(200);

if(ledtam1==0xf0&&ledtam2==0x0f) // nếu ledtam1 = 1111 0000

break; // và ledtam2 = 0000 1111 thì thoát vòng lặp

}; //khi đèn sáng hết thì dừng

while(led)

{

ledtam1=(ledtam1>>1)&0xf0; // ledtam1 dịch phải 1 bit rồi

// và bit 1111 0000

ledtam2=(ledtam2<<1)&0x0f; // ledtam2 dịch trái 1 bit rồi

// và bit với 0000 1111

led=ledtam1|ledtam2; // hoặc bít giữa ledtam1 và //ledtam2 rồi gán cho led

// đèn tắt dần từ trong ra ngoài

delay_ms(200);

};

};

while(sw4)

{

m=8;n=8; // khởi tạo m và n bằng 8

ledtam2=0x00; // ledtam2 = 0000 0000

Page 7: Bài Báo Cáo Môn Vi Xử Lý

while(m) // lặp khi m khác 0

{

led=0x01; // gán led = 0000 0001

delay_ms(200);

ledtam1=0x01; // gán ledtam1 = 0000 0001

while(n) // lặp khi n khác 0

{

ledtam1=ledtam1<<1; // dịch ledtam1 sang trái 1 bit

// đèn sáng lần lược qua phải

led=ledtam1|ledtam2; // hoặc bít ledtam1 và 2 rồi

// gán cho led

// sáng dần qua phải và dừng

// lại ở bên phải

n--; // giảm n đi 1 lần

delay_ms(200);

};

ledtam2=(ledtam2>>1)|0x80; // dịch ledtam2 qua phải 1 bit

// rồi hoặc bít với 1000 0000

led=ledtam2;

delay_ms(500);

m--; // giảm m đi 1

n=m-1;

};

};

Page 8: Bài Báo Cáo Môn Vi Xử Lý

while(sw5)

{

led=0xff; // led = 1111 1111 đèn sáng hết

delay_ms(200);

led=0x00; // đèn tắt hết

delay_ms(200);

};

while(sw6)

{

led=0x55; //đèn 1 3 5 7 sáng còn lại tắt

delay_ms(200);

led=0xaa; // đèn 2 4 6 8 sáng còn lại tắt

delay_ms(200);

};

while(sw7)

{

led=0xf0; // đèn 1 2 3 4 sáng còn lại tắt

delay_ms(200);

led=0x0f; // đèn 5 6 7 8 sáng còn lại tắt

delay_ms(200);

};

while(sw8)

{

led=0x81; // led = 1000 0001 (đèn 1 và 8 sáng)

delay_ms(200);

Page 9: Bài Báo Cáo Môn Vi Xử Lý

ledtam1=ledtam2=led;

while(led)

{

ledtam1=(ledtam1>>1);

ledtam2=(ledtam2<<1);

led=ledtam1|ledtam2; //đèn sáng từ 2 bên chạy vào

delay_ms(200);

if(ledtam1==0x10&&ledtam2==0x01) // đèn sáng chạy vào giữa

break; // thì thoát khỏi vòng lặp

};

while(led)

{

ledtam1=(ledtam1>>1)&0xf0; // ledtam1 dich phải 1 bit rồi và

// bit với 1111 0000

ledtam2=(ledtam2<<1)&0x0f; // ledtam2 dịch trai 1 bit

// rồi và bít với 0000 1111

led=ledtam1|ledtam2; //đèn sáng chạy từ trong ra ngoài

delay_ms(200);

};

};

};

}

Page 10: Bài Báo Cáo Môn Vi Xử Lý

2. Bài 2: Điều khiển hiển thị trên LED 7 đoạn.

#include <mega16.h> // Khai báo thư viện

#include <delay.h>

#define nut1 PINC.4 // Định nghĩa lại tên các chân của port C và port D

#define nut2 PINC.5

#define nut3 PINC.6

#define nut4 PINC.7

#define led1 PORTC.3

#define led2 PORTC.2

#define led3 PORTC.1

#define led4 PORTC.0

#define xuatled PORTD

int bien=0,n=0,a=0,b=0,c=0,d=0; // Khai báo cái biến

void main(void)

{

Page 11: Bài Báo Cáo Môn Vi Xử Lý

// Port C initialization

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

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

PORTC=0xF0; // 4 chân bít cao port C có điện trở kéo lên vào 4 chân bít thâp có giá trị 0

DDRC=0x0F; // set port C ở trạng thái 4 chân bít cao là ngõ vào và 4 chân bít thấp là ngõ ra

// Port D initialization

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

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

PORTD=0xF0; // tương tự như set port C

DDRD=0x0F;

led1=0;

led2=0;

led3=0;

led4=0;

while (1)

{

xuatled=0x00;

if(a==0&&nut1) // nếu a=0 và nut1 =1 thì bien tăng lên 1

{ // và a=1

bien=bien+1;

a=1;

Page 12: Bài Báo Cáo Môn Vi Xử Lý

};

if(!nut1) // nếu nut1=0 thì a=0

a=0;

// nghĩa của các câu lệnh trên là khi nhấn và giữ nguyên nút nhấn thì giá trị bien sẽ chỉ tăng lên 1 lần, tương tự với các câu lệnh dưới đây.

if(b==0&&nut2)

{

bien=bien+10;

b=1;

};

if(!nut2)

b=0;

if(c==0&&nut3)

{

bien=bien+100;

c=1;

};

if(!nut3)

c=0;

if(d==0&&nut4)

{

bien=bien+1000;

d=1;

Page 13: Bài Báo Cáo Môn Vi Xử Lý

};

if(!nut4)

d=0;

if(bien>9999) // nếu bien lớn hơn thì bien = 0

bien=0;

n++; // n tăng lên 1

switch(n)

{

case 1: led1=led2=led3=led4=0; // để đảm bảo số hiện ra led này không

// bị lem sang con led khác

xuatled=bien%10; // xuatled bằng lấy dư 10 của led

// tức là xuatled bằng giá trị hàng đơn vị

led1=1; // led1 sáng

break; // thoát vòng lặp

case 2: led1=led2=led3=led4=0;

xuatled=(bien/10)%10; // xuatled bằng giá trị hàng chục

led2=1; // led 2 sáng

break;

case 3: led1=led2=led3=led4=0;

xuatled=(bien/100)%10; // xuatled bằng giá trị hàng trăm

led3=1; // led 3 sáng

break;

case 4: led1=led2=led3=led4=0;

xuatled=bien/1000; // xuatled bằng giá trị hàng nghìn

Page 14: Bài Báo Cáo Môn Vi Xử Lý

led4=1;n=0; // led 4 sáng

break;

};

delay_ms(50);

}; // nội dung của đoạn code trong switch là quét led và xuất giá trị từng led

}

3. Bài 3 : Điều khiển bàn phím ma trận hiển thị lên LED 07 đoạn.

#include <mega16.h> // Khai báo thư viện

#include <delay.h>

#include <math.h>

#define a1 PORTA.0 // định nghĩa tên cho các chân của port A và C

#define a2 PORTA.1

#define a3 PORTA.2

#define a4 PORTA.3

#define xuatled PORTC

unsigned int i,n=0; // khái báo các biến và màng

unsigned char x,a[]={0x00,0x04,0x08,0x0c,0x01,0x05,0x09,0x0d,0x02,0x06,0x0a,0x0e,0x03,0x07,0x0b,0x0f};

void main(void)

{

// Input/Output Ports initialization

// Port A initialization

Page 15: Bài Báo Cáo Môn Vi Xử Lý

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

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

PORTA=0xF0; // set 4 chân bít cao có điện trở kéo lên, 4 chân bít thấp ngõ ra bằng 0

DDRA=0x0F; // set 4 chân bít cao là ngõ vào, 4 chân bít thấp là ngõ ra

// Port C initialization

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

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

PORTC=0x00; // set các chân ngõ ra bằng 0

DDRC=0xFF; // set các chân port C là ngõ ra

xuatled=0x00; // xuatled bằng 0 (vì trong mạch có dùng con giải mã 7447 nên

// xuatled bằng số nào thì led sẽ hiện số đó)

while (1)

{

switch(n)

{

case 0: a1=0;

a2=a3=a4=1;

break;

case 1: a2=0;

a1=a3=a4=1;

break;

case 2: a3=0;

Page 16: Bài Báo Cáo Môn Vi Xử Lý

a1=a2=a4=1;

break;

case 3: a4=0;

a1=a2=a3=1;

}; // quét phím (xem bên mạch nguyên lý)

x=(PINA>>4)|0xf0; // lấy 4 bit cao của port A gán cho x

x=~x; // lấy đảo của x gán cho x

// vì trong mạch nguyên lý nút nhấn được nhấn sẽ là 0

if(x!=0)

{

i=log(x)/log(2); // lấy giá trị mũ gán cho i tức là i sẽ tương ứng với

// hàng thứ mấy trong cột

xuatled=a[4*n+i]; // xuatled được gán giá trị nội dung của mảng chỉ đến

};

n++;

if(n==4)

n=0;

};

}

Page 17: Bài Báo Cáo Môn Vi Xử Lý

4. Bài 4: Điều khiển hiển thị chữ chạy trên LCD.

#include <mega16.h>

#include <delay.h>

int n; // khai bão biến, mảng và chuỗi

int i;

int j;

unsigned char *ten = "DoVanTienDat";

unsigned char *lop = "d07vta1";

unsigned char a[13]; // 13 là độ dài chuỗi “DoVanTienDat” công thêm 1 ký tự kết thúc chuỗi

unsigned char b[8]; // 8 là độ dài chuỗi “d07vta1” và 1 ký tự kết thúc chuỗi

// Alphanumeric LCD Module functions

#asm // Khai báo sử dụng hỗ trợ lcd từ codevisions

.equ __lcd_port=0x15 ;PORTC // khái báo port nối với lcd là port C

#endasm

#include <lcd.h>

void main(void)

Page 18: Bài Báo Cáo Môn Vi Xử Lý

// LCD module initialization

lcd_init(16); // khai báo lcd sử dụng là lcd 16 cột

lcd_clear(); // xóa màn hình lcd

n=15;

while (1)

{

for(i=0;i<16;i++) //vòng lặp for 16 lần (dịch chuỗi 16 lần)

{

if(i<7){

*(b+i)=*(lop+i); // lưu nội dung ký tự thứ i của chuỗi lớp vào phần tử

// thứ i của mảng b

*(b+i+1)='\0'; // đưa ký tự kết thúc chuỗi vào phần tử tiếp theo của

// mảng b

}

if(i<12){

*(a+i)=*(ten+i); // lưu nội dung ký tự thứ i của chuỗi lớp vào phần tử

// thứ i của mảng a

*(a+i+1)='\0'; // đưa ký tự kết thúc chuỗi vào phần tử tiếp theo của

// mảng a

}

if(n==-1) n=15; // nếu n = -1 thì gán lại n =15

// dòng lệnh này có tác dụng không cho nội dung của

Page 19: Bài Báo Cáo Môn Vi Xử Lý

// hàng trên của lcd tràn xuống hàng dưới

lcd_clear(); // xóa màn hình

lcd_gotoxy(n,0); // đến vị trí xuất ra màn hình lcd cột n hàng thứ nhất

lcd_puts(a); // đưa chuỗi a ra lcd

lcd_gotoxy(n,1); // đến vị trí xuất ra màn hình lcd cột n hàng thứ hai

lcd_puts(b); // đưa chuỗi b ra lcd

n--; // giảm n đi 1

delay_ms(50);

};

};

}

5. Bài 5: Đoc ADC hiển thị lên LCD.

#include <mega16.h>

#include <stdio.h>

#include <delay.h>

#define _ALTERNATE_PUTCHAR_ // định nghĩa lại lệnh putchar

int n=0;

Page 20: Bài Báo Cáo Môn Vi Xử Lý

float i;

// Alphanumeric LCD Module functions

#asm // khai báo sử dụng hỗ trợ xuất lcd của codevisions

.equ __lcd_port=0x15 ;PORTC // khai báo sử dung port C làm port xuất lcd

#endasm

#include <lcd.h>

#define ADC_VREF_TYPE 0x20

// Read the 8 most significant bits

// of the AD conversion result

unsigned char read_adc(unsigned char adc_input) // hàm đoc chân vào adc

{ // và trả giá trị vào ADCH

ADMUX=adc_input|ADC_VREF_TYPE;

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

return ADCH;

}

void putchar(char c) // viết lại hàm putchar

{

Page 21: Bài Báo Cáo Môn Vi Xử Lý

lcd_putchar(c);

}

void main(void)

{

// 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; // port A không có điện trở kéo lên

DDRA=0x00; // khai báo port A là cổng vào

// ADC initialization

// ADC Clock frequency: 115.200 kHz

// ADC Voltage Reference: AREF pin

// ADC Auto Trigger Source: None

// Only the 8 most significant bits of

// the AD conversion result are used

ADMUX=ADC_VREF_TYPE;

ADCSRA=0x86;

// LCD module initialization

lcd_init(16);

Page 22: Bài Báo Cáo Môn Vi Xử Lý

while (1)

{

while(n<=7) // lập 8 lần để đoc lần lược cái chân vào của adc

{

read_adc(n); // đoc chân adc thứ n

if(ADCH<255) // nếu giá trị đoc được nhỏ hơn mức thứ 256

{

i=ADCH*(float)(5)/255*(n+1); // tính giá trị điện áp tương ứng

// rồi ép kiểu foat và gán cho i

} else

{

n++;

if(n==8) // nếu n=8 nghĩa là khi điện áp cần đo vượt mức

{ // adc có thể đo

i=ADCH*(float)(5)/255*(n); // những câu lệnh trong này

n=0; // xuất gia trị điện áp cao nhất mà

lcd_gotoxy(0,0); // adc có thể đoc được

printf("%f",i); // các bạn có thể thay thế bằng

lcd_gotoxy(15,0); // câu lệnh xuất ra chuỗi “ đien

printf("V"); // ap vuot muc quy dinh”

delay_ms(50); // n=0;

lcd_clear(); // lcd_gotoxy(0,0);

break; // printf("đien ap vuot muc quy dinh”);

}; // break;

Page 23: Bài Báo Cáo Môn Vi Xử Lý

continue; // bỏ qua nhưng câu lệnh bên dưới và thực hiện

}; // típ vong lập while(n<=7)

lcd_gotoxy(0,0); // chuyển đến vị trí đầu tiên trên lcd

printf("%f",i); // xuất chuỗi i ra lcd

lcd_gotoxy(15,0); // chuyển đến vị trí cột thứ 15 hàng thứ nhất

printf("V"); // xuất ký tự V ra lcd

delay_ms(50);

lcd_clear();

};

};

}

6. Bài 6: Đo và hiển thị nhiệt độ hiển thị trên LED 7 đoạn.

#include <mega16.h> // Khai báo các thư viện nhập xuất, trễ và tính toán

#include <delay.h>

#include <math.h>

#include <stdio.h>

// Alphanumeric LCD Module functions

Page 24: Bài Báo Cáo Môn Vi Xử Lý

#asm

.equ __lcd_port=0x15 ;PORTC

#endasm

#include <lcd.h>

#define _ALTERNATE_PUTCHAR_ // định nghĩa lại hàm putchar

void putchar(char c) // viết lại hàm putchar

{

lcd_putchar(c);

}

unsigned int i=0,x,R=10000;

float time,t,v,C=0.001;

// Timer 0 output compare interrupt service routine

interrupt [TIM0_COMP] void timer0_comp_isr(void) // hàm ngắt timer

{

i++; // khi xảy ra ngắt tăng i lên 1

}

Page 25: Bài Báo Cáo Môn Vi Xử Lý

// Analog Comparator interrupt service routine

interrupt [ANA_COMP] void ana_comp_isr(void) // hàm ngắt analog compare

{

time=i; // gán i cho time

}

void main(void)

{

// Input/Output Ports initialization

// Port A initialization

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

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

PORTA=0x00; // ngõ ra bằng 0

DDRA=0x01; // khai báo cổng ra là chân số 0,

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 172.800 kHz

// Mode: CTC top=OCR0 //chế độ hoạt động CTC

// OC0 output: Disconnected

TCCR0=0x0B;

TCNT0=0x00;

Page 26: Bài Báo Cáo Môn Vi Xử Lý

OCR0=0x1A; //156.25us ngắt 1 lần

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

TIMSK=0x00; // không cho phép ngắt timer hoạt động

// Analog Comparator initialization

// Analog Comparator: On

// Interrupt on Rising Output Edge

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

ACSR=0x0F;

SFIOR=0x00;

// LCD module initialization

lcd_init(16);

// Global enable interrupts

#asm("sei") // cho phép xử dụng ngắt

PORTA.0=1; // xả tụ ( xem bên mạch nguyên lý )

delay_ms(50);

while (1)

{

PORTA.0=0; // nạp tụ

i=0;

Page 27: Bài Báo Cáo Môn Vi Xử Lý

TIMSK=0x02; // cho phép ngắt timer0 hoạt động

TCNT0=0x00; // cho timer counter bằng 0

x=1;

while(x) //đợi cho đến khi tụ được nạp xong

{

if(time!=0) // kiểm tra xem time có khác 0 hay không

x=0;

};

TIMSK=0x00; // không cho ngắt hoạt động

v=12*(1-exp((-time)/64000)); // tính điện áp theo công thức v=v0.(1- e^(-t/RC))

t=v*100-273; // công thức tính nhiệt độ(xem datasheet LM335)

lcd_clear();

lcd_gotoxy(0,0);

printf("%f",t);

time=0;

PORTA.0=1;

delay_ms(100);

};

}

7. Bài 7: Tạo xung bằng DAC.

#include <mega16.h>

#include<math.h>

#include<delay.h>

Page 28: Bài Báo Cáo Môn Vi Xử Lý

#define pi 3.141592654

int i,j,count;

unsigned char table[128];

unsigned char source[17];

#define ADC_VREF_TYPE 0x20

// Read the 8 most significant bits

// of the AD conversion result

unsigned char read_adc(unsigned char adc_input)

{

ADMUX=adc_input|ADC_VREF_TYPE;

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

return ADCH;

}

void main(void)

{

for(i=0;i<128;i++)

Page 29: Bài Báo Cáo Môn Vi Xử Lý

table[i]=(int)((sin(2*pi*i/128)+1)*63)*2; // tạo hàm sóng sin lưu giá trị vào mảng table

// Port C initialization

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

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

PORTC=0x00; // trạng thái ngõ ra ở mức 0

DDRC=0xFF; // Khởi tạo port C là ngõ ra

// Port D initialization

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

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

PORTD=0x00; // trạng thái ngõ ra ở mức 0

DDRD=0xFF; // Khởi tạo port D là ngõ ra

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 8000,000 kHz // xung cấp cho time 8Mhz

// Mode: Normal top=FFh // chế độ hoạt động Normal top=FFh

// OC0 output: Disconnected

TCCR0=0x01;

TCNT0=0x00;

OCR0=0x00;

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

Page 30: Bài Báo Cáo Môn Vi Xử Lý

TIMSK=0x00;

// Analog Comparator initialization

// Analog Comparator: Off

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

ACSR=0x80;

SFIOR=0x00;

// ADC initialization

// ADC Clock frequency: 125,000 kHz

// ADC Voltage Reference: AREF pin

// ADC Auto Trigger Source: None

// Only the 8 most significant bits of

// the AD conversion result are used

ADMUX=ADC_VREF_TYPE;

ADCSRA=0x86;

while (1)

{

switch(PINB) //đoc giá trị của ngõ vào B (xem bên mạch nguyên lý)

{

case 1: // nếu PINB =1 thì dong lệnh trong case 1 được

{ // thực hiện

PORTD=1; // Đóng relays (xem bên mạch nguyên lý)

count=0;

Page 31: Bài Báo Cáo Môn Vi Xử Lý

while(count<64&&PINB==1) // khi B có tín hiệu và count < 64

{ // (nữa chu kỳ đầu)

PORTC=0; // áp bằng 0

read_adc(0); // đoc chân adc 0

delay_ms(ADCH); // độ trễ phụ thuộc vào tần số (xem mạch nguyên lý)

count++; // đếm count từ 1->64

}

while(count<128&&PINB==1) // khi B có tín hiệu và count < 128

{ // (nữa chu kỳ sau)

PORTC=0xff; //áp bằng biên độ đỉnh

read_adc(0);

delay_ms(ADCH);

count++;

}

break;

}

case 2: // nếu PINB =2 thì dong lệnh trong case 1 được

{ // thực hiện

PORTD=0; // mở relays

count=0;

while(count<64&&PINB==2) // nữa chu kỳ đầu

{

PORTC=count*4; // biên độ áp tăng theo cấp số cộng 4

read_adc(0);

delay_ms(ADCH);

Page 32: Bài Báo Cáo Môn Vi Xử Lý

count++;

}

while(count<128&&PINB==2) // nữa chu kỳ sau

{

PORTC=(127-count)*4; // biên độ áp giảm theo cấp số cộng 4

read_adc(0);

delay_ms(ADCH);

count++;

}

break;

}

case 4: // nếu PINB =4 thì dong lệnh trong case 1 được

{ // thực hiện

PORTD=0;

count=0;

while(count<128&&PINB==4) // xét cả chu kỳ

{

PORTC=table[count]; // giá trị áp ngõ ra thay đổi theo sóng sin

read_adc(0);

delay_ms(ADCH);

count++;

}

break;

}

Page 33: Bài Báo Cáo Môn Vi Xử Lý

}

};

}

8. Bài 8: Giao tiếp nối tiếp hai KIT vi điều khiển.

#include <mega16.h>

#include <delay.h>

#include <math.h>

#define a1 PORTA.0

#define a2 PORTA.1

#define a3 PORTA.2

#define a4 PORTA.3

#define COM 0 //định nghĩa COM = 0

#define LCD 1 //định nghĩa LCD = 1

char x,data,xuat=0;

unsigned char a[]={0x61,0x65,0x69,0x73,0x62,0x66,0x70,0x74,0x63,0x67,0x71,0x75,0x64,0x68,0x72,0x76};

int i,n=0,key;

// Alphanumeric LCD Module functions

#asm //***********Khai báo LCD

Page 34: Bài Báo Cáo Môn Vi Xử Lý

.equ __lcd_port=0x15 ;PORTC

#endasm // sử dụng port C **********

#include <lcd.h>

#define RXB8 1

#define TXB8 0

#define UPE 2

#define OVR 3

#define FE 4

#define UDRE 5

#define RXC 7

#define FRAMING_ERROR (1<<FE)

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<OVR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer

#define RX_BUFFER_SIZE 8

char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256

unsigned char rx_wr_index,rx_rd_index,rx_counter;

#else

Page 35: Bài Báo Cáo Môn Vi Xử Lý

unsigned int rx_wr_index,rx_rd_index,rx_counter;

#endif

// This flag is set on USART Receiver buffer overflow

bit rx_buffer_overflow;

// USART Receiver interrupt service routine

interrupt [USART_RXC] void usart_rx_isr(void)

{

char status,data;

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

{

rx_buffer[rx_wr_index]=data;

if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;

if (++rx_counter == RX_BUFFER_SIZE)

{

rx_counter=0;

rx_buffer_overflow=1;

};

};

}

#ifndef _DEBUG_TERMINAL_IO_

Page 36: Bài Báo Cáo Môn Vi Xử Lý

// Get a character from the USART Receiver buffer

#define _ALTERNATE_GETCHAR_

#pragma used+

char getchar(void)

{

char data;

while (rx_counter==0);

data=rx_buffer[rx_rd_index];

if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;

#asm("cli")

--rx_counter;

#asm("sei")

return data;

}

#pragma used-

#endif

// USART Transmitter buffer

#define TX_BUFFER_SIZE 8

char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256

unsigned char tx_wr_index,tx_rd_index,tx_counter;

#else

unsigned int tx_wr_index,tx_rd_index,tx_counter;

Page 37: Bài Báo Cáo Môn Vi Xử Lý

#endif

// USART Transmitter interrupt service routine

interrupt [USART_TXC] void usart_tx_isr(void)

{

if (tx_counter)

{

--tx_counter;

UDR=tx_buffer[tx_rd_index];

if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;

};

}

#ifndef _DEBUG_TERMINAL_IO_

// Write a character to the USART Transmitter buffer

#define _ALTERNATE_PUTCHAR_

#pragma used+

void putchar_com(char c)

{

while (tx_counter == TX_BUFFER_SIZE);

#asm("cli")

if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))

{

tx_buffer[tx_wr_index]=c;

if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;

Page 38: Bài Báo Cáo Môn Vi Xử Lý

++tx_counter;

}

else

UDR=c;

#asm("sei")

}

#pragma used-

#endif

// Các câu lệnh trên xuất hiện khi set chế độ ngắt ở đầu thu và đầu phát của USART

void putchar(char c)

{

switch(key)

{

case COM: putchar_com(c); //xuất ra cổng COM

break;

case LCD: lcd_putchar(c); //xuất ra LCD

break;

}

}

// Standard Input/Output functions

#include <stdio.h>

Page 39: Bài Báo Cáo Môn Vi Xử Lý

// Timer 0 output compare interrupt service routine

interrupt [TIM0_COMP] void timer0_comp_isr(void)

{

switch(n) //************************

{

case 0: a1=0;

a2=a3=a4=1;

break;

case 1: a2=0;

a1=a3=a4=1; // quét phím nhấn

break;

case 2: a3=0;

a1=a2=a4=1;

break;

case 3: a4=0;

a1=a2=a3=1;

}; // *************************

x=(PINA>>4)|0xf0; // lấy 4 bit cao của port A rồi gán cho x

x=~x; // đảo x (trong mạch nguyên lý khi nhấn =0)

if(x!=0) // nếu phím được nhấn

{

i=log(x)/log(2); // xác định vị trí phím nhấn

xuat=a[4*n+i];

Page 40: Bài Báo Cáo Môn Vi Xử Lý

};

n++;

if(n==4)

n=0;

}

void main(void)

{

// Input/Output Ports initialization

// Port A initialization

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

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

PORTA=0xF0;

DDRA=0x0F;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 10.800 kHz // xung cấp cho timer0 là 10,8khz

// Mode: CTC top=OCR0 // chế độ hoạt động CTC

// OC0 output: Disconnected

Page 41: Bài Báo Cáo Môn Vi Xử Lý

TCCR0=0x0D;

TCNT0=0x00;

OCR0=0x10; // 1,574 ms

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

TIMSK=0x02; //cho phép ngắt timer0 hoạt động

// USART initialization //********

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud rate: 9600 // set chế độ hoạt động UART

UCSRA=0x00;

UCSRB=0xD8;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x47; // ******

// LCD module initialization

lcd_init(16); // khai báo LCD loại 16 cột

// Global enable interrupts

#asm("sei") // cho phép ngắt timer hoạt động

Page 42: Bài Báo Cáo Môn Vi Xử Lý

while (1)

{

if(xuat==0) // nếu ko có phím nào nhấn

{

xuat=' '; // truyền ký tự “ ”

};

key=COM; // chon cổng truyền

putchar(xuat); // truyền dữ liệu

data=getchar(); // nhận dữ liệu lưu vào biến data

lcd_gotoxy(15,0);

key=LCD; // chon cổng truyền LCD

lcd_putchar(data); // xuất ra lcd

delay_ms(50);

lcd_clear();

};

}

9. Bài 9: Thực hiện đồ hồ điện tử trên KIT vi điều khiển.

#include <mega16.h>

Page 43: Bài Báo Cáo Môn Vi Xử Lý

#include <stdio.h>

#include <delay.h>

// Alphanumeric LCD Module functions

#asm

.equ __lcd_port=0x15 ;PORTC

#endasm

#include <lcd.h>

int i=0,a=0,b=1,gio=0,phut=0,giay=0,x=0,y=0,z=0;

// Timer 0 output compare interrupt service routine

interrupt [TIM0_COMP] void timer0_comp_isr(void)

{

i++; // mỗi lần ngắt i tăng lên 1

}

#define _ALTERNATE_PUTCHAR_ //*********************************************

void putchar(char c)

{ //Định nghĩa và khái báo lại hàm putchar

lcd_putchar(c);

} //*********************************************

void xuat(int vitri,int noidung) //Hàm hiển thị đồng hồ trên lcd với 2 đối số

Page 44: Bài Báo Cáo Môn Vi Xử Lý

{

if(noidung<10)

{

lcd_gotoxy(vitri,0);

printf("%d",noidung);

lcd_gotoxy(vitri-1,0);

printf("0");

}

else

{

lcd_gotoxy(vitri-1,0);

printf("%d",noidung);

}

lcd_gotoxy(13,0);

printf(":");

lcd_gotoxy(10,0);

printf(":");

}

void main(void)

{

// Timer/Counter 0 initialization

Page 45: Bài Báo Cáo Môn Vi Xử Lý

// Clock source: System Clock

// Clock value: 7.200 kHz

// Mode: CTC top=OCR0

// OC0 output: Disconnected

TCCR0=0x0D;

TCNT0=0x00;

OCR0=0x47; //10ms

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

TIMSK=0x02;

// Analog Comparator initialization

// Analog Comparator: Off

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

ACSR=0x80;

SFIOR=0x00;

// LCD module initialization

lcd_init(16);

// Global enable interrupts

#asm("sei")

while (1)

{

Page 46: Bài Báo Cáo Môn Vi Xử Lý

if(PINA.0&&x==0) // xét nút nhấn chỉnh đồng hồ có nhấn hay không

{

a=1;x=1;

TIMSK=0x00; //không cho ngắt hoạt động

TCNT0=0x00; // thanh ghi counter =0

};

if(PINA.0==0) // đảm bảo nếu nhấn giữ nguyên nút chỉnh đồng hồ

x=0; //thì giá trị sẽ không thay đổi

if(a)

{

while(a)

{

if(b)

{

if(PINA.1&&y==0) // xét nút chon chế độ chỉnh

{

b++;y=1;

if(b==4)

b=1;

};

if(PINA.1==0) // nếu nhấn giữ nguyên nút chon

y=0; // chế độ giá trị b không thay đổi

switch(b)

{

Page 47: Bài Báo Cáo Môn Vi Xử Lý

case 1: xuat(15,giay); // chỉnh giây

xuat(12,phut);

xuat(9,gio);

if(PINA.2&&z==0)

{

giay++;z=1;

if(giay==60)

giay=0;

};

if(PINA.2==0) // giữ nút nhấn giá trị

z=0; // giay không thay đổi

break;

case 2: xuat(15,giay); // chỉnh phút

xuat(12,phut);

xuat(9,gio);

if(PINA.2&&z==0)

{

phut++;z=1;

if(phut==60)

phut=0;

};

if(PINA.2==0) // giữ nút nhấn giá trị

z=0; //phút không thay đổi

break;

case 3: xuat(15,giay); // chỉnh giờ

Page 48: Bài Báo Cáo Môn Vi Xử Lý

xuat(12,phut);

xuat(9,gio);

if(PINA.2&&z==0)

{

gio++;z=1;

if(gio==24)

gio=0;

};

if(PINA.2==0) // giữ nút nhấn giá trị

z=0; // giờ không thay đổi

};

};

if(PINA.0==0)

x=0;

if(PINA.0&&x==0)

{

a=0;

x=1;

};

};

}

else // nếu không nhấn nút chỉnh đồng hồ

{

TIMSK=0x02;

Page 49: Bài Báo Cáo Môn Vi Xử Lý

if(i==100)

{

giay++;

i=0;

};

if(giay==60)

{

giay=0;

phut++;

};

if(phut==60)

{

phut=0;

gio++;

};

if(gio==24)

gio=0;

xuat(15,giay);

xuat(12,phut);

xuat(9,gio);

};

};

}

Page 50: Bài Báo Cáo Môn Vi Xử Lý

10. Bài 10: Thực hiện giao tiếp với tải AC. (vd đèn giao thông)

include <mega16.h>

#include<delay.h>

int i=0,j=0,a=1;

char buffer=0,n=10,m=0;

// Timer 0 output compare interrupt service routine

interrupt [TIM0_COMP] void timer0_comp_isr(void)

{

i++;j++;

if(j==6)

{

switch(a)

{

case 1:

buffer=m%10; //gán giá trị hàng đơn vị của m cho buffer buffer=buffer<<4; // chuyển giá trị vừa nhận lên 4 bit cao

buffer=buffer|(n%10); //gán giá trị hàng đơn vị của n

// cho 4 bit thấp của bufer

PORTA=buffer; // xuất giá trị ra đèn led

PORTB=0x01; // đèn thứ nhất của 2 led đôi sáng

a++;

Page 51: Bài Báo Cáo Môn Vi Xử Lý

break;

case 2:

buffer=m/10; //gán giá trị hàng chục của m cho buffer

buffer=buffer<<4;

buffer=buffer|(n/10); //gán giá trị hàng đơn vị của n

// cho 4 bit thấp của bufer

PORTA=buffer;

PORTB=0x02; // đèn thứ 2 của 2 led đôi sáng

a=1;

}; j=0;

};

}

void main(void)

{

// Input/Output Ports initialization

// Port A initialization

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

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

PORTA=0x00; // trạng thái ngõ ra bằng 0

DDRA=0xFF; // sét các chân port A là ngõ ra

// Port B initialization

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

Page 52: Bài Báo Cáo Môn Vi Xử Lý

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

PORTB=0x00; // trạng thái chân ngõ ra bằng 0

DDRB=0x0F; // set 4 chân bit thấp port B là ngõ ra

// Port C initialization

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

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

PORTC=0x00; // trạng thái chân ngõ ra bằng 0

DDRC=0x3F; // set chân 0 ->5 của port C là ngõ ra

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 7.200 kHz

// Mode: CTC top=OCR0

// OC0 output: Disconnected

TCCR0=0x0D;

TCNT0=0x00;

OCR0=0x47; //10ms

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

TIMSK=0x02;

// Global enable interrupts

#asm("sei")

Page 53: Bài Báo Cáo Môn Vi Xử Lý

PORTC=0x21; // đèn đỏ trên và đèn xanh dưới sáng

while (1)

{

while(n) //10 giay đầu

{

if(n==10) // nếu n==10 thì gán m= 7

m=7;

if(i==100) // sau 1 giây giảm m và n đi 1

{

i=0;

n--;m--;

};

if(n==2) // n=2 thì gán m=2

{

PORTC=0x11; // đèn đỏ trên và đèn vàng dưới sáng

m=2;

};

if(n==0) // n=0 thì gán m=10

{

m=10;

PORTC=0x0c; // đèn xanh trên và đèn đỏ dưới sáng

};

};

while(m) // 10 giây sau

{

Page 54: Bài Báo Cáo Môn Vi Xử Lý

if(m==10) // m=10 thì gán n=7

n=7;

if(i==100) // sau 1 s m và n giảm 1

{

i=0;

m--;n--;

};

if(m==2) // m=2 thì gán n=2

{

PORTC=0x0a; // đèn vàng trên và đèn đỏ dưới sáng

n=2;

};

if(m==0) // m=0 thì gán n=10

{

n=10;

PORTC=0x21; // đèn đỏ trên và đèn xanh dưới sáng

};

};

};

}