You are on page 1of 27

CÁC LỆNH TRUY XUẤT PORT

Với x: A, B, C, D, E (B, C, D đủ 8
bit)
output_x(value);
Value: 0x45, 0b01000101,
256
Xuất giá trị đi xuống ở 1 chân nào
output_low(pin_xi); đó.
pin_xi: với x từ A – E và i từ 0 – 7
output_high(pin_xi); Xuất giá trị đi lên ở 1 chân nào đó
VD: output_bit(pin_B3, 1)
output_bit(pin, value);
Xuất ra chân B3 giá trị là 1
x: từ A – E
set_tris_x(value);
value: từ 0x00 đến 0Xff
get_tris_x( ); Đọc giá trị của thanh ghi
Đọc giá trị của port tương ứng
input_x( );
x: từ A đến E
Đọc giá trị trên 1 chân của PIC
input(pin_xi);
pin_xi: với x từ A – E và i từ 0 – 7
Đảo giá trị trước đó của chân
output_toggle(pin_xi);
VD: output_toggle(pin_D0);
delay_ms(value); Thời gian để hiển thị giá trị
delay_us(value);
CÁCH TÍNH GIÁ TRỊ NẠP CHO TIMER:
- Chu kỳ đi vào Timer 0:
1 1
𝑇𝑇𝑖𝑚𝑒𝑟0 = =
𝑓𝑇𝑖𝑚𝑒𝑟0 𝑓𝑂𝑆𝐶 /4/𝑋
Với X: bộ chia trước
- Chu kỳ của xung cần tạo ra:
1
𝑇𝑥𝑢𝑛𝑔 =
𝑓𝑥𝑢𝑛𝑔
𝑇𝑥𝑢𝑛𝑔
𝑇𝑜𝑛 = 𝑇𝑜𝑓𝑓 =
2
- Giá trị nạp cho Timer 0:
𝑇𝑜𝑛
𝑁 = 𝟐𝟓𝟔 −
𝑇𝑇𝑖𝑚𝑒𝑟0

 Timer0 8 bit nên 28 = 256


 Timer1 16 bit nên 216 = 65536

TIMER/COUNTER 0
- Timer 8 bit
- Chỉ có bộ chia trước 8 bit

TIMER/COUNTER 2
- Có 2 bộ chia: chia trước và chia sau
o Bộ chia trước: chia 1, 4, 16
o Bộ chia sau: từ 1 đến 16

CÁC LỆNH CỦA TIMER


setup_timer_0(mode); - Mode:
o rtcc_internal: xuất xung trong
o rtcc_ext: xuất xung ngoài
o rtcc_ext_l/h_to_h/l
o rtcc_div_2/4/8/16/64
setup_timer_1(mode); - Mode:
o T1_disable: ko hoạt động
o T1_internal/external
o T1_internal_sync: đồng bộ
o Tc_clk_out: xuất xung ra ngoài
o T1_div_by_1/2/4/8
setup_timer_2(mode, period, postsale); - Mode:
o T2_disable: ko hoạt động
o T2_div_by_1/4/16
- Period: 0 → 255
- Postsale: 1 → 16
set_timerX(value); - Đặt giá trị cho Timer
get_timerX(); với X là loại timer

BÀI 1:
Thạch anh là 10MHz, viết chương trình hiển thị xung vuông với f = 5KHz truyền vào
PORT A (RA0). Sử dụng Timer 0 trong chế độ 8 bit với hệ số chia trước là 64

- Chu kỳ đi vào Timer 0:


