You are on page 1of 38

PICAT = Programmable Intelligent Circuit Automation Technology

PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

http://www.holiaco.com

PICAT Class
CCSC for Embedded System Guide
Lecturer: Nguyễn Tuấn Anh
Mobile: 098.808.6099
http://picat.dieukhien.net
Nick chat: ktmt_tact@yahoo.com,
email: tuananhktmt@gmail.com

Student (Trainee): ...............................................................................................

PICAT = Công nghệ tự ñộng với mạch thông minh lập trình ñược
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Phần 1: Giới thiệu về PIC

Chương 1. PIC18F452
 Tính năng
RISC CPU hiệu năng cao:
Tập lệnh, cấu trúc ñược tối ưu hóa theo ngôn ngữ C
o Mã nguồn tương thích với tập lệnh PIC17 và PIC16
Địa chỉ bộ nhớ chương trình tuyến tính ñến 32 Kbytes
Địa chỉ bộ nhớ dữ liệu tuyến tính ñến 1.5 Kbytes

Hoạt ñộng lên ñến 10MIPs


o Đầu vào dao ñộng thạch anh lên ñến 40 MHz
o Đầu vào dao ñộng thạch anh với PLL: 4 MHz - 10 MHz
Lệnh rộng 16-bit, ñộ rộng bit dữ liệu: 8-bit
Hỗ trợ các cấp ưu tiên ngắt
Nhân bằng phần cứng ñơn chu kỳ 8 x 8
Tính năng ngoại vi:
Dòng phát/hút cao: 25 mA/25 mA
3 chân ngắt ngoài
Timer0 module: 8-bit/16-bit timer/counter với 8-bit ñặt tỷ lệ lập trình ñược
Timer1 module: 16-bit timer/counter
Timer2 module: 8-bit timer/counter với thanh ghi 8-bit (thời gian cơ sở cho PWM)
Timer3 module: 16-bit timer/counter
Tùy chọn xung clock thứ 2 - Timer1/Timer3
Hai bộ Capture/Compare/PWM (CCP).
Chân CCP có thể ñược cấu hình thành:
o Capture input: capture is 16-bit, max. resolution 6.25 ns (TCY/16)
o Compare is 16-bit, max. resolution 100 ns (TCY)
o PWM output: PWM resolution is 1- to 10-bit, max. PWM freq. @: 8-bit resolution =
156 kHz, 10-bit resolution = 39 kHz
Khối truyền thông nối tiếp ñồng bộ (Master Synchronous Serial Port - MSSP)
Hai chế ñộ hoạt ñộng:
o 3-dây SPI™ (Hỗ trợ cả 4 chế ñộ SPI)
o I2C™ cả chế ñộ Master và Slave
Khối USART có thể ñịnh ñịa chỉ:
o Hỗ trợ RS-485 và RS-232
Khối cổng song song (Parallel Slave Port - PSP)
Tính năng tương tự:
Khối chuyển ñổi tương tự sang số ñộ phân giải 10-bit:
o Chu kỳ lấy mẫu nhanh
o Chuyển ñổi cả trong khi ngủ
o Tuyến tính ≤ 1 LSB
Phát hiện ñiện áp thấp lập trình ñược
o Hỗ trợ ngắt khi phát hiện ñiện áp thấp
Phát hiện reset do sụt nguồn lập trình ñược (BOR)

Tính năng bộ vi ñiều khiển ñặc biệt:


100,000 chu kỳ ghi/xóa bộ nhớ chương trình FLASH
2
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
1,000,000 chu kỳ ghi/xóa bộ nhớ chương trình EEPROM
Dữ liệu tồn tại ở FLASH/Data EEPROM: > 40 năm
Lập trình lại an toàn dưới sự ñiều khiển của phần mềm
Power-on Reset (POR), Power-up Timer (PWRT) và Oscillator Start-up Timer (OST)
Watchdog Timer (WDT) với chính bộ dao ñộng On-Chip RC
Bảo vệ mã nguồn
Chế ñộ tiết kiệm nguồn
Tùy chọn tần số dao ñộng bao gồm:
o 4X Phase Lock Loop (nhân tần số lên 4 lần của bộ dao ñộng chính)
o Bộ dao ñộng thứ 2 32KHz
Lập trình ngay tại mạch (In-Circuit) chỉ với 5v qua truyền thông nối tiếp
Gỡ rối qua ICD
Công nghệ CMOS:
Công nghệ FLASH/EEPROM ñiện áp thấp, tốc ñộ cao
Thiết kế tĩnh hoàn chỉnh
Dải ñiện áp hoạt ñộng rộng (2.0V to 5.5V)
Dải nhiệt ñộ công nghiệp và mở rộng
Tiêu thụ ñiện năng thấp:
o Dòng hoạt ñộng ñặc trưng < 1.6 mA @ 5V, 4 MHz
o Dòng hoạt ñộng ñặc trưng 25 µA @ 3V, 32 kHz
o Dòng nghỉ ñặc trưng < 0.2 µA

S ñ và ý nghĩa chân

3
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Ý nghĩa các chân:
Loại
Tên Chân Loại
Bộ Giải thích
chân số IO
ñệm
MCLR 1 I ST Chân reset PIC, PIC sẽ reset khi chân này mức thấp
VPP 1 I ST Chân lập trình (nạp PIC), ngõ vào ñiện áp cao
OSC1 13 I ST Dao ñộng thạch anh ñầu vào hoặc nguồn ñầu vào ñồng hồ bên ngoài.
Bộ ñệm ST khi cấu hình trong chế ñộ RC, CMOS khác.
OSC2 14 O - Đầu ra của bộ dao ñộng thạch anh
VDD 11, 32 P Nguồn 5v cho PIC và logic 1 cho các IO
VSS 12, 31 P Mass cho PIC và các mức logic 0 cho IO
CLKI 13 I CMOS Nguồn dao ñộng từ bên ngoài vào. Luôn luôn kết hợp với chức năng
OSC1 pin. (Xem liên quan chân OSC1/CLKI, OSC2/CLKO)
CLKO 14 O - Trong chế ñộ RC, chân OSC2 xuất xung ra CLKO, trong ñó có tần số
bằng 1/4 của OSC1 và biểu thị tần số thực hiện lệnh
RAi/ANi Chân vào ra 2 chiều, cổng RA (i=0..6)
RAi … TTL Vào ra số
ANi Analog Vào tương tự (cho chuyển ñổi ADC)
VREF- 4 Analog Điện áp tham chiếu thấp cho ADC
VREF+ 5 Analog Điện áp tham chiếu cao cho ADC
SS 7 ST Đầu vào chọn Slave trong truyền thông SPI
LVDIN 7 Analog Đầu vào phát hiện ñiện áp thấp
RBi 33..40 IO TTL Đầu vào/ra hai chiều, có thể lập trình tạo ñiện trở treo (yếu)
nội(i=0..7)
INTi I ST Đầu vào ngắt ngoài (i=0..2)
CCPi IO Capture input, Compare output, PWM output. (i=1..2)
PGM 38 IO ST Chân cho phép lập trình ICSP ñiện áp thấp
PGC 39 IO ST Chân Clock khi lập trình ICSP và gỡ rối tại mạch (In-Circuit)
PGD 40 IO ST Chân dữ liệu khi lập trình ICSP và gỡ rối tại mạch (In-Circuit)
RCi IO TTL Đầu vào ra hai chiều, cổng RC (i=0..7)
T1OSO 15 O - Chân ra bộ dao ñộng timer1
T1CKI 15 I ST Dao ñộng từ ngoài vào Timer1/Timer3
T1OSI 16 I CMOS Đầu vfo bộ dao ñộng Timer1
SCK 18 IO ST Xung clock nối tiếp ñồng bộ vào/ra cho SPI
SCL 18 IO ST Xung clock nối tiếp ñồng bộ vào/ra cho I2C
SDI 23 I ST Chân dữ liệu vào trong SPI
SDA 23 IO ST Chân dữ liệu vào/ra trong I2C
SDO 24 O ST Chân dữ liệu ra trong SPI
TX 25 O - Chân truyền dữ liệu không ñồng bộ USART
CK 25 IO ST Chân xung nhịp truyền thông ñồng bộ USART
RX 26 I ST Chân nhận dữ liệu nối tiếp trong truyền thông không ñồng bộ USART
DT 26 IO ST Chân dữ liệu truyền thông ñồng bộ USART
RDi 19..30 IO ST Vào ra số cổng RD (i=0..7)
PSPi 19..30 IO TTL Dữ liệu cổng song song (Slave) (i=0..7)
REi 8..10 IO ST Vào ra số cổng RE (i=0..2)
RD 8 TTL Điều khiển ñọc cho cổng song song Slaver
WR 9 TTL Điều khiển ghi cho cổng song song Slaver
CS 10 TTL Điều khiển chọn chip trong giao tiếp song song Slaver
Trong ñó:
TTL = TTL tương thích với ñầu vào ST = Schmitt Trigger ñầu vào với mức CMOS
O = ra, I=vào P = Power
OD = Open Drain (không có diode P nối tới vdd) CMOS = CMOS compatible input or output

