mach do nhiet do ds18b20 hien thi lcd.pdf

37
[email protected] Lest’s Share to be Shared 1 Đo nhit độ dùng DS18B20,đo khong cách, giao tiếp máy tính, hin thLCD. Li m: Mình hy vng đề tài này sgiúp cho bn hiu thêm vlp trình cho Avr. Mình đã bước đầu làm quen vi Avr và gp nhiu khó khăn, mt nhiu time (và c$) cho vic làm quen, mong rng tài liu này sgiúp bn tiếp cn Avr nhanh hơn .Tt cphn cng và code mình đã làm và chy OK. Cui cùng xin cm ơn din đàn dientuvietnam.net đã cho mình hc hi rt nhiu kiến thc. Đặc bit là mod Sphinx,( xin cm ơn nhân sư ca Pnlab :D ) CHÚ Ý : Tài liu này chdành cho newbie ,chcác bác cao thđọc thì em ly làm xu hlm. Các trang web bích cho vn đề này : www.dientuvietnam.net http://vagam.dieukhien.net/ LCD: 1. http://dientuvietnam.net/forums/showthread.php?t=281&highlight=L%E1%BA%ADp +tr%C3%ACnh+hi%E1%BB%83n+th%E1%BB%8B+LCD+b%E1%BA%B1ng+Asse mbler+%28+tutorial%29 2. http://www.vagam.dieukhien.net/discuss.php?thid=3121&pagenum=2 3. http://vagam.dieukhien.net/discuss.php?thid=148&pagenum=1 RS232 4. http://www.8051projects.net/serial-communication/introduction.php 5. http://www.vagam.dieukhien.net/discuss.php?thid=3216&pagenum=1 6. http://dientuvietnam.net/forums/forumdisplay.php?f=74

Upload: hieuhuech1

Post on 22-Oct-2015

382 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

1

Đo nhiệt độ dùng DS18B20,đo khoảng cách, giao tiếp máy tính, hiển thị LCD.

Lời mở:

Mình hy vọng đề tài này sẽ giúp cho bạn hiểu thêm về lập trình cho Avr. Mình đã bước đầu làm quen với Avr và gặp nhiều khó khăn, mất nhiều time (và cả $) cho việc làm quen, mong rằng tài liệu này sẽ giúp bạn tiếp cận Avr nhanh hơn .Tất cả phần cứng và code mình đã làm và chạy OK.

Cuối cùng xin cảm ơn diễn đàn dientuvietnam.net đã cho mình học hỏi rất nhiều kiến thức. Đặc biệt là mod Sphinx,( xin cảm ơn nhân sư của Pnlab :D )

CHÚ Ý : Tài liệu này chỉ dành cho newbie ,chứ các bác cao thủ mà đọc thì em lấy làm xấu hổ lắm.

Các trang web bổ ích cho vấn đề này :

www.dientuvietnam.net

http://vagam.dieukhien.net/

LCD:

1. http://dientuvietnam.net/forums/showthread.php?t=281&highlight=L%E1%BA%ADp

+tr%C3%ACnh+hi%E1%BB%83n+th%E1%BB%8B+LCD+b%E1%BA%B1ng+Asse

mbler+%28+tutorial%29

2. http://www.vagam.dieukhien.net/discuss.php?thid=3121&pagenum=2

3. http://vagam.dieukhien.net/discuss.php?thid=148&pagenum=1

RS232

4. http://www.8051projects.net/serial-communication/introduction.php

5. http://www.vagam.dieukhien.net/discuss.php?thid=3216&pagenum=1

6. http://dientuvietnam.net/forums/forumdisplay.php?f=74

Page 2: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

2

Phần cứng :

Dưới đây là cái mạch của mình .

Page 3: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

3

Mạch thật nè (xấu quá :D):

Page 4: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

4

Các linh kiện trong mạch:

� Chip AVR Atmega16. � IC DS18B20. � IC GP2D12. � MAX 232. � LCD 1602 � LM7805. � Led, trở, loa tụ.

Có lẽ không phải nói nhiều về mạch này

Mình chỉ xin đề cập 1 số phần nhỏ :

� Kết nối với ds18B20 bạn có thể xem ở datasheet � Trong mạch có jump của mạch nạp , có thể bỏ đi vì cho vào mạch sẽ phức tạp hơn. � Code mình dùng thạch anh trong 4Mhz nên bạn có thể bỏ thạch anh và tụ 22p nếu dùng

thạch anh trong. � Mình dùng adc chân adc0 để đo khoảng cách từ con Gp2D12, nếu bạn ko dùng con này