1 1 256
𝑇𝑇𝑖𝑚𝑒𝑟0 = = = = 25,6 (𝜇𝑠)
𝑓𝑇𝑖𝑚𝑒𝑟0 𝑓𝑂𝑆𝐶 / 4 / 64 10𝑀𝐻𝑧
- Chu kỳ của xung cần tạo ra:
1 1
𝑇𝑥𝑢𝑛𝑔 = = = 0,2 (𝑚𝑠) = 200 (𝜇𝑠)
𝑓𝑥𝑢𝑛𝑔 5 × 103
𝑇𝑥𝑢𝑛𝑔 200
𝑇𝑜𝑛 = 𝑇𝑜𝑓𝑓 = = = 100 (𝜇𝑠)
2 2
- Giá trị nạp cho Timer 0:
𝑇𝑜𝑛 100
𝑁 = 256 − = 256 − = 252
𝑇𝑇𝑖𝑚𝑒𝑟0 25,6
Chương trình (cách 1):
#include <18F458.h>
#FUSES NOWDT, HS, NOPROTECT

#bit TMR0IF = 0x0b.2


int dem = 0;

void main()
{

set_tris_A(0x00);

setup_timer_0(rtcc_internal|rtcc_div_64);
set_timer0(252);
while(true)

if(TMR0IF == 1)

dem++;

set_timer0(252);

TMR0IF = 0;

if(dem == 1)
{

output_high(pin_A0);

if(dem == 2)

{
output_low(pin_A0);

dem = 0;
}

}\\if

}\\while
}\\main
Chương trình (cách 2: áp dụng khi Ton = Toff):
#include <18F458.h>
#FUSES NOWDT, HS, NOPROTECT

#bit TMR0IF = 0x0b.2

int dem = 0;
void main()
{

set_tris_A(0x00);

setup_timer_0(rtcc_internal|rtcc_div_64);

set_timer0(252);

while(true)

if(TMR0IF == 1)

{
output_toggle(pin_A0);

set_timer0(252);

TMR0IF = 0;

}
}

Nếu f = 5Hz:
- Chu kỳ đi vào Timer 0:
1 1 256
𝑇𝑇𝑖𝑚𝑒𝑟0 = = = = 25,6 (𝜇𝑠)
𝑓𝑇𝑖𝑚𝑒𝑟0 𝑓𝑂𝑆𝐶 / 4 / 64 10𝑀𝐻𝑧
- Chu kỳ của xung cần tạo ra:
1 1
𝑇𝑥𝑢𝑛𝑔 = = = 200 000 (𝜇𝑠)
𝑓𝑥𝑢𝑛𝑔 5
𝑇𝑥𝑢𝑛𝑔 200 000
𝑇𝑜𝑛 = 𝑇𝑜𝑓𝑓 = = = 100 000 (𝜇𝑠)
2 2
- Giá trị nạp cho Timer 0:
𝑇𝑜𝑛 100 000
𝑁 = 256 − = 256 − = 3650 > 256
𝑇𝑇𝑖𝑚𝑒𝑟0 25,6

Nên giảm 𝑇𝑜𝑛 = 1000 (𝜇𝑠)

Vậy giá trị nạp cho Timer 0 là:


𝑇𝑜𝑛 1000
𝑁 = 256 − = 256 − = 217
𝑇𝑇𝑖𝑚𝑒𝑟0 25,6

 Thay N = 217 vào giá trị nạp cho Timer trong chương trình trên

Chương trình 1:
set_timer0(252); → set_timer0(217);

if(dem == 1) → if(dem == 100)

if(dem == 2) → if(dem == 200)


BÀI 2:
Viết chương trình truyền ký tự ‘G’ vào bộ nối tiếp với paud = 9600. Tần số thạch anh là
10MHz

Chương trình:
#include <18F458.h>

#use RS323 (baud = 9600, parity = N, xmit = pin_C6, rev = pin_C7)


#FUSES NOWDT, HS, Noprotect

#use delay (clock = 10M)

char kytu;

void main()

while(true)

putchar('G');

delay_ms(100);

}
}

BÀI 3:
Viết chương trình truyền các số từ 0 – 100 ra port nối tiếp. Tốc độ paud = 4800. Thạch
anh là 16MHz

Chương trình: (giống bài 12)

BÀI 4: (giống bài 13)


