Bài giảng lớp VĐK nâng cao
Bài 1,2Giới thiệu chung :
1.Kiến trúc vi điều khiển:
AVR là họ vi điều khiển mới, với những tính năng rất mạnh đ ược tích
hợp trong chip của hãng Atmel theo công nghệ RISC, nó ngang hang với các
họ vi điều khiển khác cùng thời như PIC, Pisoc, nhưng được sử dụng phổ
biến hơn .
Do ra đời muộn hơn nên họ vi điều khiển AVR có nhiều tính năng
mới đáp ứng tối đa nhu cầu của ng ười sử dụng, nhất là những ai đã sử dụng
qua các dòng vi điều khiển trước nó như họ 89xx sẽ có sự so sánh toàn diện
hơn về độ ổn định, khả năng tích hợp v à sự mềm dẻo trong việc lập tr ình
AVR, đặc biệt là nó có bộ phần mềm lập trình vô cùng tiện dụng .
Một số tính năng mới của họ AVR:
- Giao diện SPI đồng bộ.
- Các đường dẫn vào/ra (I/O) lập trình được.
- Giao tiếp I2C.
- Bộ biến đổi ADC 10 bit.
- Các kênh băm xung PWM.
- Các chế độ tiết kiệm năng lượng như sleep, stand by..vv.
- một bộ định thời Watchdog.
- 3 bộ timer/Counter 8 bit.
- 1 bộ timer/Counter 16 bit.
- 1 bộ so sánh analog.
- bộ nhớ EEPROM.
- Giao tiếp USART..vv.
2. Giới thiệu vi điều khiển Atmega16L:
1
Lựa chọn vi điều khiển Atmelga16L về tính năng có đầy đủ tính năng
của họ AVR, về giá thành so với các loại khác thì giá thành là vừa phải khi
nghiên cứu và làm các công việc ứng dụng tới vi điều khiển.
Tính năng:
- Bộ nhớ 16K(flash) .
- 512 byte (EEPROM).
- 1 K (SRAM).
- Đóng vỏ 40 chân , trong đó có 32 chân v ào ra dữ liệu chia làm 4
PORT A,B,C,D. Các chân này đ ều có chế độ pull_up reitors.
- Giao tiếp SPI.
- Giao diện I2C.
- Có 8 kênh ADC 10 bit.
- 1 bộ so sánh analog.
- Có 4 kênh băm xung PWM.
- 3 bộ timer/counter , 2 bộ timer/counter 0,2 ở chế độ 8 bit, 1 bộ
timer/counter1 16 bit.
- 1 bộ định thời Watchdog.
- 1 bộ truyền nhận UART lập trình được.
24VCC
Cách sử dụng và tính năng các chân khi thiết kế mạch:
- Vcc và GND 2 chân cấp nguồn cho vi điều khiển hoạt động.
- Reset đây là chân reset cứng khởi động lại mọi hoạt động của hệ thống.
- 2 chân XTAL1, XTAL2 các chân t ạo bộ dao động ngoài cho vi điều khiển,
các chân này được nối với thạch anh (hay sử dụng loại 4M), tụ gốm (22p).
- Chân Vref thường nối lên 5v(Vcc), nhưng khi sử dụng bộ ADC thì chân
này được sử dụng làm điện thế so sánh, khi đó chân n ày phải cấp cho nó
điện áp cố định, có thể sử dụng diod zener:
10K
R
Vref
5V
GND
DIODE BREAKDOWN
Hình 3.7. Cách nối chân Vref
- Chân Avcc thường được nối lên Vcc nhưng khi sử dụng bộ ADC
thì chân này được nối qua 1 cuộn cảm lên Vcc với mục đích ổn
định điện áp cho bộ biến đổi.
2
3. Phần mềm lập trình codevision:
Lựa chọn phần mềm : đây là phần mềm được sử dụng rất rộng dải bởi
nó được xây dựng trên nền ngôn ngữ lập trình C, phần mềm được viết
chuyên nghiệp hướng tới người sử dụng bởi sự đơn giản, mềm dẻo, sự hổ trợ
cao các thư viện có sẳn.
4.Thiết lập cổng vào ra:
Sơ đ ồ bố trí chân của AVR ATMEGA16
Khi xem xét đến các cổng I/O của AVR thì ta phải xét tới 3 thanh ghi bit
DDxn,PORTxn,PINxn.
Thực hiện việc trao đổi giữa VĐK AVR với b ên ngoài thì cần phải biết là
đang thực hiện xuất/nhập.
Thanh ghi DDRx đảm nhận việc xuất/nhập của các chip AVR.
-Các bit DDxn để truy cập cho địa chỉ xuất nhập DDRx.
-Các bit PORTxn để truy cập tại địa chỉ xuất nhập PORTx.
-Các bit PINxn để truy cập tại địa chỉ xuất nhập PINx.
-Bit DDxn trong thanh ghi DDRx dùng để điều khiển hướng dữ liệu của các
chân của cổng này.Khi ghi giá trị logic ‘0’ vào bất kì bit nào của thanh ghi
này thì nó sẽ trở thành lối vào,còn ghi ‘1’ vào bit đó thì nó trở thành lối ra.
3
-PINx là các cổng chỉ để đọc,các cổng này có thể đọc trạng thái logic của
PORTx.PINx không phải là thanh ghi,việc đọc PINx cho phép ta đọc giá trị
logic trên các chân của PORTx.chú ý PINx không phải là thanh ghi,việc đọc
PINx cho phép ta đọc giá trị logic trên các chân của PORTx.
-Khi PORTx được ghi giá trị 1 khi các chân có cấu tạo nh ư cổng ra thì điện
trở kéo là chủ động(được nối với cổng).Ngắt điện trở kéo ra, PORTx được
ghi giá trị 0 hoặc các chân có dạng nh ư cổng ra.Các chân của cổng l à 3 trạng
thái khi 1 điều kiện reset là tích cực thậm chí xung đồng hồ không hoạt
động.
-Nếu PORTxn được ghi giá trị logic ‘1’ khi các chân của cổng có dạn g như
chân ra ,các chân có giá trị ‘1’.Nếu PORTxn ghi giá trị ‘0’ khi các chân của
cổng có dạng như chân ra thì các chân đó có giá trị ‘0’.
Các cổng của AVR đều có thể đọc,ghi.
Để thiết lập 1 cổng là cổng vào ,ra thì ta tác động tới các bit DDxn,
PORTxn,PINxn.ta có thể thiết lập để từng bit làm cổng vào,ra cứ không chỉ
với cổng,như vậy ta có thể sử lí tới từng bit,đây chính l à điểm mạnh của các
dòng Vi điều khiển 8 bit.
4
Ta có thể sử dụng CodeWizardAVR để thiết lập cho cá c PORTx và Pinx.
Ví dụ như trên hình:các bit 0,1,2,4,7 của PORTA làm chân ra có trở kéo,còn
các bit còn lại làm chân vào.
Khi đã thiết lập xong thì các bit 0,1,2,4,7 sẽ có thể xuất dữ liệu ra còn các bit
còn lại có thể nhận dữ liệu vào.
Ví dụ :
Ta muốn ghi dữ liệu giá trị logic ’0’ ra PORTA.0 để bật tắt một Led th ì:
PORTA.0=1;
Ta muốn đọc dữ liệu là một bit từ chân 3 của PORTA:
Bit x;
x=PINA.3;
Cũng như vậy khi ta thiết lập PORTA l àm cổng ra thì ta có thể xuất dữ liệu
ra từ PORTA:
PORTA=0xAA;
5
PORTA
Còn nếu ta thiết lập PORTA làm cổng vào và giá trị hiện thời của PORTA:
PORTA
Thì sau câu lệnh đọc giá trị từ PORTA: x=PINA;th ì x=0x55;
Khi thiết lập PORTA làm cổng ra thì khi reset giá trị của PORTA là
PORTA=0xFF;
PORTA
Khi thiết lập PORTA làm cổng vào thì khi reset giá trị của PORTA là
PORTA=0x00;
PORTA
Việc thiết lập cổng vào ra là một việc quan trọng vì tùy theo mục đích sử
dụng các cổng nào làm cổng vào ra,thì ta phải thiết lập đúng thì mới có thể
sử dụng được,ta có thể so sánh vấn đề n ày với dòng vi điều khiển AT8951.
Nếu ở AT8951,ta thiết lập PORTx làm cổng vào nhưng ta lại sử dụng với
mục đích là cổng ra,thì PORTx sẽ bị hỏng qua vài lần cho kết quả đúng,và
do ta quên không thiết lập PORTx là cổng ra,câu lệnh cũng không khác n ên
ta không phát hiện ra.Khi ta thiết lập PORTx làm cổng vào nhưng lai sử
dụng với mục đích cổng ra thì do câu lệnh không khác nên ta cũng không
phát hiện ra.
Ví dụ:
PORT0=0xFF;(PORT0 là cổng vào)sau đó ta lại xuất dữ liệu ra
PORT0=0xAA;có thể ban đầu vẫn cho kết quả đúng nh ưng chắc chắn
PORT0 sẽ bị hỏng.
PORT0=0x00;(PORT0 là cổng ra)sau đó ta lại nhập dữ liệu v ào
x=PORT0;thì ta cũng không đọc được.
Còn ở AVR,khi muốn nhập dữ liệu vào thì phải thiết lập PORTx là cổng vào
và dùng câu lệnh:
X=PINx;//không dùng x=PORTx.
6
Thực hành lập trình:
Chúng ta tiếp tục chương trình với các bài thực hành:
Thiết lập chương trình nháy LED
D3
R_470
chan VDK
5VCC
LED
Thiết lập chương trình như sau: Theo sơ đồ nguyên lý như hình vẽ các
chân của vi điều khiển được nối với đèn LED qua 1 trở kéo lên 5v chúng ta
thiết lập chương trình cho đèn LED nháy liên tục ở các tần số khác nhau.
{
// Declare your local variables here
// 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=0xff;
DDRA=0xFF;
// Port B 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
PORTB=0xff;
DDRB=0xFF;
// 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=0xff; //su dung tro keo trong
DDRC=0xFF;
// 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=0xff;
DDRD=0xFF;
}
while (1)
{
// Place your code here
// cho tat ca cac LED deu sang
PORTA=0x00;
PORTB=0x00;
PORTC=0x00;
7
PORTD=0x00;
delay_ms(300);// delay 300ms, thoi gian de lay co the thay doi
// tat toan bo cac LED
PORTA=0xff;
PORTB=0xff;
PORTC=0xff;
PORTD=0xff;
delay_ms(300);// delay 300ms
};
Như vậy trong đoạn chương trình trên nếu chúng ta dưa thời gian delay dưới
dạng biến số có thể thay đổi được tg , ta sẽ thấy thời gian đóng ngắt của
LED sẽ thay đổi delay_ms(tg).
Trước hết ta khai báo biến tg như sau:
unsigned char tg; khai báo biến tg dạng nguyên từ 0->255.
/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.6 Professional
Automatic Program Generator
© Copyright 1998-2005 Pavel Haiduc, HP InfoTech s.r.l.
e-mail:
Project :
Version :
Date : 12/7/2006
Author : F4CG
Company : F4CG
Comments:
Chip type
: ATmega16L
Program type
: Application
Clock frequency : 8.000000 MHz
Memory model
: Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
//************* bai tap giao tiep voi phim bam*******************
//***************************************************************
/*
noi dung bai tap la thet lap phim bam o PINA
kiem tra cac phim bam de lua chon chuong trinh
*/
#include <mega16.h>
8
#include <delay.h>
unsigned char tg; // bien thoi gian la tg co the thay doi
// Declare your global variables here
// Phan main thiet lap cac thanh ghi sau khi khoi tao chuong trinh
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; // thiet lap PORTA lam dau vao
// Port B 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
PORTB=0x00;
DDRB=0xFF;
// 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 Stat e1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// 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;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
9
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// 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=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
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=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
tg=50; // gan bien tg=50 ban dau .
10
//--------------------------------------------------------------- -----------//---------------- phan chuong trinh chay chinh -----------------------//---------------------------------------------------------------------------while (1)
{
// Place your code here
while(!PINA.0) // lenh kiem tra ne u PINA.0=0
{
tg=tg+10;
delay_ms(100) ;
}
PORTC=0xaa;
PORTD=0xaa;
delay_ms(tg);// delay tg ms
PORTC=0x55;
PORTD=0x55;
delay_ms(tg);// delay tg ms
while(!PINA.1) // lenh kiem tra neu PINA.1=0
{
PORTC=0x00;
PORTD=0x00;
}
while(!PINA.2) // lenh kiem tra neu PINA.2=0 thi tat cac LED PORTC,D
{
PORTC=0xff;
PORTD=0xff;
}
};
}
11
Bài 3:Giới thiệu bộ biến đổi ADC, bộ nhớ EEPROM nội AVR :
+ADC cho LM35 và biến trở -> hiển thị LCD.
+Các biến EEPROM nội AVR-> hiển thị LCD.
VCC
Chức năng của LCD trong mạch Robocon củng như trong hầu hết
các mạch (các bộ điều khiển khác) hầu như chủ yếu đảm nhân vai trò
hiển thị các thông số , các thông tin mà chúng ta muốn nhập vào hay
các thông tin sử lý mà bộ điều khiển đang hoạt động đựoc hiển thị ra
màn hình , giúp chúng ta giao tiếp gần hơn với quá trình hoạt đông
của hệ thống.
loại LCD mà chúng ta sử dụng là loại SD-DM1602A , loại này
hiện nay được Trung Quốc sản xuất . đây là LCD 2 dòng mổi dòng 16
kí tự , nó có 16 chân như hình vẽ:
GND
bien tro
GND
VCC
VSS
PB0
PB1
PB2
1
2
3
4
5
6
7
8
9
10
PB4(SS)11
PB5(MOSI)
12
PB6(MISO)
13
PB7(SCK)
14
15
16
LCD
Trong đó chúng ta có thể thấy 2 chân 1,2 được cấp nguồn cho LCD
hoạt động , chân thứ 3 (chân VSS) được nối vào đầu ra của biến trở
dùng để điều chỉnh độ tương phản (phải điều chỉnh VSS hợp lý thì
LCD mới hiển thị được) 2 chân 15,16 đây là 2 chân cấp nguồn dung
để bật đèn của LCD từ chân 4->14 là các chân điều khiển được nối
với vi điều khiển , các chân 4,5,6 được nối với vi điều khiển để điều
khiển LCD hoạt động , các chân còn lại là các chân Data dung để
truyền nhận dữ liệu . chúng ta có thể truyền Data 8 bit một hoặc 4 bit
một , như trong mạch của chúng ta truyền Data dưới dạng 4 bit một
việc truyền dưới dạng 4bit hoặc 8 bit phải được thiết lập cả phần cúng
và phần mềm .
12
Để sử dụng tính năng ADC của Atmega 16L chúng ta cần phải
thiết kế phần cứng của Vi điều khiển như sau :
Chân AVCC chân này bình thường khi thiết kế mạch chúng ta đưa lên
5vcc nhưng khi trong mạch có sử dụng các kênh ADC của phần cứng
thì chúng ta phải nối chân này lên 5vcc qua 1 cuộn cảm nhằm mục
đích cấp nguồn ổn định cho các kênh (đầu vào) của bộ biến đổi ,
Chân AREF chân này cần cấp 1 giá trị điện áp ổn định được sử
dụng làm điện áp tham chiếu , chính vì vậy điện áp cấp vào chân này
cần ổn định vì khi nó thay đổi làm giá trị ADC ở các kênh thu được bị
trôi (thay đổi ) không ổn định với 1 giá trị đầu vào chúng ta có công
thức tính như sau:
ADCx=(V_INT*1024)/ AREF
chỉ dựa vào công thức chúng ta củng có thể thấy giá trị ADCx tỉ lệ
thuận với điện áp vào V_INT(đây chính là V_OUT của Sensor).
Giá trị ADC thu được từ các kênh được lưu vào 2 thanh ghi ADCH và
ADCL khi sử dụng chúng ta phải đọc giá trị từ các thanh ghi này, khi sử
dụng ở ché độ 8 bít thì chỉ lưu vào thanh ghi ADCL.
Bộ nhớ EEPROM để có thể lưu được giá trị của nó khi RESET
chương trình hoặc khi tắt nguồn
Ví dụ :
eeprom unsigned char VA_T;
eeprom unsigned char VB_T;
eeprom unsigned char TG_T;
chúng ta thực hiẹn quá trình khởi tạo ADC và LCD như sau:
Hinh1,2
13
Hình 3,4
Hình 5,6
14
Giao diện chương trình
Hình 7
Như vậy trong bài này chúng ta sử dụng PORTA làm đầu vào, 8 chân
của PORTA sử dụng làm 8 kênh đầu vào ADC.
Giá trị Analog thu được từ LM35, biến trở ta đưa vào các chân
PINA.0,PINA.1 tương ứng với các kênh 0,1 cua bộ biến đổi ADC.
Đọc giá trị ADC từ thanh ghi ADCH,ADCL như sau : m=adc_data[x]
x chính là dịa chỉ kênh đầu vào(0->7).
Các lệnh chính khi sử dụng, điều khiển LCD như :
lcd_gotoxy(0,0);
lcd_putsf("VI DIEU KHIEN NANG CAO ") ;
lcd_putchar();
Lệnh lcd_gotoxy( );
Đặt địa chỉ, vị trí con trỏ bắt đầu của dòng kí tự.
Lệnh lcd_putsf(“ ”) : in ra dòng kí tự.
Lệnh lcd_putchar( ) : in ra giá trị ở dạng char
15
Thuật toán in ra số liệu dưới dạng giá trị nguyên như sau:
void lcd_putnum(unsigned char d)
{
//
unsigned char i,j;
i=d%10;
d=d/10;
j=d%10;
d=d/10;
if(d>0) lcd_putchar(48+d);
// 48 la gia tri o muc nen d la gia tri
//hien thi
if(j>0) lcd_putchar(48+j);
// j la gia tri hien thi
lcd_putchar(48+i);
//
}
Bài toán thứ nhất của chúng ta là đọc giá trị ADC từ LM35 hay từ biến trở
và hiển thị lên màn hình.
Ví dụ đầu ra của LM35 ta đưa vào chân thứ nhất của PORTA(PINA.0)
Lúc này ta hiểu giá trị ADC cần đọc về là kênh 0 adc_data[0], hiển thị lên
LDC như sau:
đầu tiên chúng ta viết chương trình hiển thị số liệu dưới dạng char
void lcd_putnum(unsigned char d)
{
//
unsigned char i,j;
i=d%10;
d=d/10;
j=d%10;
d=d/10;
if(d>0) lcd_putchar(48+d);
// 48 la gia tri o muc nen d la gia tri
//hien thi
if(j>0) lcd_putchar(48+j);
// j la gia tri hien thi
lcd_putchar(48+i);
//
}
Trong chương trình chính chúng ta đọc giá trị ADC như sau:
while (1)
{
// Place your code here
lcd_gotoxy(0,0);
16
lcd_putsf("bai tap ADC");
lcd_gotoxy(5,1);
delay_ms(100);
};
Bài toán thứ 2 chúng ta cần giải quyết đó là sử dụng các biến dưới dạng bộ
nhớ EEPROM như sau:
Khai báo biến 2 biến tg1,tg2 như sau:
eeprom unsigned char tg1=10;
unsigned char tg2=10;
và sử dụng thuật toán giao tiếp với bàn Phím như bài trước như sau :
while(1)
{
lcd_gotoxy(0,0);
lcd_putsf(" Gia tri tg1.tg2")
lcd_gotoxy(2,1);
lcd_putnum(tg1);
lcd_putsf(" ");
lcd_putnum(tg2);
while(!PINA.0) // lenh kiem tra neu PINA.0=0
{
lcd_gotoxy(0,0);
lcd_putsf(" Gia tri tg1.tg2")
lcd_gotoxy(2,1);
lcd_putnum(tg1);
lcd_putsf(" ");
lcd_putnum(tg2);
tg1=tg1+1;
tg1=tg1+1;
delay_ms(100) ;
}
}
Sau khi chạy chương trình chúng ta RESET toàn bộ hệ thống chúng ta thấy
màn hình hiển thị 2 giá trị tg1và tg2 khác nhau.
17
Bài 4. Giao tiếp I2C: RTC với DS1307 và 24Cxx.
Việc giao tiếp theo chuẩn I2C sẽ trở nên đơn giản hơn với AVR
Hình 4.1
Hình 4.2
18
Hình 4.3
Giao diện chương trình chính
Hình 4.4
19
Sau khi thiết lập chương trình xong chúng ta viết thêm đoạn chương trình
hiển LCD như sau:
void lcd_putnum(unsigned char d)
{
//
unsigned char i,j;
i=d%10;
d=d/10;
j=d%10;
d=d/10;
if(d>0) lcd_putchar(48+d);
// 48 la gia tri o muc nen d la gia tri
//hien thi
if(j>0) lcd_putchar(48+j);
// j la gia tri hien thi
lcd_putchar(48+i);
//
}
rtc_set_time(9,10,11) ;// hàm đặt thời gian
chúng ta còn có 1 hàm nữa là hàm đoc thời gian
rtc_get_time(&h,&s,&m);
h : giờ.
s: phút.
M: giây.
Trong vòng lặp chính chúng ta viết doạn chương trình hiển thị thời gian như
sau:
while (1)
{
// Place your code here
rtc_get_time(&h,&s,&m);
lcd_gotoxy(0,0);
lcd_putsf("Real Time Clock");
lcd_gotoxy(0,1);
lcd_putnum(h);
lcd_putsf(" ");
lcd_putnum(s);
lcd_putsf(" ");
lcd_putnum(m);
delay_ms(200);
};
Ngoài ra chúng ta có thể viết tương tụ cho chương trình hiển thị ngày tháng,
năm .
20
Chúng ta thiết lập I2C với 24cxx:
Hinh4.5
Hinh4.6
21
Viết các hàm đọc và ghi EEROM :
//=========================================
=========
unsigned char eeprom_read(unsigned int address);
void eeprom_write(unsigned int address, unsigned char data);
//=========================================
=========
/* read a byte from the EEPROM */
unsigned char eeprom_read(unsigned int address)
{
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
22
}
/* write a byte to the EEPROM */
void eeprom_write(unsigned int address, unsigned char data)
{
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
/* 10ms delay to complete the write operation */
delay_ms(1);
}
//=========================================
=======
Bây giờ chúng ta viết đoạn chương trình ghi vào bộ nhớ ngoài 100 giá
trị sau đó đọc ra và hiển thị vào PPORTD :
void test_24C(){
int i;
while(1){
for(i=0; i<100; i++) eeprom_write(i,i);
for(i=0; i<100; i++){
PORTA = eeprom_read(i);
delay_ms(1000);
}
}
}
Sau đó trong chương trình chính chúng ta chỉ cần gọi hàm
“test_24C()”.
23
Bài 5,6 Giao tiếp qua cổng RS232 , giao tiếp VB với th ư viện MSCOMM
Giao tiếp theo chuẩn RS232 là chuẩn giao tiếp nối tiếp dung định dạng
không đồng bộ, được sử dụng khá phổ biến trong việc kết nối với máy tính
và các thiết bị ngoại vi khác. MSComm là 1 điều khiển dung trong truyền
thông nối tiếp, các tính chất của MSComm được dung để thiết lập giao tiếp
với các ngoại vi qua cổng RS232 , MSComm được hổ trợ cho cả VB và VC
, nhưng đối với VB thì nó trở nên đơn giản hơn.
Các thiết lập và lập trình:
- thiết lập với codevision:
o
Gao diện chính
24
Chúng ta có 2 hàm cơ bản mà phần mềm đã khởi tạo đó là hàm
putchar() và hàm getchar()
Sau khi khởi tạo xung chúng ta có thể viết chương trình truyền và
nhận như sau:
Khai báo biến s: unsigned char s
Sau đó trong chương trình chúng ta thực hiện các lệnh truyền và nhận
các dữ liệu như sau:
s=getchar();
PORTC=s;
putchar(s);
delay_ms(100);
Chúng ta có thể thực hiện chế độ text thử chương trình truyền nhận
như sau:
Ta được giao diện chương trình text như sau:
25