thì có thể coi code như là adc bình thường. Về phần cứng chỉ có vậy. Bạn có thể tham khảo thêm file mạch mình gửi kèm.

Phần mềm: Bây giờ lập trình nào, mình chia làm 2 phần : trên AVR (mình dùng CodeVisionAvr)và trên PC (dùng Vb6 :D).

CodeVision AVR: Mình kết hợp adc và ds18B20 bị lỗi (cũng không biết tại sao, bạn giải quyết được nhớ chỉ cho mình nhé) nên mình lập trình 2 code riêng 1 code đo nhiệt độ và 1 code ADC.

Sau đây là code đo nhiệt độ :

Page 5: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

5

Click chọn new Project :

Dĩ nhiên là Yes rồi Sau đó bạn lần lượt cấu hình như sau:

Chọn chip

Page 6: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

6

Nối LCD vào PORT B

Page 7: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

7

Cấu hình ds18B20

Page 8: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

8

Cấu hình USART

Page 9: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

9

Cấu hình cổng OUT cho các PORTA.2 và PORTA.4 để báo hiệu ra LED và Loa

Sau đó vào menu vào như trong hình rồi chọn tên file để save

Page 10: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

10

Bây giờ ta đã có code c/t tự dịch . Đầu tiên là phải thay dòng #include

<ds1820.h> bằng #include <ds18b20.h> (đơn giản vì ta dùng IC 18B20). Cuối cùng đây là code mình đã viết /*****************************************************

This program was produced by the

CodeWizardAVR V2.03.4 Standard

Automatic Program Generator

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

http://www.hpinfotech.com

Project :

Version :

Date : 6/23/2009

Author : DuongV3

Company : DHBK

Comments: Have A Mice Day

Chip type : ATmega16

Program type : Application

Clock frequency : 4.000000 MHz

Memory model : Small

External RAM size : 0

Data Stack size : 256

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

#include <mega16.h>

#include <delay.h>

// 1 Wire Bus functions

#asm

.equ __w1_port=0x15 ;PORTC

.equ __w1_bit=0

#endasm

#include <1wire.h>

// DS1820 Temperature Sensor functions

Page 11: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

11

#include <ds18b20.h>

// Alphanumeric LCD Module functions

#asm

.equ __lcd_port=0x18 ;PORTB

#endasm

#include <lcd.h>

int c,d,tp1,tp2,tp3,tp4;

typedef unsigned char byte;

flash byte char0[8]={

0b0000000,

0b0011100,

0b0010100,

0b0011100,

0b0000000,

0b0000000,

0b0000000,

0b0000000};

void define_char(byte flash *pc,byte char_code)

{

byte i,a;

a=(char_code<<3) | 0x40;

for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);

}

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

Page 12: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

12

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

Page 13: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

13

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(char c)

