You are on page 1of 11

MCH O NHIT IU KHIN TC QUT

I.

II.

NGUYN L HOT NG :
Mch c 2 ch hot ng
Auto : dng cm bin LM35 o nhit i tng ri t iu khin tc qut lm
gim nhit ca i tng ,ty theo nhit qut c th qut nhanh hay chm hoc
tt .
Handy : dng hai nt bm iu khin tc qut ,1 nt tng tc qut ,1 nt
gim tc
Ta c th thay i ch ca qut bng cch bm 1 nt bm ni vi chn B0 ca
PIC16F887 .khi bm nt ny th ch hot ng b thay i t handy sang auto hoc
ngc li.
PHN CNG :
Gm 1 PIC16F887,1 LCD 16x2, 1 cm bin nhit LM35,1 ng c DC ,1 transistor
2N4401,nt bm v cc in tr
Cc linh kin nu trn s c kt ni nh hnh di y:

1. Mch vi iu khin PIC 16F887:


PIC16F887 l 1 dng vi iu khin ca hng MICROCHIP
c tnh phn cng ca PIC16F887:

S mch iu khin :

2. LCD 16x2 :
Di y l bng lit k chn v chc nng ca LCD

y chng ta dng kiu kt ni 4 chn d liu ,v dng th vin flex_lcd.c lp trnh


// flex_lcd.c
// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.
#define LCD_DB4
#define LCD_DB5
#define LCD_DB6
#define LCD_DB7

PIN_D1
PIN_D2
PIN_D3
PIN_D4

#define LCD_E
PIN_D7
#define LCD_RS PIN_D5
#define LCD_RW PIN_D6
// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.
#define USE_LCD_RW 1
//========================================
#define lcd_type 2
// 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line

int8 const LCD_INIT_STRING[4] =


{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc,
// Display on
1,
// Clear display
6
// Increment cursor
};

//------------------------------------void lcd_send_nibble(int8 nibble)