Viết chương trình nhận ký tự từ port nối tiếp, paud = 9600, XTAL = 20MHz
a. Ký tự nhận được là 1 thì hiển thị từ 0 – 98
b. Ký tự nhận được là 2 thì hiển thị 1 – 99
ADC
- Độ phân giải: 10 bit
BÀI 5:
Viết chương trình lấy dữ liệu từ kênh 0 (RA0) của ADC và hiển thị kết quả lên port C và
port D. Thực hiện mỗi 0,25s.

Chương trình:
#include <18F458.h>

#FUSES NOWDT, HS, Noprotect


#use delay (clock = 20M)

#device ADC = 10

int byte_high, byte_low;

int1 ktra;

int16 value;

void main()

set_tris_C(0x00);

set_tris_D(0x00);

set_tris_A(0xFF);
setup_adc(adc_clock_internal);

setup_adc_ports(AN0);

set_adc_channel(0);

delay_us(20);

while(true)

{
ktra = adc_done();
while(ktra == 0)

{
ktra = adc_done();

}
value = read_ADC();

byte_high = value/256;

byte_low = value%256;
output_C(byte_high);
output_D(byte_low);

delay_ms(250);

}
BÀI 6:

Chương trình:
Thạch anh: fOSC = 12MHz

Giả sử N nạp cho Timer 0 là 50 (Vào thi thì phải tính N nạp cho Timer)

#include <18F458.h>
#FUSES NOWDT, HS, Noprotect

#use delay (clock = 12M)


#int_timer0
int status;

void ngat_timer0()