{

while (tx_counter == TX_BUFFER_SIZE);

#asm("cli")

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

Page 14: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

14

{

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

// Standard Input/Output functions

#include <stdio.h>

// Declare your global variables here

void putnum(int a)

{

switch(a){

case 0: putchar('0');

break;

case 1: putchar('1');

break;

case 2: putchar('2');

break;

case 3: putchar('3');

break;

case 4: putchar('4');

break;

case 5: putchar('5');

break;

case 6: putchar('6');

break;

case 7: putchar('7');

break;

case 8: putchar('8');

break;

case 9: putchar('9');

break;

Page 15: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

15

};

}

int getnum(unsigned char a)

{

switch(a){

case 0: return 0;

break;

case 1: return 1;

break;

case 2:return 2;

break;

case 3: return 3;

break;

case 4: return 4;

break;

case 5: return 5;

break;

case 6: return 6;

break;

case 7: return 7;

break;

case 8: return 8;

break;

case 9: return 9;

break;

};

}

void locso(float so)

{

// unsigned char t,c,d,tp1,tp2,tp3,tp4;

float temp1,temp2;

// t=so/100;

// lay fan tram

c=so/10;

// lay fan chuc

d=(so-10*c);

// lay hang don vi

if(so<0)

Page 16: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

16

temp2=so*-1;

else

temp2=so;

temp1=temp2-(c*10+d);

tp1 = (unsigned char)(temp1*10);

tp2 = (unsigned char)(temp1*100-tp1*10);

tp3 = (unsigned char)(temp1*1000-tp1*100-tp2*10);

tp4 = (unsigned char)(temp1*10000-tp1*1000-tp2*100-tp3*10);

}

// unsigned char t,c,d,tp1,tp2,tp3,tp4;

void main(void)

{

float tg;

char lcd_buffer[10];

unsigned char kt;

int min,max,t_g,array[4],i;

// Input/Output Ports initialization

// Port A initialization

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

Func0=In

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

PORTA=0x00;

DDRA=0x14;

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

PORTB=0x00;

DDRB=0x00;

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

Page 17: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

17

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

PORTD=0x00;

DDRD=0x00;

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

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

Page 18: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

18

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

// USART initialization

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

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 9600

UCSRA=0x00;

UCSRB=0xD8;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x19;

// Analog Comparator initialization

// Analog Comparator: Off

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

ACSR=0x80;

SFIOR=0x00;

// 1 Wire Bus initialization

w1_init();

// LCD module initialization

lcd_init(16);

Page 19: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

19

// Global enable interrupts

#asm("sei")

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf("DuongV3");

lcd_gotoxy(0,1);

lcd_putsf("T(C)= ");

define_char(char0,0);

delay_ms(1000);

i=0;

max=35;

min=30;

while (1)

{

if (rx_counter>0){

kt=getchar(); //kt tra ve se la gia tri trong bang ASCii

// lcd_putchar(kt);

array[i]=getnum(kt)-48;

++i;

}

if(i==2)

{

max=array[0]*10+array[1];

}

if(i==4)

{

i=0;

min=array[2]*10+array[3];

array[0]=0;

array[1]=0;

array[2]=0;

array[3]=0;

}

// Chon so max, min

if (max<min)

{

t_g=max;

Page 20: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

20

max=min;

min=t_g;

}

//In ra LCD Gia tri max min

sprintf(lcd_buffer,"%d",max);

lcd_gotoxy(0,0);

lcd_putsf("Max= ");

lcd_puts(lcd_buffer);

sprintf(lcd_buffer,"%d",min);

lcd_gotoxy(8,0);

lcd_putsf("Min= ");

lcd_puts(lcd_buffer);

//

if(ds18b20_init(0,25,35,DS18B20_12BIT_RES))

{

tg= ds18b20_temperature(0);

// temp=(unsigned char) (tg);

if(tg==-9999)

{

}

else

{

lcd_gotoxy(6,1);

if(tg<0)

lcd_putchar(45);

else

lcd_putchar(43);

sprintf(lcd_buffer,"%.4f",tg);

lcd_puts(lcd_buffer);

lcd_putchar(0);

lcd_putsf("C");

delay_ms(80);

if(tg>max)

PORTA=0x10; //PORTA=0x14;

else if (tg<min)

PORTA=0x14;

else PORTA=0x00;

Page 21: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

21

}

}

locso(tg);

putnum(c);

putnum(d);

putchar('.');

putnum(tp1);

putnum(tp2);

putnum(tp3);

putnum(tp4);

putchar(' ');

};

}

Bây giờ mình xin giải thích về lưu đồ thuật toán trong hàm main và vòng while(1) (ngại vẽ lắm nên chỉ nói thôi).

Đầu tiên c/t sẽ từ khởi tạo cho ta ds18b20 và lcd.Sau đó viết lên dòng đầu tiên màn hình dòng chữ DuongV3 (cái này thì tất nhiên bạn sẽ thay đổi thôi :D). Sau đó là viết lên dòng thứ 2 dòng chữ t(c) . Đặt giá trị i , max , min ban đầu để cảnh báo. Chi tiết về lập trình LCD, bạn tham khảo ở trang sau :

http://www.vagam.dieukhien.net/discuss.php?thid=3121

http://vagam.dieukhien.net/discuss.php?thid=148&pagenum=1

Bây giờ là trong vòng while: Nhận ký tự từ cổng Com(nếu có) � ghi 2 ký tự nhận được vào mảng (2 ký tự này sẽ coi là 1 số max hoặc min) Sau đó nhận tiếp 2 ký tự nữa lưu vào mảng (2 ký tự này sẽ coi là 1 số max hoặc min).,Hàm getnum là mình viết có tác dụng chuyển từ ký tự sang số để lưu vào mảng � so sánh 2 số và chọn max ,min � Ghi ra LCD � Nếu khởi tạo ban đầu cho ds18b20 thành công gán tg cho nhiệt độ từ con ds18B20 � Nếu dương ghi dấu “+”, nếu âm ghi dấu “-” ,đưa giá trị ra LCD � locso() có tác dụng chuyển số nhiệt độ có dạng xx.xxxx về các số riêng phần chục , dv, thập phân tương ứng với các biến c,d,tp1,tp2,tp3,tp4 � Hàm putnum () mình viết có tác dụng đưa 1 số ra cổng COM . Vậy là hết nhỉ :D

Chú ý cấu hình hàm sprintf() như sau:

Page 22: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

22

Vào Project� configure:

Chọn như sau :

Page 23: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

23

Sau đây là code ADC : Cấu hình giống trên các phần của chip, lcd , PORT còn ADC cấu hình như sau :

Ở đây mình dùng ADC 10bit nên nên ko tick vào ô “Use 8 bits”. Và mình chọn chân ADC vào là ADC0 nên nó sẽ scan First =0 và Last = 0 Cuối cùng đây là code phần này.

#include <mega16.h>

// Alphanumeric LCD Module functions

#asm

.equ __lcd_port=0x18 ;PORTB

#endasm

#include <lcd.h>

int t,c,d;

typedef unsigned char byte;

Page 24: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

24

flash byte char0[8]={

0b0111111,

0b0100001,

0b0100001,

0b1110001,

0b0100001,

0b0100001,

0b0100001,

0b0011111};

/* function used to define user characters */

void define_char(byte flash *pc,byte char_code)

{

byte i,a;

a=(char_code<<3) | 0x40;

for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);

}

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

Page 25: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

25

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

Page 26: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

26

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

}