4
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Chương 2. Sơ ñồ tối thiểu ñể PIC có thể chạy ñược:

ICSP chip programming

5 ICSP_Data_PGD 40 1
RB7/PGD
4 ICSP_Clk_PGC 6 2 39 2
RA0/AN0 RB6/PGC
3 VPP 5 3 38 3
RA1/AN1 RB5/PGM
2 4 4 37 4
GND RA2/AN2/VREF- RB4
1 3 5 36 5
VCC RA3/AN3/VREF+ RB3/CCP2*
2 6 35 6
J1 RA4/T0CKI RB2/INT2
1 7 34 7
RA5/AN4/SS/LVDIN RB1/INT1
3 8 33 8
j2 RE0/RD/AN5 RB0/INT0
D1 R1 10k 2 9
RE1/WR/AN6 J3
1 2 1 10 26 1
VCC RE2/CS/AN7 RC7/RX/DT
25 2
J4 RC6/TX/CK
24 3
RC5/SDO
Reset1 VPP 1 23 4
GND MCLR/VPP RC4/SDI/SDA
18 5
RC3/SCK/SCL
C1 13 17 6
OSC1/CLKI RC2/CCP1
16 7
RC1/T1OSI/CCP2*
22p Y1 15 8
2

RC0/T1OSO/T1CKI
20MHz 14
OSC2/CLKO/RA6 J5
C2 30 1
RD7/PSP7
VCC 11 29 2
1

VDD RD6/PSP6
GND 32 28 3
22p VDD RD5/PSP5
27 4
RD4/PSP4
C3 C4 22 5
RD3/PSP3
VCC 22p 21 6
J6 22p RD2/PSP2
2 12 20 7
VSS RD1/PSP1
1 31 19 8
VSS RD0/PSP0
J7
Power Input
GND GND
U1 18F452 http://picat.dieukhien.net

S¬ ®å tèi thiÓu ®Ó ch¹y PIC

5
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Phần 2 Ngôn ngữ lập trình CCS cho PIC


Chương 1. Tổng quan
…………..
Chương 2. Môi trường CCS
………………..
Chương 3. Định hướng chương trình dịch

3.1. #include <filename>


Ví dụ: #include <18F452.h>
3.2. #define <Tên ñại diện> <Nội dung cần ñại diện>
Dùng ñể ñịnh nghĩa một số, một lệnh hay nhiều lệnh thành một tên.
Ví dụ:
#define Nmax 8 // Từ ñây trở ñi, dùng Nmax hay 8 là như nhau
a=a+Nmax; //như là a=a+8;

#define hi(x) (x<<4)


a=hi(a); //như là a=(a<<4);
3.3. #INT_xxxx: Chỉ dẫn ngắt
#INT_AD Chuyển ñổi AD xong Analog to digital conversion complete
#INT_BUSCOL Xung ñột BUS Bus collision
#INT_CCP1 Capture hoặc Compare 1 Capture or Compare on unit 1
#INT_CCP2 Capture hoặc Compare 2 Capture or Compare on unit 2
#INT_COMP Phát hiện so sánh Comparator detect
#INT_EEPROM Ghi xong Write complete
#INT_EXT Ngắt ngoài xảy ra External interrupt
#INT_PSP Dữ liệu vào cổng song song Parallel Slave Port data in
#INT_RB Ngắt thay ñổi bất kỳ chân nào từ RB4-7 Port B any change on B4-B7
#INT_RDA Nhận dữ liệu xong RS232 receive data available
#INT_RTCC Bộ ñịnh thời 0 tràn Timer 0 (RTCC) overflow
#INT_SSP SPI hoặc I2C SPI or I2C activity
#INT_TBE Truyền dữ liệu xong RS232 transmit buffer empty
#INT_TIMER0 Bộ ñịnh thời 0 tràn Timer 0 (RTCC) overflow
#INT_TIMER1 Bộ ñịnh thời 1 tràn Timer 1 overflow
#INT_TIMER2 Bộ ñịnh thời 2 tràn Timer 2 overflow
3.4. #use delay(clock=speed, restart_wdt)
Dùng ñể cấu hình tần số hoạt ñộng của PIC. Bắt buộc phải có.
#use delay (clock=speed)
#use delay (clock=speed, restart_wdt)
#use delay (clock=speed, type)
#use delay (clock=speed, type=speed)
#use delay (type=speed)

6
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Ví dụ:
//Clock= 32KHz, restart watchdog timer
//ñể dùng các hàm trễ: delay_us() và delay_ms()
#use delay (clock=32000, RESTART_WDT)

//Bốn ví dụ sau ñặt clock= 20Mhz


#use delay (clock=20000000) //user must manually set HS config bit
#use delay (clock=20,000,000) //user must manually set HS config bit
#use delay(clock=20M) //user must manually set HS config bit
#use delay(clock=20M, oscillator) //compiler will set HS config bit
#use delay(oscillator=20M) //compiler will set HS config bit

//Dùng thạch anh 10Mhz nhưng sử dụng bộ nhân tần lên 4 lần: 4x PLL
//Xung nhịp ñạt ñược = 40Mhz. CCS tự cấu hình, dùng cho PIC có PLL
#use delay(clock=40M, oscillator=10M)

//Dùng dao ñộng nội 8MHz. CCS tự cấu hình


#use delay(internal=8M)
Cách dùng hàm delay_xx():
delay_ms( 2 );
………………………
void delay_seconds(int n) {
for (;n!=0; n- -)
delay_ms( 1000 );
}
……………………
do { output_high(PIN_B0);
delay_us(duty);
output_low(PIN_B0);
delay_us(period-duty);
} while(TRUE);

3.5. #bit id = x.y


Dùng ñể truy cập ñến từng bít ñơn trong 1 byte.
Ví dụ:
#bit T0IF = 0xb.2
...
T0IF = 0; // Clear Timer 0 interrupt flag: Xoá cờ báo tràn Timer 0

int result;
#bit result_odd = result.0
...
if (result_odd)