{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//----------------------------------// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//--------------------------------------// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();

low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//---------------------------------------// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//---------------------------void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);

// If the R/W signal is not used, then


// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//---------------------------void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//----------------------------void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//-----------------------------#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
Ta s ni phn cng ca LCD nh sau :
DB4 D1
DB5 D2
DB6 D3
DB7 D4
E D7
RS D5
RW D6
lp trnh cho LCD ta s dng cc lnh sau :
Lcd_init() : thit lp kt ni vi LCD ,mi ln mun lm vic vi LCD ta phi
gi lnh ny u tin.
Lcd_putc(): hin th k t ln mn hnh.
Lcd_gotoxy(): dng di chuyn v tr ca con tr n v tr mong mun
3. Cm bin LM35
Cm bin dng trong mch ny c 3 chn dng TO-92,
Chn s 1 : VCC
Chn s 2 : Vout ,ta s ni chn ny vi chn A0 ca PIC16F877 c
gi tr analog output ca LM35
Chn s 3 : GND
Nguyn l hot ng : in p ng ra tng 10mv khi nhit tng 1 C

III.

C D LIU V IU CH XUNG PWM BNG PIC16F887:


PIC16F877 c b ADC 10 bit ,ta chn tm o l 5v nh vy in p c c s c biu din
bng cc s t 0 n 1023.
chuyn t gi tr digital sang nhit ta s p dng phng trnh nh sau

n gin ta s dng phng trnh gn ng sau


c d liu chnh xc hn ta s ly 1 ln 10 mu mi ln ly mu cch nhau khong
50ms ,sau ly gi tr trung bnh ri mi hin th ra LCD.

Sau ng vi mi gi tr nhit vo ta s iu ch xung PWM v xut xung PWM ra chn


C2(CCP1) iu khin ch hot ng ca qut
mch ny BJT ng vai tr nh mt cng tc in ,khi c xung t Vi iu khin a ra th mi
cho dng chy t cc C sang cc E lm qut chy
Temperature (deg C)
Fan
PWM Value
35
0
36
30
37
30
38
30
39
40
40
50
41
60
42
70
43
80
44
90
45
100
Sau nhit v tc quay ca qut c hin th ra LCD
IV.
CH I KHIN BNG TAY
S c 2 nt bm :
Nt B1 ni vi chn B1 khi n nt ny tc qut s tng
Nt B2 ni vi chn B2 khi n nt ny tc qut gim
Khi tc gim nh hn 30 th tc qut t ng chuyn v 0 v qut s tt ,ngha l
s khng c ch hot ng tm tc 0 30 v tc ny qut khng hot ng
hiu qu m ch lm tn nng lng
V.
CODE:
Code di y s dng chng trnh CCS bin dch
Chng trnh chnh :

#include "16F887.h"
#device ADC= 10
#use delay(clock=4000000)
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#include "flex_lcd.c"
#include "in.c"
#include "demo.c"
int blink ;
#int_ext // Interrupt name
void isrext() // Interrupt service routine name
{
blink = blink +1;
blink = blink&0xf1;
}
void main() //**************************************************************
{
blink = 0;
setup_ccp1(ccp_pwm); // Select timer module and mode
setup_timer_2(T2_DIV_BY_16,255,1); // Clock rate &
enable_interrupts(int_ext); // Enable named interrupt
enable_interrupts(global); // Enable all interrupts
ext_int_edge(H_TO_L); // Interrupt signal polarity
while(1) // Foreground loop
{
switch(blink){
case 0:
auto1();
break;
case 1:
handy();
break;

}
}
}
File in.c cha chng trnh auto1():
Read & display analogue input
***************************************************************************/
int z;
#define b0 PIN_b0
void dec( int16 x)
{ int16 a,b,c,d ;
a = x/1000;
x = x - 1000*a;
b = x/ 100;
x = x - 100*b;
c = x/10;
d = x -10*c;
c = c + 0x30;
a = a + 0x30;
d = d + 0x30;
b = b + 0x30;
lcd_gotoxy(8,1);
lcd_putc(b);
lcd_putc(c);
lcd_putc(".");
lcd_putc(d);
}
void dec2( int16 x)
{
int16 b=0, c=0,d=0;
if ((z ==1)&(x!=1000))
{ lcd_init();
lcd_putc("auto");
lcd_gotoxy(1,2);
lcd_putc("speed");
z = 0;
}
x = x*0.1;
b=x/100;
x = x - 100*b;
c = x/10;
d= x -10*c;
lcd_gotoxy(8,2);
switch(b){
case 1:
b = b + 0x30;
lcd_putc(b);
z = 1;
break;
case 0:
break;
}
c= c+0x30;
lcd_putc(c);
d = d + 0x30;
lcd_putc(d);}
void auto1() //************************************************************

{
int16 vin0 , pwmval,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10; // Input variable
int f;
lcd_init();
lcd_putc("auto");
lcd_gotoxy(1,2);
lcd_putc("speed");
while(1){
setup_adc(ADC_CLOCK_INTERNAL); // ADC clock
setup_adc_ports(sAN0); // Input combination
set_adc_channel(0); // Select RA0
a1 = read_adc(); // lay mau nhiet do
delay_ms(50);
a2 = read_adc();
delay_ms(50);
a3 = read_adc();
delay_ms(50);
a4 = read_adc();
delay_ms(50);
a5 = read_adc();
delay_ms(50);
a6 = read_adc();
delay_ms(50);
a7 = read_adc();
delay_ms(50);
a8 = read_adc();
delay_ms(50);
a9 = read_adc();
delay_ms(50);
a10 = read_adc();
delay_ms(50);
vin0 = (a1+a2+a3+a4+a5+a6+a7+a8+a9+a10)*0.1;
vin0 = (vin0)*4.9 ;
if (vin0 <= 350) pwmval = 0;
if ((vin0 > 350)& (vin0 <= 390)) pwmval = 300;
if ((vin0 > 390)& (vin0 <= 400)) pwmval = 400;
if ((vin0 > 400)& (vin0 <= 410)) pwmval = 500;
if ((vin0 > 410)& (vin0 <= 420)) pwmval = 600;
if ((vin0 > 420)& (vin0 <= 430)) pwmval= 700;
if ((vin0 > 430)& (vin0 <= 440)) pwmval = 800;
if ((vin0 > 440)& (vin0 <= 450)) pwmval = 900;
if (vin0 > 450) pwmval = 1000;
dec2(pwmval);
dec(vin0);
set_pwm1_duty(pwmval);
f = input(b0);
if(f == 0)break;}
}
File demo.c cha chng trnh con handy():
#define b1 PIN_b1
#define b2 PIN_b2
int16 pwm =300,t;
void dec1( int16 x)
{
int16 b=0, c=0,d=0;
if ((t==1)&(x!=1000))
{ lcd_init();
lcd_putc("handy");
lcd_gotoxy(1,2);
lcd_putc("speed");

t = 0;
}
x = x*0.1;
b=x/100;
x = x - 100*b;
c = x/10;
d= x -10*c;
lcd_gotoxy(8,2);
switch(b){
case 1:
b = b + 0x30;
lcd_putc(b);
t = 1;
break;
case 0:
break;
}
c= c+0x30;
lcd_putc(c);
d = d + 0x30;
lcd_putc(d);}
//===============================
int h2l(int x){int a,b;
a = input(x);
delay_ms(20);
b = input(x);
a = 10*a + b;
return a ;}
//==========================
void handy()
{
int x,y,f;
lcd_init();
lb1: lcd_putc("handy");
lcd_gotoxy(1,2);
lcd_putc("speed");
while(1){
x = h2l(b1);
if (x == 10)
pwm = pwm +100;
if ((pwm<300)&(pwm>0))
pwm = 300;
y = h2l(b2);
if (y == 10)
pwm = pwm - 100;
if (pwm <300)
pwm = 0;
if (pwm>1000)
pwm =1000;
f = input(b0);
if(f == 0)break;
set_pwm1_duty(pwm);
dec1(pwm);
}
}
Chng trnh chnh s dng 2 chng trnh con l auto1() (ch iu khin nh cm bin) v
handy() (iu khin bng tay) cha trong 2 file in.c v demo.c
Khi bm nt B0 ngt s xy ra v ch hot ng chuyn t auto sang handy hoc ngc li.

You might also like