Page 27: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

27

else

UDR=c;

#asm("sei")

}

#pragma used-

#endif

// Standard Input/Output functions

#include <stdio.h>

#include <delay.h>

#define FIRST_ADC_INPUT 0

#define LAST_ADC_INPUT 0

unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];

#define ADC_VREF_TYPE 0x00

// ADC interrupt service routine

// with auto input scanning

interrupt [ADC_INT] void adc_isr(void)

{

static unsigned char input_index=0;

// Read the AD conversion result

adc_data[input_index]=ADCW;

// Select next ADC input

if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))

input_index=0;

ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;

// Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0x40;

}

void putnum(int a)

{

switch(a){

case 0: putchar('0');

break;

case 1: putchar('1');

Page 28: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

28

break;

case 2: putchar('2');

break;

case 3: putchar('3');

break;

case 4: putchar('4');

break;

case 5: putchar('5');

break;

case 6: putchar('6');

break;

case 7: putchar('7');

break;

case 8: putchar('8');

break;

case 9: putchar('9');

break;

};

}

void locso(int so)

{

// unsigned char t,c,d,tp1,tp2,tp3,tp4;

// float temp1,temp2;

t=so/100;

// lay fan tram

c=(so-100*t)/10;

// lay fan chuc

d=(so-100*t-10*c);

// lay hang don vi

}

void main(void)

{

unsigned int adc;

unsigned char lcd_buffer[10];

Page 29: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

29

int

a[22]={497,464,420,385,360,330,307,290,266,248,230,224,211,209,198,194,189,182,17

8,170,167,167 },kc,i;

// 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=0x10;

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

PORTB=0x00;

DDRB=0x00;

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

PORTD=0x00;

DDRD=0x00;

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

// Clock value: Timer 1 Stopped

Page 30: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

30

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

Page 31: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

31

// USART initialization

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

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 9600

UCSRA=0x00;

UCSRB=0xD8;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x19;

// Analog Comparator initialization

// Analog Comparator: Off

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

ACSR=0x80;

SFIOR=0x00;

// ADC initialization

// ADC Clock frequency: 1000.000 kHz

// ADC Voltage Reference: AREF pin

// ADC Auto Trigger Source: None

ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);

ADCSRA=0xCA;

// LCD module initialization

lcd_init(16);

// Global enable interrupts

#asm("sei")

lcd_clear();

lcd_gotoxy(0,0);

lcd_putsf("DuongV3");

// define_char(char0,0);

// define_char(char1,1);

// define_char(char2,2);

// lcd_putchar(0);

/* lcd_putsf("i");

lcd_putchar(1);

Page 32: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

32

lcd_putsf("n t");

lcd_putchar(2);*/

while (1)

{

adc = adc_data[0];

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

{

if(adc< a[i] && adc >a[i+1])

{

kc= i+10;

lcd_gotoxy(0,1);

break;

}

}

// lcd_gotoxy(0,1);

if(adc> a[0] || adc <a[19])

{ //lcd_clear();

lcd_gotoxy(0,1);

lcd_putsf("Ngoai Khoang ");

delay_ms(100);

}

else //if(adc< a[0] && adc >a[29])

{

sprintf(lcd_buffer,"Distance :%d",kc);

lcd_gotoxy(0,1);

lcd_puts(lcd_buffer);

lcd_putsf(" cm ");

locso(kc);

putnum(c);

putnum(d);

putchar(' ');

delay_ms(100);

};

};

}