7
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Chương 4. Kiểu dữ liệu
Type-Specifier Giá trị
0
int1 2 : 0-1 Defines a 1 bit number
8
int8 2 : 0-255 Defines an 8 bit number
16
int16 2 : 0-65536 Defines a 16 bit number
32
int32 2 : Defines a 32 bit number
8
char 2 ; biểu diễn ký tự Defines a 8 bit character
32
float 2 : số thực 32 bit Defines a 32 bit floating point number
short =int1 By default the same as int1
Int =int8 By default the same as int8
long =int16 By default the same as int16
void Không kiểu Indicates no specific type
Chương 5. Câu lệnh và biểu thức trong C
5.1. Câu lệnh (Statements)
Câu lệnh Ví dụ
if (expr) stmt; [else stmt;] if (x==25){x=1;}else{ x=x+1;}
while (expr) stmt; while (get_rtcc()!=0){putc(‘n’);}
do stmt while (expr); do{ putc(c=getc());}while (c!=0);
for (expr1;expr2;expr3) stmt; for (i=1;i<=10;++i)
printf(“%u\r\n”,i);
switch (expr) { switch (cmd){
case cexpr: stmt; //one or more case case 0: printf(“cmd 0”); break;
[default:stmt] case 1: printf(“cmd 1”); break;
... } default: printf(“bad cmd”);break;
}
return [expr]; return (5);
goto label; goto loop;
label: stmt; loop: I++;
break; break;
continue; continue;
expr; i=1;
; ;
{[stmt]} //Zero or more {a=1; b=1;}

5.2. Hệ thống số ñếm


Quy tắc chuyển hệ ñếm Các phép toán trên hệ thống số ñếm nhị phân:
Hệ Hệ AND 0 1 VD:
Hệ 2 AND
10 16 0 0 0
0 0 0 0 0 0 1 0 1 1001 1010
1 1 0 0 0 1 0011 0110
OR 0 1
2 2 0 0 1 0 0001 0010
0 0 1
3 3 0 0 1 1 1 1 1
4 4 0 1 0 0 OR
5 5 0 1 0 1 XOR 0 1 1001 1010
6 6 0 1 1 0 0 0 1 0011 0110
1 1 0 1011 1110
7 7 0 1 1 1
8 8 1 0 0 0 NOT
9 9 1 0 0 1 0 1
10 A 1 0 1 0 1 0
11 B 1 0 1 1 Dịch trái 1 bit: Đầu vào: C916 = 1100 10012
12 C 1 1 0 0 1 1 0 0 1 0 0 1
13 D 1 1 0 1
1 ← 1 0 0 1 0 0 1 0 ← 0
14 E 1 1 1 0
Đầu ra sau khi dịch trái 1 bit: 9216=1001 0010
15 F 1 1 1 1

8
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Chương 6. Các hàm tích hợp sẵn

6.1. Các hàm vào ra cơ bản (DESCRETE I/O)


6.1.1. SET_TRIS_X( ) : Xác ñịnh hướng 6.2. Thao tác với bit
vào/ra cho chân PIC 6.2.1. BIT_CLEAR( ): Xoá bit về =0
set_tris_a (value) trong 1 byte
set_tris_b (value) bit_clear(var, bit)
set_tris_c (value) Ví dụ:
..... int x;
Trong ñó, value là một byte (8bit) ñược x=5;
xác ñịnh vào ra theo từng bit tương ứng với
bit_clear(x,2);// x is now 1
từng chân trong cổng ñó. Mỗi bit =1/0
bit_clear(*11,7);
(1:vào/0:ra)
// A crude way to disable ints
Ví dụ:
6.2.2. BIT_SET( ): Đặt bit lên =1
SET_TRIS_B( 0x0F ); trong 1 byte
Tức là: bit_set(var, bit)
0 0 0 0 1 1 1 1 ví dụ:
=0000 11112 = 0F16 int x;
// B7,B6,B5,B4 là chân ra x=5;
// B3,B2,B1,B0 là chân vào bit_set(x,3); // x = 13
SET_TRIS_B( 0x63 ); bit_set(*6,1);
Tức là: // A crude way to set pin B1 high
0 1 1 0 0 0 1 1 6.2.3. BIT_TEST( ): kiểm tra bit =0
=0110 00112 = 6316 hay =1
// B7,B4,B3,B2 là chân ra value = bit_test (var, bit)
// B6,B5,B1,B0 là chân vào Ví dụ:
6.1.2. INPUT_X( ): Đọc cổng (1 byte) if( bit_test(x,3) || !bit_test (x,1) ){..}
value = input_a() //either bit 3 is 1 or bit 1 is 0
value = input_b() 6.2.4. ROTATE_LEFT( )
value = input_c() rotate_left (address, bytes)
.... Ví dụ:
Trả về: một byte chứa giá trị hiện tại của cổng. x = 0x86;
Ví dụ: Int8 data; rotate_left( &x, 1);
….. // x is now 0x0d
data = input_b(); 6.2.5. SHIFT_LEFT( )
6.1.3. INPUT( ): ñọc chân PIC (1 bit) shift_left (address, bytes, value)
value = input (pin) Ví dụ:
Ví dụ: byte buffer[3];
while ( !input(PIN_B1) ); for(i=0; i<=24; ++i){
// Đợi cho ñến khi B1 lên cao // Wait for clock high
if( input(PIN_A0) ) while (!input(PIN_A2));
printf("A0 ñã lên mức cao\r\n"); shift_left(buffer,3,input(PIN_A3));
6.1.4. OUTPUT_A( ): Xuất giá trị ra // Wait for clock low
cổng while (input(PIN_A2));
output_a (value)
}// reads 24 bits from pin A3,each
output_b (value)
bit is read on a low to high on pin A2
output_c (value)
.......
Xuất 1 byte ra cổng.
Ví dụ: Xuất giá trị 0xF0 ra cổng B:
OUTPUT_B(0xf0);
6.1.5. PORT_B_PULLUPS():
Kích hoạt trở treo nội cổng B
port_b_pullups(True);
port_b_pullups(FALSE);
9
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

6.3. RS232 I/O


6.3.1. #use rs232
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
Baud: Tốc ñộ bô, xác ñịnh ttốc ñộ truyền thông giữa PIC và PC
Xmit: chân phát
Rcv: Chân thu (nhận)
6.3.2. FPRINTF( )
printf (string)
hoặc
printf (cstring, values...)
hoặc
printf (fname, cstring, values...)
fprintf (stream, cstring, values...)
Ví dụ:
byte x,y,z;
printf("HiThere");
printf("RTCCValue=>%2x\n\r",get_rtcc());
printf("%2u %X %4X\n\r",x,y,z);
printf(LCD_PUTC, "n=%u",n);
Các tham số ñi kèm:
Ví dụ: Về việc sử dụng ñịnh dạng
* Không ñúng ñịnh dạng (không có kết quả).

6.3.3. GETC( ): Hàm nhận dữ liệu từ cổng RS232. Kết quả trả về: 1 byte
value = getc()
value = fgetc(stream)
value=getch()
value=getchar()
Ví dụ: Char answer;
.......
printf("Continue (Y,N)?");
do {
answer=getch();
}while(answer!='Y' && answer!='N');

6.3.4. KBHIT( ): Kiểm tra có phím bấm hay không


value = kbhit()
value = kbhit (stream)
Ví dụ:
char timed_getc() {
long timeout;
timeout_error=FALSE;
timeout=0;
while(!kbhit()&&(++timeout<50000)) // 1/2 second
delay_us(10);
if(kbhit())
return(getc());
else {
timeout_error=TRUE;
return(0);
}
}

10
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Chương 7. Ví dụ mẫu - Chỉ có tại lớp PICAT

7.1. Nháy LED ñơn

Chương trình sau minh họa việc nhấp nháy LED ñơn, dịch một ñiểm sáng từ phải sang trái. Và
cứ lặp ñi lặp lại như vậy.

Nháy LED trên cổng A: Nháy LED trên cổng D:


#include <18F452.h> #include <18F452.h>
#fuses HS,NOLVP,NOWDT,PUT #fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=8000000) #use delay(clock=8000000)
//****************************** //******************************
// main program start here // main program start here
//****************************** //******************************
void main() void main()
{ {
int8 i,count; int8 i,count;
set_tris_b(0x00);
while(TRUE) while(TRUE)
{ {
count=1; count=1;
for (i=0;i<=6;i++) for (i=0;i<=8;i++)
{ {
output_A(count); output_D(count);
delay_ms(100); delay_ms(100);
count=count<<1; count=count<<1;
} }
output_A(0xff); delay_ms(100); output_D(0xff); delay_ms(100);
output_A(0x00); delay_ms(100); output_D(0x00); delay_ms(100);
output_A(0xff); delay_ms(100); output_D(0xff); delay_ms(100);
output_A(0x00); delay_ms(100); output_D(0x00); delay_ms(100);
}} }}

