mach do nhiet do ds18b20 hien thi lcd.pdf
TRANSCRIPT
[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
[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 độ :
[email protected] Lest’s Share to be Shared
5
Click chọn new Project :
Và
Dĩ nhiên là Yes rồi Sau đó bạn lần lượt cấu hình như sau:
Chọn chip
[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
[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
[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)
[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);
[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))
[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;
[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)
[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
[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
[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);
[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;
[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;
[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:
[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;
[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];
[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")
[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;
}
[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');
[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];
[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
[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;
[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);
[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);
};
};
}
[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
[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 ?.
[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
[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:
Và
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à
[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 !!!!!!!