You are on page 1of 54

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.
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)

{
// 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


// đè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


};

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


//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


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;

};

};
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);
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);

};

};

};

}
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)

{
// 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;
};

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;
};

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


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
// 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;
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;

};

}
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)
// 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
// 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: Đọc 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;
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 đọc 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


{

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);

while (1)

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

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

if(ADCH<255) // nếu giá trị đọc đượ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ể đọc đượ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;

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

#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

}
// 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;

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;

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>

#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++)

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

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) //đọc 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;

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); // đọc 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);

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;
}

};

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

.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

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_

// 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;

#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;

++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>
// 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];

};

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

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

while (1)

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

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

};

key=COM; // chọn 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; // chọn 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>

#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ố

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

// 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)
{

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 chọn chế độ chỉnh

b++;y=1;

if(b==4)

b=1;

};

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

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

switch(b)
{

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ờ

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;
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);

};

};

}
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++;
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


// 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")
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

{
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

};

};

};

You might also like