11
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Nhấp nháy LED Nháy LED từ trái sang phải, phải sang trái:
#include <18F452.h> #include <18F452.h>
#use delay(oscillator=8MHz) #fuses NOWDT, XT, NOLVP
void flash_pattern_0() { #use delay(clock=4000000)// 4MHz
byte i;
byte led; byte const SHIFT_COUNT = 8;
led = 0b10000000; byte const MS = 100;
for (i = 0; i < 8; i++) {
output_b(led); void left_to_right() {
delay_ms(100); byte i, led;
led >>= 1;
} } led = 0b01000000;
for (i=0;i<SHIFT_COUNT-1;i++)
void flash_pattern_1() { {
byte i; output_b(led);
byte led; delay_ms(MS);
led = 1; led >>= 1;
for (i = 0; i < 8; i++) { }
output_b(led); }
delay_ms(100);
led <<= 1; void right_to_left() {
} } byte i, led;

void flash_pattern_2() { led = 1;


output_b(0b10000001); delay_ms(100); for (i=0;i<SHIFT_COUNT-1;i++)
output_b(0b01000010); delay_ms(100); {
output_b(0b00100100); delay_ms(100); output_b(led);
output_b(0b00011000); delay_ms(100); delay_ms(MS);
output_b(0b00100100); delay_ms(100); led <<= 1;
output_b(0b01000010); delay_ms(100); }
output_b(0b10000001); delay_ms(100); }
}
void blink() {
void flash_pattern_3() { right_to_left();
output_b(0b10000000); delay_ms(100); left_to_right();
output_b(0b01000000); delay_ms(100); }
output_b(0b10100000); delay_ms(100);
output_b(0b01010000); delay_ms(100); void main() {
output_b(0b10101000); delay_ms(100); while (true)
output_b(0b01010100); delay_ms(100); blink();
output_b(0b10101010); delay_ms(100); }
output_b(0b01010101); delay_ms(100);
output_b(0b00101010); delay_ms(100);
output_b(0b00010101); delay_ms(100);
output_b(0b00001010); delay_ms(100);
output_b(0b00000101); delay_ms(100);
output_b(0b00000010); delay_ms(100);
output_b(0b00000001); delay_ms(100);
}

void main() {
//set_tris_b(0); // set as output
output_b(0x00);
while (true)
{
flash_pattern_0();
flash_pattern_1();
flash_pattern_2();
flash_pattern_3();
}
}