{
output_toggle(pin_B5);

set_timer0(50);
}
void main()
{

set_tris_C(0xFF);
set_tris_D(0x00);

setup_timer0(rtcc_internal|rtcc_div_64 [64 là đề cho hoặc tự cho]);

enable_interrupts(global);
enable_interrupts(int_timer0);
set_timer0(50);

while(true)

status = input_C();

output_D(status);

BÀI 7:
Viết chương trình tạo ra xung 2KHz ở chân RB0. Biết chu kỳ nhiệm vụ là 20%, thạch
anh sử dụng là 16MHz. Sử dụng Timer0 chế độ 8 bit, hệ số chia là 32.

- Chu kỳ đi vào Timer0:


1 1
𝑇𝑇𝑖𝑚𝑒𝑟0 = = = 8 (𝜇𝑠)
𝑓𝑇𝑖𝑚𝑒𝑟0 𝑓𝑂𝑆𝐶 /4/32
- Chu kỳ xung cần tạo ra:
1 1
𝑇𝑥𝑢𝑛𝑔 = = = 0,5 (𝑚𝑠) = 500 (𝜇𝑠)
𝑓𝑥𝑢𝑛𝑔 2 × 103
𝑇𝑥𝑢𝑛𝑔 500
𝑇𝑜𝑛 = = = 100 (𝜇𝑠)
5 5
- Giá trị nạp cho Timer0:
𝑇𝑜𝑛 100
𝑁 = 256 − = 256 − = 243
𝑇𝑇𝑖𝑚𝑒𝑟0 8
Chương trình:

#include <18F458.h>

#FUSES NOWDT, HS, Noprotect


#use delay (clock = 16M)

#bit TMR0IF = 0x0b.2

int dem;

void main()
{

set_tris_B(0x00);

setup_timer0(rtcc_internal|rtcc_div_32);

set_timer0(243);
while(true)

{
if(TMR0IF == 1)

dem++;
TMR0IF = 0;
set_timer0(243);

if(dem == 1)
{
output_low(pin_B0);

}
if(dem == 5)
{

output_high(pin_B0);
dem = 0;

}\\if
}\\while
}\\void

BÀI 8:
Viết chương trình tạo ra xung 10Hz ở chân RB0. Biết chu kỳ nhiệm vụ là 20%, thạch anh
sử dụng là 16MHz. Sử dụng Timer0 chế độ 8 bit, hệ số chia là 32.

- Chu kỳ đi vào Timer0:


1 1
𝑇𝑇𝑖𝑚𝑒𝑟0 = = = 8 (𝜇𝑠)
𝑓𝑇𝑖𝑚𝑒𝑟0 𝑓𝑂𝑆𝐶 /4/32
- Chu kỳ xung cần tạo ra:
1 1
𝑇𝑥𝑢𝑛𝑔 = = = 100 000 (𝜇𝑠)
𝑓𝑥𝑢𝑛𝑔 10
𝑇𝑥𝑢𝑛𝑔 100 000
𝑇𝑜𝑛 = = = 20 000 (𝜇𝑠)
5 5
- Giá trị nạp cho Timer0:
𝑇𝑜𝑛 20 000
𝑁 = 256 − = 256 − = 2244
𝑇𝑇𝑖𝑚𝑒𝑟0 8

 Giảm Ton: 𝑇𝑜𝑛 = 1000 (𝜇𝑠)


𝑇𝑜𝑛 1000
⇒ 𝑁 = 256 − = 256 − = 131
𝑇𝑇𝑖𝑚𝑒𝑟0 8
Chương trình:
Tương tự như Bài 7.
Một số chỗ cần sửa:

set_timer0(243); → set_timer0(131);
if(dem==1) → if(dem==20)

if(dem==5) → if(dem==100)

BÀI 9:
Viết chương trình hiển thị các số từ 0 – 9 ở port D. Đồng thời cũng phát ra xung tần số
5KHz ở chân RC0. Sử dụng Timer1, hệ số chia 4 và dao động thạch anh là 20MHz. Vẽ
hình trước khi làm bài.

- Chu kỳ đi vào Timer0:


1 1
𝑇𝑇𝑖𝑚𝑒𝑟1 = = = 0,8 (𝜇𝑠)
𝑓𝑇𝑖𝑚𝑒𝑟1 𝑓𝑂𝑆𝐶 /4/4
- Chu kỳ xung cần tạo ra:
1 1
𝑇𝑥𝑢𝑛𝑔 = = = 200 (𝜇𝑠)
𝑓𝑥𝑢𝑛𝑔 5 × 103

𝑇𝑥𝑢𝑛𝑔 200
𝑇𝑜𝑛 = = = 100 (𝜇𝑠)
2 2
- Giá trị nạp cho Timer0:
𝑇𝑜𝑛 100
𝑁 = 65536 − = 256 − = 65411
𝑇𝑇𝑖𝑚𝑒𝑟1 0,8

Chương trình:
#include <18F458.h>

#FUSES NOWDT, HS, Noprotect


#use delay (clock = 16M)

#bit TMRIF1 = 0x0c.0

int i;
const char M7D[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
#int_timer1

void ngat_timer1()

output_toggle(pin_C0);

set_timer1(65411);

void main()

{
set_tris_C(0x00);

set_tris_D(0x00);

setup_timer1(T1_internal|T1_div_by_4);

set_timer1(65411);

enable_interrupts(global);
enabla_interrupts(int_timer1);

while(true)
{

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

{
Z = M7D[i];
output_D(Z);

}
}

BÀI 10:

Cảm biến nhiệt độ LM35 đưa vào chân RA1.

2 LED 7 đoạn nối vào port C và D. Viết ct đo nhiệt độ và hiển thị lên 2 LED 7 đoạn. Biết
ADC chế độ 8 bit, giá trị đọc được là 2 chữ số.

Chương trình:
#include <18F458.h>

#FUSES NOWDT, HS, Noprotect


#use delay (clock = 20M)

#device ADC = 8

int16 kq;
int1 kt;
int8 donvi, chuc;

const char M7D[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};


void main()
{

set_tris_C(0x00);
set_tris_D(0x00);

set_tris_A(0xFF);

setup_adc(adc_clock_internal);
setup_adc_ports(AN1);
set_adc_channel(1);

while(true)

kt = adc_done();

while(kt == 0)

kt = adc_done();

}
kq = read_adc();

chuc = kq/10;

donvi = kq%10;

output_C(M7D[chuc]);

output_D(M7D[donvi]);
delay_ms(500);

}
}
BÀI 11

Chương trình
#include<18F458.h>

#FUSES NOWDT, HS, Noprotect

#use delay (clock = 20M)


int dem = 0, tram, chuc, donvi, i;

int16 value;

const char M7D[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

#int_ext
void ngat_ext()

{
dem++;

if(dem == 3)

{
dem = 1;

}
void main()

{
set_tris_D(0x00);

set_tris_C(0x00);

set_tris_B(oxFF);
enable_interrupts(global);
enable_interrupts(int_ext);

ext_int_edge(L_to_H);

while(true)

if(dem == 1)

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

{
tram = i/100;

chuc = (i - tram*100)/10;

donvi = chuc%10;

output_low(pin_C0);
output_high(pin_C1);

output_high(pin_C2);
output_D(M7D[tram]);

delay_ms(10);

output_high(pin_C0);
output_low(pin_C1);

output_high(pin_C2);
output_D(M7D[chuc]);

delay_ms(10);

output_high(pin_C0);
output_high(pin_C1);

output_low(pin_C2);

output_D(M7D[donvi]);

delay_ms(10);

if(dem == 2)

{
for(i=1; i<1000; i+=2)

tram = i/100;

chuc = (i - tram*100)/10;

donvi = chuc%10;

output_C(0b11111110);
output_D(M7D[tram]);

delay_ms(10);

output_C(0b11111101);
output_D(M7D[chuc]);

delay_ms(10);

output_C(ob11111011);

output_D(M7D{donvi});
delay_ms(10);
}

}\\while

}\\main

BÀI 12
Hiển thị số từ 0 – 99, đồng thời truyền giá trị này ra port nối tiếp. Biết UART 8 bit, baud
= 2400. Thạch anh 16MHz

Chương trình
#include <18F458.h>
#FUSES NOWDT, HS, Noprotect

#use delay (clock = 16M)

#RS232 (baud = 2400, parity = N, Xmit = pin_C6, RCV = pin_C7)

const char M7D[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

int dem, chuc, donvi;

void main()
{
set_tris_B(0x00);

set_tris_D(0x00);
while(true)

{
for(dem=0; dem<100; dem++)

chuc = dem/10;
donvi = dem%10;
output_B(M7D[chuc]);

output_D(M7D[donvi]);

putchar(dem);

delay_ms(50);

BÀI 13
Nhận dữ liệu từ port nối tiếp (baud = 4800, chế độ 8 bit, thạch anh 20MHz)
a. Nếu ký tự nhận được là A thì hiển thị số chẵn lên 2 LED 7 đoạn
b. Nếu ký tự nhận được là B thì hiển thị số lẻ lên 2 LED 7 đoạn
Chương trình
#include <18F458.h>
#FUSES NOWDT, HS, Noprotect

#use delay (clock = 20M)

#RS232(baud = 4800, parity = N, Xmit = pin_C6, RCV = pin_C7)


const char M7D[10]={ 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
int kytu, chuc, donvi, i;

#int_RDA

void ngat_nhan()

kytu = getchar();

void main()

{
set_tris_B(0x00);

set_tris_D(0x00);

enable_interrupts(global);

enable_interrupts(int_RDA);

while(true)
{

if(kytu == 'A')
{

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

{
chuc = i/10;
donvi = i%10;

output_B(M7D[chuc]);
output_D(M7D[donvi]);

delay_ms(500)

}
}
if(kytu == 'B')

for(i=1; i<100; i+=2)

chuc = i/10;

donvi = i%10;

output_B(M7D[chuc]);

output_D(M7D[donvi]);
delay_ms(500)

You might also like