Page 33: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

33

Tất nhiên , khi lập trình bạn phải thay giá trị của mảng cũng như code trong vòng while .

Code trên PC (phần này nêu qua thôi vì có trong Folder rồi):

Dim s As String

Private Sub Command1_Click()

s = MSComm1.Input 'Temp

Text1.Text = s

End Sub

Private Sub Command2_Click()

s = MSComm1.Input

Text2.Text = s

End Sub

Private Sub Command3_Click()

s = Text3.Text ' Max

MSComm1.Output = s

End Sub

Private Sub Command4_Click()

s = Text4.Text 'Min

MSComm1.Output = s

End Sub

Page 34: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

34

Private Sub Command5_Click()

End

End Sub

Private Sub Form_Load()

MSComm1.CommPort = 1

MSComm1.Settings = "9600,n,8,1"

MSComm1.PortOpen = True

End Sub

Cách dùng : cho 2 số có 2 chữ số vào ô MAX , MIN sau đó click vào Button � truyền xuống LCD . Click vào nhiet do để đọc nhiet do.

Chú ý: để dùng cái này , phải tắt các tài nguyên đang dùng cổng Com như mạch nạp (có thể) hoặc terminal của CodeVision. Và file .exe của mình bật lên rất là lâu mới lên (cũng ko biết tại sao, KIS báo là virus :D )

Cuối cùng là 1 số chú ý (có thể bạn làm làm giống hệt trên � cho vào mạch ko chạy thì chú ý 1 số lỗi hay gặp sau):

1. Điều đầu tiên là xem lại mạch, kiểm tra các chân LCD và PORTB, AVR với MAX232, MAX 232 với cổng COM .. ,Ban đầu mình truyền toàn ký tự lỗi , hóa ra hàn cổng Com chưa chắc ( nhất là chân nối GND ) :D

2. Bạn đã cấu hình cho hàm sprintf chưa ?.

Page 35: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

35

3. Cấu hình cho dao động 4Mhz dao động trong cho AVR . Mình dùng mạch nạp AVR 910 dùng AVRProg cấu hình như sau :

4. Clcick vào Advance

Chọn như trên , rồi Chip erase � Write

Page 36: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

36

Và nếu là mạch nạp khác , bạn phải chọn Fuse bits, chi tiết xem tại trang sau: (vì tôn trọng bản quyền mà nên mình sẽ không nói): http://www.dientuvietnam.net/forums/showthread.php?t=4182 Mình chú ý bạn 1 bảng trong datasheet thôi:

5. Cái code Vision rất là khó hiểu,ban đầu bạn viết code OK sau đó chỉ thay đổi 1 số thứ � nó không chạy � đem trở về giá trị ban đầu � lần này ko chạy thật. Vì vậy kinh nghiệm của mình là viết code OK thì copy, coi là ver 1 sau đó muốn sửa gì thì sửa . VD như : với code Ok nếu bạn thay thanh ghi UBRRL và UBRRH thì phần giao tiếp máy tính sẽ ko chạy (tất nhiên), bạn đưa nó về giá trị ban đầu � nó sẽ vẫn ko chạy:D. À ,mà nhân đây nói giao tiếp máy tính, mình nói luôn cách tính UBRRL và UBRRH khi chọn thạch anh . Công thức sẽ là

Page 37: Mach Do Nhiet Do Ds18B20 Hien Thi LCD.pdf

[email protected] Lest’s Share to be Shared

37

UBRR =( Tần số thạch anh /9600*16) -1. Sau đó sẽ cho vào phần High và low của UBRR (ở đây là số hệ 16 (0x) ).

6. Cuối cùng nếu nó vẫn ko chạy, hãy liên lạc với mình , mình sẽ cố gắng giúp :D [email protected] .

7. Và nữa là : Code mình viết không hoàn toàn tối ưu, cả trên vi điều khiển lẫn PC (nhất là trên PC , mình viết vội trong 1 đêm :D ) . Bạn nếu cải tiến thì share luôn cho mình để mình học tập nhé. Mà quên, ngay cả bài này mình cũng viết vội nên nếu sai về chính tả, bạn bỏ qua nhé ^-^

Lest’s Share to be Shared !!!!!!!