12
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Mở rộng: Chương trình chạy thực tế:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tiêu ñề, phần khai báo chung cho toàn bộ chương trình
// Ngày viết: 11/04/2007, sửa chữa: 09/03/2011 23:11:22
// Tên file: All type of bling.c
// Tác giả: Nguyễn Tuấn Anh: 098.808.6099 – Giáo viên lớp PICAT
// Mục ñích viết: Làm chương trình mẫu chuẩn cho lớp PICAT
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include<18F452.h>
#Fuses HS,NOWDT,NOPUT,NOPROTECT, NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=8000000)
int16 Trai,Phai,KQ,loop,i,j,k;
////////////////////////////////////////////////////////
void lanbi(int SoLanLap){ void Cuon(int SoLanLap){
for(loop=0; loop<SoLanLap; loop++){ k=0; for(loop=0; loop<SoLanLap; loop++){
for(i=256; i>=1; i/=2){ k=i|k; Trai=0x10; Phai=0x08; KQ=0;
for(j=1; j<i; j*=2){ kq=k|j;kq=~kq; for(i=0; i<4; i++){
output_b(kq); delay_ms(100); KQ+=Trai+Phai; output_b(~KQ);
} } } } // for(j=}//for(i=//for(loop=//void delay_ms(200);Trai<<=1; Phai>>=1;
} //for(i=
void lanbi16(int SoLanLap){ int32 i,j;
for(loop=0; loop<SoLanLap; loop++){k=0; Trai=0x10; Phai=0x08; KQ=0xFF;
for(i=0x10000; i>=1; i>>=1){ k=i|k; for(i=0; i<4; i++){
for(j=1; j<i; j<<=1){ kq=~(k|j); KQ-=Trai+Phai; output_b(~KQ);
output_b(kq>>8);output_d(kq); delay_ms(200); Trai<<=1; Phai>>=1;
delay_ms(100); } } } //for(i=//for(loop=// void ////// Cuon16
} } } // for(j=}//for(i=}//for(loop=//void
void Cuon16(int SoLanLap){
void KeoLoXo(int SoLanLap){ for(loop=0; loop<SoLanLap; loop++){
for(loop=0; loop<SoLanLap; loop++){ Trai=0x8000; Phai=0x0001; KQ=0;
Trai=0x10; Phai=0x08; KQ=0; for(i=0; i<8; i++){
for(i=0; i<4; i++){ KQ+=Trai+Phai; KQ+=Trai+Phai; output_d(~(KQ>>8));
output_b(~KQ); delay_ms(200); output_b(~KQ); delay_ms(100);
Trai<<=1; Phai>>=1; Trai>>=1; Phai<<=1;
}//for(i= }//for(i=
Trai=0x80; Phai=0x01; KQ=0xFF;
for(i=0; i<4; i++){ Trai=0x8000;Phai=0x0001;KQ=0xFFFF;
KQ-=Trai+Phai; for(i=0; i<8; i++){
output_b(~KQ); delay_ms(200); KQ-=Trai+Phai; output_d(~(KQ>>8));
Trai>>=1; Phai<<=1; output_b(~KQ); delay_ms(100);
} } } //for(i=//for(loop=// void Trai>>=1; Phai<<=1;
///////////////////////////////// KeoLoXo16 } } } //for(i=//for(loop=//void

void KeoLoXo16(int SoLanLap){ void DayKeo(int SoLanLap){


for(loop=0; loop<SoLanLap; loop++){ for(loop=0; loop<SoLanLap; loop++){
Trai=0x8000; Phai=0x0001; KQ=0; Trai=0x80; Phai=0x1;
for(i=0; i<8; i++){ for(i=1; i<=8; i++){
KQ+=Trai+Phai; output_d(~(KQ>>8)); kq=Trai|Phai;output_b(~KQ);
output_b(~KQ); delay_ms(100); delay_ms(100);
Trai>>=1; Phai<<=1; Trai>>=1; Phai<<=1;
} //for(i= } } } //for(i=//for(loop=//void DayKeo
Trai=0x8000;Phai=0x0001; KQ=0xFFFF;
for(i=0; i<8; i++){
KQ-=Trai+Phai; output_B(~(KQ>>8));
output_D(~KQ); delay_ms(100);
Trai>>=1; Phai<<=1;
} } } //for(i=//for(loop=//void //////////
Cuon

13
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

void ThoThut(int SoLanLap){ void blink(int SoLanLap){


for(loop=0; loop<SoLanLap; loop++){ for(loop=0; loop<SoLanLap; loop++){
Trai=0x10; Phai=0x08; KQ=0; Output_A(0x00); Output_B(0x00);
for(i=0; i<4; i++){ Output_C(0x00); Output_D(0x00);
KQ+=Trai+Phai;output_b(KQ); Output_E(0x00); delay_ms(200);
delay_ms(200); Output_A(0xFF); Output_B(0xFF);
Trai<<=1; Phai>>=1; Output_C(0xFF); Output_D(0xFF);
}//for(i= Output_E(0xFF); delay_ms(200);
} } //for(loop= //void bling
Trai=0x80; Phai=0x01; KQ=0xFF;
for(i=0; i<4; i++){ /////////////////////////////////////////////////////
KQ-=Trai+Phai; output_b(KQ); // Chương trình chính
delay_ms(200); // Ghép từ các modul
Trai>>=1; Phai<<=1; ////////////////////////////////////////////////////
} } } //for(i= //for(loop= //void thothut
void main(){
void LanTraiPhai(int SoLanLap){ SETUP_ADC(NO_ANALOGS);
for(loop=0; loop<SoLanLap; loop++){ set_tris_A(0); set_tris_B(0);
for(Trai=0x80; Trai>0; Trai>>=1){ set_tris_C(0); set_tris_D(0);
output_b(~Trai); delay_ms(100); set_tris_E(0);
}//for(Trai= while(1){
for(Phai=0x01; Phai<0x80; Phai<<=1){ blink(3);
output_b(~Phai); delay_ms(100); LanTraiPhai(2);
} } } //for(Phai=//for(loop=//void LanTraiPhai lanbi(1);
KeoLoXo(2);
void LanTraiPhai16(int SoLanLap){ DayKeo(2);
for(loop=0; loop<SoLanLap; loop++){ ThoThut(3);
for(Trai=0x8000; Trai>0; Trai>>=1){ cuon(2);
output_B(~(Trai>>8)); LanTraiPhai16(2);
output_D(~Trai);delay_ms(100); lanbi16(1);
}//for(Trai= KeoLoXo16(2);
for(Phai=0x01; Phai<0x8000; Phai<<=1){ cuon16(2);
output_B(~(Phai>>8)); } } //while(1) //void main()
output_D(~Phai);delay_ms(100);
} } } //for(Phai=//for(loop=//void
LanTraiPhai

14
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

15
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
7.2. LED 7 thanh

Phân tích mạch:


 Mạch hiển thị LED 7 thanh ñược ghép nối 6 LED 7 thanh, chung BUS dữ liệu, chọn LED bởi các chân
RA0..RA5, qua Tranzitor A1015.
 Dữ liệu (qua mặt nạ-Mask) ñược chuyển ra cổng RB7..RB0  Seg a ... Seg h
 Điều khiển chọn LED (cổng RA), nếu muốn LED nào sáng, ta cho chân ñiều khiển tương ứng về mức 0
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
 Thuật toán và cách lập trình quét LED ñược thể hiện qua các ví dụ sau:
Đếm LED từ 00-99 Đếm LED từ 0-99 7segDisplayAB
(Đếm từ 0 ñến 99, xóa LED ñầu
(Đếm từ 00 ñến 99 rồi quay về 00 - 99) tiên, vì nó không cần thiết, rồi quay (Hiển thị 2 số bất kỳ AB trên 2 LED)
về 0 - 99)
#include <18F452.h> #include <18F452.h> #include <18F452.h>
#fuses HS, NOWDT, PUT,NOLVP #fuses HS,NOLVP,NOWDT,PUT #fuses HS,NOWDT,NOLVP
#use delay (clock=8000000) #use delay (clock=8000000) #use delay (clock=8000000)

#define LEFT_LED_C1 PIN_A0 byte const MAP[10] = { #define LED1 PIN_A0


#define RIGHT_LED_C2 PIN_A1 0xC0,0xF9,0xA4,0xB0,0x99, #define LED2 PIN_A1
0x92,0x82,0xF8,0x80,0x90 byte const DIGITS[10] = {
byte const DIGITS[] = { }; 0x3f,0x06,0x5b,0x4f,0x66,
// 0 1 2 3 4 0x6d,0x7d,0x07,0x7f,0x6f
0x3f,0x06,0x5b,0x4f,0x66, //=================== };
// this function use to
// 5 6 7 8 9
//display number 00=99 void off_on_right_transistor()
0x6d,0x7d,0x07,0x7f,0x6f
// input : {
}; // n = number to display output_low(LED2);
void off_on_right_transistor() { //=================== delay_ms(1);
output_low(RIGHT_LED_C2); void display(int n) output_high(LED2);
delay_ms(1); { }
output_high(RIGHT_LED_C2); char b;
} b=((MAP[n/10]) ^ 0x00); void off_on_left_transistor()
void off_on_left_transistor() { if ((n/10)==(0)) b=0xff; {
output_low(LEFT_LED_C1); output_d(b); output_low(LED1);
delay_ms(1); output_low(PIN_A4); delay_ms(1);
output_high(LEFT_LED_C1); delay_ms(2); output_high(LED1);
} output_high(PIN_A4); }
void display_right_led(byte digit) {
output_d(DIGITS[digit] ^ 0xff); output_d((MAP[n%10]) ^ void display_right_led(byte digit)
off_on_right_transistor(); 0x00); {
} output_low(PIN_A5); output_d(DIGITS[digit] ^ 0xff);
void display_left_led(byte digit) { delay_ms(2); off_on_right_transistor();
output_d(DIGITS[digit] ^ 0xff); output_high(PIN_A5); }
off_on_left_transistor(); }
void display_left_led(byte digit)
}
//================== {
void display(byte n) {
// main program output_d(DIGITS[digit] ^ 0xff);
byte i;
//================== off_on_left_transistor();
for (i = 0; i < 100; i++) { void main() }
display_left_led(n / 10); {
display_right_led(n % 10); int i,count; void display_ab(char a,b)
} count=0; {
} while(TRUE) display_left_led(a);
void count_00_99() { { display_right_led(b);
byte i; // dispay 50 times }
for (i = 0; i < 100; i++) for (i=0;i<=50;i++)
display(i); display(count); //=====================
} count=(count==99) ? 0: // main program
count+1; //=====================
//====================== }
// main program } void main()
//====================== {
void main() { while (true)
while (true) display_ab(8,9);
count_00_99(); }
}

17
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

LED 7 thanh: Mở rộng:

#include <16f877a.h>
#use delay(clock=8000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP

const int8 LED7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};


const int8 time=15;
int8 i,cnt,tmp, L1,L2,L3,L4;
void main()
{ SET_TRIS_b(0);SET_TRIS_C(0);
while(1){
cnt++; tmp=cnt;
L1=tmp % 10; tmp/=10;
L2=tmp % 10; tmp/=10;
L3=tmp % 10; tmp/=10;
L4=tmp % 10;
for(i=0;i<10;i++){
output_b(LED7[L1]);output_high(PIN_D0);delay_ms(time); output_low(PIN_D0);
output_b(LED7[L2]);output_high(PIN_D1);delay_ms(time); output_low(PIN_D1);
output_b(LED7[L3]);output_high(PIN_D2);delay_ms(time); output_low(PIN_D2);
output_b(LED7[L4]);output_high(PIN_D3);delay_ms(time); output_low(PIN_D3);
} } }

18
19
void main()
{ printf("Truyen thong noi tiep giua PC va PIC\n\r");
#include <18F452.h> printf("Bam phim bat ky:\n\r");
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, NoPUT while(true){ c=getc();
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

#use delay(clock=20000000) printf("Ngai da bam phim: %c\n\r",c);


#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) printf("Bam tiep di !\n\r");
char c; }}
RS232

Mô phỏng
7.3.
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
7.4. LCD
Các module sử dụng trong ví dụ Sử dụng module LCD
Rất nhiều hàm dùng ñể hiển thị lên LCD Dùng hàm ñể ñiều khiển LCD
File: PICAT_LCD.c #include <18F452.h>
(Tham khảo trong mã nguồn các ví dụ.) #fuses HS, NOLVP, NOWDT, NOPROTECT
#use delay (clock=8MHz)
//Use built-in function: delay_ms() &
delay_us()
#include "PICAT_LCD.c"
//use module function

void main(void)
{
while(true)
{
lcd_init();
lcd_gotoxy(17,1);
printf(lcd_putc, "PICAT Class");

lcd_gotoxy(18,2);
printf(lcd_putc, "Holiaco.com");

lcd_moveLeft(16);
delay_ms(500);

lcd_init();

lcd_gotoxy(5,1);
printf(lcd_putc, "The best of");

lcd_gotoxy (1,2);
printf(lcd_putc, "PIC,AVR,8051...");

delay_ms(500);
lcd_moveright(16);
}
}

20
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define use_portb_lcd TRUE


#include <lcd.c>

void main() {
lcd_init(); delay_ms(50);
while(true){
printf(lcd_putc,"\fPICAT Class"); delay_ms(1000);
printf(lcd_putc,"\fWhere "); delay_ms(500);
printf(lcd_putc,"\n Start your job"); delay_ms(1000);
}
}

21
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
7.5. Chuyển ñổi ADC
Chuyển ñổi ADC hiển thị lên Chuyển ñổi ADC – Truyền thông
LED
(Đọc ADC hiển thị ra LED trên cổng B) (Đọc ADC rồi truyền lên máy tính thông qua cổng RS232)
#include <18F452.h> #include <18F452.h>
#device ADC=8 #device ADC=10 // 10 bits ADC
#use delay(oscillator=8000000) #use delay(clock=8MHz)
#fuses HS, NOWDT, NOPROTECT, NOLVP
void main() #use rs232(baud=9600, xmit=PIN_C7, rcv=PIN_C6, stream=MYPC)
// rs232 setting
{
#define DO_NOTHING 0
setup_adc(adc_clock_internal); #define DO_START_ADC 1
setup_adc_ports(ALL_ANALOG); #define DO_END_ADC 2
set_adc_channel(2); //ñặt kênh void main(void) {
// EasyPIC Board: int16 int_volt;
// VR P1=RA2, int8 str_volt[21], tmp;
// VR P2=RA3 float flt_volt;
delay_ms(10); int8 do_what = DO_NOTHING;
set_tris_b(0x00); printf( "S: Start ADC\n\r");
while (true) Printf( "Q: END ADC\n\r");
while(true){
output_b(read_adc());
if(0 != kbhit()){ // if rs232 get char
} tmp = fgetc(MYPC);
switch(tmp) {
case 'S':
case 's':
printf( "S: Start ADC\n\r" );
do_what = DO_START_ADC;
setup_adc_ports(RA0_RA1_RA3_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(3);
break;
case 'Q':
case 'q':
printf( "Q:EndADC\n\r" );
do_what = DO_END_ADC;
// adc off
setup_adc(ADC_OFF);
break;
default : // rs232 get other char
putc(tmp);
break;
}//end switch(tmp)
}//end if(kbhit())
switch(do_what) {
case DO_START_ADC:
// start adc and send result to PC
int_volt = read_adc();
flt_volt = 5.0 * int_volt / 0x3ff;
sprintf(str_volt, "ADC: %1.3fV\n\r", flt_volt);
printf(str_volt);
printf( "\n\r" );
delay_ms(500);
break;
case DO_END_ADC: break;// you want to do
case DO_NOTHING: break;// you want to do
default:
} } }//end switch(do_what) //end while(1) //end main()

22
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
7.6. I2C và Thời gian thực
EasyPIC sử dụng real time clock DS1307 giao tiếp chuẩn I2C. 2 chân SCL và SDA nối
với RC3 và RC4. có thể tách rời hoặc kết nối qua DIPSW. Pin backup nằm bên dưới LCD
dùng ñể lưu dữ liệu cho DS1307 khi ngắt nguồn ngoài VCC.

Địa chỉ của DS1307:


 Khởi tạo ghi là 0xD0
 Khởi tạo ñọc là 0xD1
 Bản ñồ ñịa chỉ cho dữ liệu như sau:

23
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
 Giản ñồ truyền dữ liệu:

 Cấu trúc ghi dữ liệu:

 Cấu trúc ñọc dữ liệu:

 Thanh ghi ñiều khiển

OUT (Output control): Bit này ñiều khiển mức của chân SQW/OUT khi ñầu ra sóng vuông là vô
hiệu. Nếu SQWE = 0, mức logic trên chân SQW /OUT là 1 nếu OUT = 1 và là 0 nếu OUT = 0.

SQWE (Square Wave Enable): Bit này, khi thiết lập một logic 1, sẽ cho phép ñầu ra dao ñộng.
Các tần số của ñầu ra sóng vuông phụ thuộc vào giá trị của các bit RS0 và RS1. Với ñầu ra sóng
vuông là 1Hz, các thanh ghi clock cập nhật trên các cạnh thuộc của sóng vuông.

RS (Rate Select): Các bit này ñiều khiển ñầu ra của sóng vuông khi bit ñiều khiển xung vuông ra
ñược cho phép. Bảng sau thiết lập mức ra của xung:

24
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
Ví dụ áp dụng:
Module thời gian thực Đọc giờ và hiển thị
(Các module khởi tạo, ghi, ñọc thời gian trên DS1307) (Đọc giờ từ DS1307 rồi hiển thị lên máy tính qua RS232 )
File: ds1307.c #include <18F452.h>
#define DS1307_SDA PIN_C4 #use delay(clock=4000000)
#define DS1307_SCL PIN_C3 #fuses xt,NOWDT,NOPROTECT,NOLVP
#use #use rs232(baud=9600, xmit=PIN_C7, rcv=PIN_C6)
i2c(master,sda=DS1307_SDA,scl=DS1307_SCL) #include "ds1307.c"
//==========================
// initial DS1307 void main(void)
//========================== {
void init_DS1307() int8 sec,min,hour,day,date,month,year;
{
output_float(DS1307_SCL); delay_ms(50);
output_float(DS1307_SDA); init_ds1307(); // initial DS1307
} sec=read_ds1307(0);
//========================== write_ds1307(0,sec & 0x7F); // enable oscillator(bit 7 =0)
// write data one byte to
// DS1307 while(true)
//========================== {
void write_DS1307(byte address, BYTE data) sec=read_ds1307(0); // read second
{ min=read_ds1307(1); // read minute
short int status; hour=read_ds1307(2); // read hour
i2c_start(); day=read_ds1307(3); // read day
i2c_write(0xd0); date=read_ds1307(4); // read date
i2c_write(address); month=read_ds1307(5); // read month
i2c_write(data); year=read_ds1307(6); // read year
i2c_stop(); putc(0x0c);
i2c_start(); printf("Time : %02X:%02X:%02X\r\n",hour,min,sec);
status=i2c_write(0xd0); printf("Day : %02X\r\n",day);
while(status==1) printf("Date : %2X/%2X/20%2X\r\n",date,month,year);
{ printf("----------------------------------- \n");
i2c_start(); delay_ms(5000);
status=i2c_write(0xd0); }
} }
}
//==========================
// read data one byte from DS1307
//==========================
BYTE read_DS1307(byte address)
{
BYTE data;
i2c_start();
i2c_write(0xd0);
i2c_write(address);
i2c_start();
i2c_write(0xd1);
data=i2c_read(0);
i2c_stop();
return(data);
}

25
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

7.7. Truyền thông 1 dây và bài toán ño nhiệt ñộ DS1820


DS1820 là IC c m bin nhit ñ dng s (digital thermometer) r#t tt cho vic ño nhit ñ
môi tr&'ng, phm vi nhit ñ rng -55°C ñn 125°C v-i ñ chính xác +/-0.5°C. Nó ph i
ñ&6c ñ7t chính xác trong socket 3 pin, và biên c;a nó ph i trùng v-i hình v> in trên
EasyPIC. Nu không DS1820 có thC bD h&. Chân data c;a DS1820 có thC ni t-i pin
RA5 ho7c RE2 c;a microcontroller bHi jumper JP14.

26
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Module truyền thông 1 dây Module ñọc nhiệt ñộ Đọc và hiển thị nhiệt ñộ
Theo datasheet của DS1820,
(Truyền thông giữa cảm biến nhiệt và PIC dùng hàm truyền thông một dây Sử dụng các hàm trong module trên,
chỉ bằng một bit tín hiệu) ñể ñọc nhiệt ñộ ñọc và hiển thị nhiệt ñộ lên LCD
Tham khảo datasheet DS1820
File: 1wire.c File: DS1820.c #include <18F452.h>
/*------- Định nghĩa chân -------*/ float ds1820_read() { #device adc=8
#define OWPIN PIN_E2 int8 busy=0, temp1, temp2; #use delay(OSCILLATOR =8MHz)
signed int16 temp3;
/*-----Truyền thông 1 dây------*/ float result; #include <1wire.c>
#include < PICAT_LCD.c>
void onewire_reset() { onewire_reset(); #include <ds1820.c>
output_low(OWPIN); delay_us( 500 ); onewire_write(0xCC);
output_float(OWPIN); delay_us( 500 ); onewire_write(0x44);
output_float(OWPIN); void main()
} while (busy == 0) {
busy = onewire_read(); float Ndo;
/* ******* onewire_write() **/
/*Ghi 1 byte vào cảm biến.*/ onewire_reset(); setup_adc_ports(NO_ANALOGS);
onewire_write(0xCC); setup_adc(ADC_OFF);
void onewire_write(int data) { onewire_write(0xBE);
int count; temp1 = onewire_read(); lcd_init();
for (count=0; count<8; ++count){ temp2 = onewire_read(); lcd_putc("\f");
output_low(OWPIN); temp3 = make16(temp2,
delay_us( 2 ); temp1); while (TRUE) {

output_bit(OWPIN,shift_right(&data,1,0 // result = (float) temp3 / 2.0; Ndo = ds1820_read();


)); // Calculation for DS18S20
delay_us( 60 ); // with 0.5 deg C resolution lcd_gotoxy(1,1);
output_float(OWPIN); printf(lcd_putc,"ND: %3.1f ",
delay_us( 2 ); result = (float) temp3 / 16.0; Ndo);
}} lcd_putc(223);
//Calculation for DS18B20 lcd_putc("C ");
/*** read1wire() ****/ // with 0.1 deg C resolution
/*Trả về: 8-bit (1-byte) lcd_gotoxy(1,2);
dữ liệu từ cảm biến */ delay_ms(200); if(Ndo >= 30)
return(result); printf(lcd_putc,"Hot! ");
int onewire_read() { } else if( Ndo >= 20 && Ndo < 30)
int count, data; printf(lcd_putc,"Comfort!");
else
for (count=0; count<8; ++count) printf(lcd_putc,"Cold! ");
{
output_low(OWPIN); }
delay_us( 2 ); }
output_float(OWPIN);
delay_us( 8 );
shift_right(&data,1,input(OWPIN));
delay_us( 120 );
}
return( data );
}

27
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
7.8. Mở rộng: LED ma trận

const char Nmax=10;


const char mf[Nmax]={0xf8,0xfc,0x12,0x11,0x11,0x12,0xfc,0xf8,0x00},
DT=1;
Int8 i,j,Dau,cnt;
void main()
{SET_TRIS_B(0);SET_TRIS_D(0); // portb=portd=trisb=trisd=0;

Dau=cnt=0;
while(1)
{ j=128;
if(++cnt==20){Dau=(Dau+1)%Nmax;cnt=0;}
for(i=7;i>=0;i--){
output_d(~mf[(Dau+i)%Nmax]);
output_b(j); j/=2;
delay_ms(DT);
output_b(0);
} } }

28
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

7.9. Mở rộng: Nút bấm

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define use_portb_lcd TRUE


#include <lcd.c>

void main() {
set_tris_d(0xff);
lcd_init(); delay_ms(50);
while(true){
printf(lcd_putc,"\fAn nut Start!"); while(!input(PIN_D0));
printf(lcd_putc,"\nAn nut More!"); while(!input(PIN_D2));
printf(lcd_putc,"\fAn nut Clear"); while(input(PIN_D5));
printf(lcd_putc,"\nAn nut Again!"); while(input(PIN_D7));
}
}

29
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

7.10. Mở rộng: PWM

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)

void main() {
char selection;
byte value;
printf("\r\nFrequency:\r\n");
printf(" 1) 19.5 khz\r\n");
printf(" 2) 4.9 khz\r\n");
printf(" 3) 1.2 khz\r\n");
do {
selection=getc();
} while((selection<'1')||(selection>'3'));
setup_ccp1(CCP_PWM);
switch(selection) {
case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1); break;
case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1); break;
case '3' : setup_timer_2(T2_DIV_BY_16,127, 1);break;
}
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
set_adc_channel( 0 );
printf("%c\r\n",selection);
while( TRUE ) {
value=read_adc();
printf("%2X\r",value);
set_pwm1_duty(value);
}
}

30
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Chương 8. Viết và Dịch chương trình cơ bản (cho người mới học):
Chương trình C tối thiểu không lỗi. Dùng ñể test CCS:

//Cách viết không có chương trình con:


//Hoặc cách viết có chương trình con:
#include <16F877A.h> #include <16F877A.h>
#use delay(oscillator=20M) #use delay(oscillator=20M)

void main() void ctc1() {.....}


{ void main()
} {....; ctc1(); ...;
While(true){
....;
ctc1();
.....;
}
}

Trong CCS, Click chuột phải, chọn Make Project, bấm F9 hoặc Click chuột phải chọn Complier ñể
dịch chương trình ra file .Hex
Khi thấy không có lỗi là ổn. Hình sau là kết quả của chương trình trên:

31
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Chương 9. Một số cổng giao tiếp, linh kiện, thiết bị cần tìm hiểu
trong quá trình học :

9.1. Cổng song song (LPT): ñịa chỉ ? chân vào/ra?


Địa chỉ ? chân vào/ra?, cách xuất/ nhập dữ liệu?

9.2. Cổng nối tiếp (RS232)


Địa chỉ ? chân vào/ra?, cách xuất/ nhập dữ liệu?

9.3. Một số ký hiệu các linh kiện


1. VCC +12V Nguồn nuôi dương Vcc: mặc ñịnh 5v

2. Nguồn nuôi âm mặc ñịnh 0v

Y5
3. Thạch anh Tạo dao ñộng cho VĐK
32.768 KHz
4. R33 R1
Điện trở
1,2K 10k

5. Biến trở Biến trở do con người hay


R109 R13
50k môi trường (Cảm biến,
5k loadcell,..)
VR

32
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
6. D12 Diode Chỉ cho dòng ñiện ñi theo 1
chiều
DIODE
1

7. Diode cầu Tích hợp sẵn 4 con diode


4 - + 2
ñược bố trí chân như hình
bên
D2 3

8. Diode quang, LED Phát sáng, có nhiêềuloại


ñơn màu, Đỏ, xanh, vàng,...
D8 LED7 Don
9. Led 7 thanh Bố trí 7 con LED ñơn vào 7
A
3
8 A1 vị trí của số 8, và 1 dấu
A2
F B
chấm. Có thể hiện thị các số,
G một vài chữ. Có cả dấu chấm
E D C
thập phân
H
G
C
D

H
A
B

E
F
4
5
7
9
10
2
1
6

U3
10. LED thu hồng ngoại
LDR

11. Tụ phân cực, ñầu Nhiều trị số ñiện dung khác


+ C28
thẳng là dương nhau, ghi trên vỏ
10uF

12. Tụ k0 phân cực Cắm ñầu nào cũng thế


13. Nút bấm Loại thường mở
14. 1 1
Header Đầu cắm mở rộng
2 2
3

15. 2 Tranztor ngược B=1:Vc => VE


1 Q13
B=0:Vc k0 chảy sang VE
3
2
16. Q14
Tranztor thuận B=0:VE => Vc
1
3 B=1:VE k0 chảy sang Vc
17. BT2
PIN Nguồn phụ
BATTERY

18. 1
2 Transmit+ Sơ ñồ chân cổng
3 Transmit- 8 RJ45
4 Receiv e+ 7
6
N/A1
5
N/A2 45
6 3
Receiv e- 2
7 1
8 N/A3
N/A4
L1

19. 3
Cuộn dây
1
S

LS3
20. Rơ le Loại này có 8 chân.
8
6
7
1,2: chân ñiều khiển
3
4 3,6: chân chung
1
5
4,8: thường ñóng với 3,6
2
5,7:thường mở với 3,6
20-2051-DPDT
2

21. Thu phát hồng ngoại Tích hợp sẵn cả thu và phát
ISO1
3N263
khoảng cách gần
4

22. ñiện trở dãy


1
2
3
4
5
6
7
8
9
10

33
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
23. D614 Diode zenner ổn áp, tuỳ thuộc vào trị số
của zenner
BZX84C10/SOT

24. F1 Cầu chì


FUSE/SM

25. Ma trận LED hoặc


ma trận nút bấm. :
Ma trận nút bấm

:
Ma trận LED
D615

9.4. Vi mạch phân kênh 74 138

9.5. Vi mạch phân kênh 74 154

34
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
9.6. Vi mạch chọn kênh 74 151

9.7. Thanh ghi dịch 74 595

9.8. Vi mạch chốt ñệm 74 573

35
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.
9.9. Vi mạch ñệm dữ liệu 74 245

9.10. Mạch khuếch ñại công suất


Khi dùng các tải lớn, cần các mạch khuếch ñại như hình sau,
Đầu vào: Din: “Điều khiển tín hiệu nhỏ”:
Đầu ra: Dout: chân âm của “Tải công suất lớn”
Diễn giải:
- Chân GND nối với GND của PIC
- Chân Din nối với một chân IO của PIC, nếu chân này = 0  Dout = GND,
nếu chân này =1: Dout ở mức 1 yếu
- Giả sử muốn nối Rowle hay ñộng cơ, ta sẽ mắc tại chỗ “Tải công suất lớn”

9.11. Động cơ và nguyên tắc ñiều khiển ñộng cơ


Mạch lực ñiều khiển ñộng cơ, có thể làm theo mạch như thế này:
Phương pháp ñiều khiển là: Pic ñiều khiển PWM ñưa vào chân Moto_PWM1, chân GND_Moto nối
vào 1 chân của ñộng cơ, chân còn lại của ñộng cơ nối lên +VDD của ñộng cơ.
Các linh kiện, có thể thay thế tương ñương.

36
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Mục lục
Phần 1: Giới thiệu về PIC ..........................................................................................................2
Chương 1. PIC18F452........................................................................................................ 2
Chương 2. Sơ ñồ tối thiểu ñể PIC có thể chạy ñược: ......................................................... 5
Phần 2 Ngôn ngữ lập trình CCS cho PIC .............................................................................6
Chương 1. Tổng quan......................................................................................................... 6
Chương 2. Môi trường CCS ............................................................................................... 6
Chương 3. Định hướng chương trình dịch ......................................................................... 6
3.1. #include <filename> ............................................................................................. 6
3.2. #define <Tên ñại diện> <Nội dung cần ñại diện> ............................................. 6
3.3. #INT_xxxx: Chỉ dẫn ngắt ...................................................................................... 6
3.4. #use delay(clock=speed, restart_wdt) .................................................................... 6
3.5. #bit id = x.y ........................................................................................................... 7
Chương 4. Kiểu dữ liệu ...................................................................................................... 8
Chương 5. Câu lệnh và biểu thức trong C.......................................................................... 8
Chương 6. Các hàm tích hợp sẵn ....................................................................................... 9
6.1. Các hàm vào ra cơ bản (DESCRETE I/O)............................................................. 9
6.2. Thao tác với bit ...................................................................................................... 9
6.3. RS232 I/O ............................................................................................................ 10
Chương 7. Ví dụ mẫu - Chỉ có tại lớp PICAT .............................................................. 11
7.1. Nháy LED ñơn ..................................................................................................... 11
7.2. LED 7 thanh ......................................................................................................... 16
7.3. RS232................................................................................................................... 19
7.4. LCD...................................................................................................................... 20
7.5. Chuyển ñổi ADC.................................................................................................. 22
7.6. I2C và Thời gian thực .......................................................................................... 23
7.7. Truyền thông 1 dây và bài toán ño nhiệt ñộ DS1820........................................... 26
7.8. Mở rộng: LED ma trận......................................................................................... 28
7.9. Mở rộng: Nút bấm................................................................................................ 29
7.10. Mở rộng: PWM .................................................................................................... 30
Chương 8. Viết và Dịch chương trình cơ bản (cho người mới học): ............................... 31
Chương 9. Một số cổng giao tiếp, linh kiện, thiết bị cần tìm hiểu trong quá trình học : . 32
9.1. Cổng song song (LPT): ñịa chỉ ? chân vào/ra? .................................................... 32
9.2. Cổng nối tiếp (RS232) ......................................................................................... 32
9.3. Một số ký hiệu các linh kiện ................................................................................ 32
9.4. Vi mạch phân kênh 74 138 .................................................................................. 34
9.5. Vi mạch phân kênh 74 154 .................................................................................. 34
9.6. Vi mạch chọn kênh 74 151 .................................................................................. 35
9.7. Thanh ghi dịch 74 595 ......................................................................................... 35
9.8. Vi mạch chốt ñệm 74 573 .................................................................................... 35
9.9. Vi mạch ñệm dữ liệu 74 245 ................................................................................ 36
9.10. Mạch khuếch ñại công suất.................................................................................. 36
9.11. Động cơ và nguyên tắc ñiều khiển ñộng cơ ......................................................... 36

37
PICAT Class 098.808.6099 – Trung tâm dạy Lập trình cho các loại vi ñiều khiển.

Danh mục những sản phẩm thực tế tham khảo:


1. Bảng quảng cáo nháy chữ
2. Bảng quảng cáo ñiện tử (Bảng quang báo, LED ma trận)
3. Đồng hồ + lịch vạn niên
4. Hệ thống ổn ñịnh nhiệt ñộ (gia ñình, lò cao,…)
5. Hệ thống ñiều khiển từ xa (Truyền dữ liệu không dây, ñiều khiển máy tính, các thiết bị ñiện
gia ñình từ xa,…)
6. Bật tắt ñèn thông minh (người vào phòng,nếu phòng sáng: không làm gì, phòng tối: tự bật
ñèn,…)
7. Làm bộ ñiều khiển trung tâm cho RoBot
8. Ổn ñịnh tốc ñộ ñộng cơ
9. Làm bộ ñiều khiển hệ thống cân băng ñịnh lượng
10. Làm máy cuốn thép sau cán, máy cắt gạch,…
11. Trạm trộn bê tông
12. Đếm sản phẩm của 1 nhà máy, xí nghiệp,…
13. Máy vận hành tự ñộng (dạng CNC)
14. Thiết bị lưu trữ dữ liệu di ñộng (dạng ổ USB)
15. Cửa tự ñộng
16. Hệ thống tự ñộng khóa cửa có hẹn giờ
17. Thang máy
18. Hệ thống an ninh (phát hiện trộm vào nhà)
19. Đèn hiệu giao thông
20. Hệ thống vệ sinh thông minh
21. Hệ thống báo giờ, báo chuông tự ñộng cho các trường học, cơ quan, nhà máy, xí nghiệp,…
22. …… .............................................................................................................................................
23. . ....................................................................................................................................................
24. .. ...................................................................................................................................................
25. .. ...................................................................................................................................................
26. .. ...................................................................................................................................................
27. .. ...................................................................................................................................................
...............................................................................................................................................................

38

You might also like