Tải bản đầy đủ (.pdf) (29 trang)

vi điều khiển họ 8051 với ngôn ngữ c

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (183.68 KB, 29 trang )

PDA
tranpic
tranpic
tranpic
Welcome www.khongtenmien.com > > ðiện - Tự
ñộng > Vi ñiều khiển > 8051 family > vi ñiều khiển họ 8051! với ngôn ngữ C
View Full Version : vi ñiều khiển họ 8051! với ngôn ngữ C
10-28-2007, 03:27 PM
họ 8051 là họ VDK cổ ñiển nhưng nó khá phổ cập ở Việt Nam. Với họ này các bạn sẽ ñược học ở trường, và nó sẽ
trở thành tiền ñề ñể học các họ khác.
Khi bắt tay vào học VDK, bạn có 2 hướng ñi: dùng ngôn ngữ Assembler hoặc sử dụng ngôn ngữ cấp cao như
Pacal, C nhưng cái nào cũng có thế mạnh riêng của nó. As thì sẽ gần với phần cứng nhất nên chương trình sẽ
chạy nhanh nhất, ngôn ngữ cấp cao thì tiện cho người sử dụng hơn nhưng sẽ chạy chậm hơn.
Ở ñây chúng ta sẽ cùng tham gia bàn luận về họ 8051 với ngôn ngữ cấp cao như C, sử dụng chương trình Keil ñể
lập trình.
ðể học VDK chúng ta cần mạch nạp và kit hoặc chương trình mô phỏng(bên PROTEUS), nhưng tốt hơn hết là phải
có một cái kit thí nghiệm có thể tự làm hoặc mua, có như vậy chúng ta mới có thể nhanh tiến bộ ñược, có nhiều
lỗi mà trong mô phỏng chúng ta không thấy ñược
Link down Keil: >>> ([Only registered and activated users can see links])
10-28-2007, 03:55 PM
sau khi cài ñặt,chon Project/close Project
sau ñó bắt ñầu tạo Project mới như sau: Project/New Project
chọn chip ở ñây mình sử dụng chip 89S52 của ATMEL
[Only registered and activated users can see links]
sau ñó bạn chon File/New rồi chọn Save ñặt tên cho nó nhớ phải có phần mở rộng là .c
tiếp tục nhấn chuột phải vào Source Group 1 chọn Add File To Group rồi chọn File *.c bạn vừa lưu ở trên
[Only registered and activated users can see links]
tạo File .hex ñể nạp cho VDK
[Only registered and activated users can see links]
[Only registered and activated users can see links]
rồi bây giờ viết chương trình và ñể dịch sang File .hex thì ta nhấn F7.


chúng ta bắt ñầu viết chương trình cho VDK
#include< *.h > ‘khai báo thư viện cần dùng
void ten()
{ ‘chương trình con

}
void ngat() interrupt 0 using 0 ‘chương trinh phục vụ ngắt
{

}
void main() ‘chương trình chính cho VDK
{

}
10-28-2007, 04:03 PM
Việc viết hàm delay có thời gian chuẩn là rất cần thiết trong lập trình VDK;)
Các vấn ñề liên quan ñến việc sử dụng Timer:
• Thanh ghi TMOD là thanh ghi 8 bit dùng ñể thiết lập bộ ñịnh thời.
Bit Tên Bộ ñịnh thời Mô tả
7 GATE 1 Bit ñiều khiển cổng. Khi ñược set lên 1, bộ ñịnh thời chỉ hoạt ñộng khi INT1 ở mức 1.
6 C/T 1 Bit chọn chức năng ñếm hoặc ñịnh thời; 1 là ñếm sự kiện, 0 là ñịnh thời trong 1 khoảng thời gian.
5 M1 1 Bit chọn chế ñộ thứ nhất.
4 M0 1 Bit chọn chế ñộ thứ hai.
3 GATE 0 Bit ñiều khiển cổng cho bộ ñịnh thời 0.
2 C/T 0 Bit chọn chức năng ñếm hay ñịnh thời cho bộ ñịnh thời 0.
1 M1 0 Bit chọn chế ñộ thứ nhất.
0 M0 0 Bit chọn chế ñộ thứ hai.
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
1 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=

tranpic
• Việc xác ñịnh chế ñộ làm việc của bộ ñịnh thời dựa vào giá trị của 2 bit M0 và M1:
M1 M0 Chế ñộ Mô tả
0 0 0 Chế ñộ ñịnh thời 13 bit
0 1 1 Chế ñộ ñịnh thời 16 bit
1 0 2 Chế ñộ tự ñộng nạp lại 8 bit
1 1 3 Chế ñộ ñịnh thời chia xẻ
Chế ñộ 0: (chế ñộ ñịnh thời 13 bit).
Chế ñộ này tương thích với bộ vi ñiều khiển tiền nhiệm 8048. Chế ñộ này không ñược dùng cho các thiết kế mới.
Chế ñộ1: (chế ñộ ñịnh thời 16 bit).
Là chế ñộ xung clock ñặt vào cả thanh ghi ñịnh thời cao và thấp kết hợp(TLxTHx),khi có xung clock ñến thì bộ
ñịnh thời ñếm lên : 0000H…FFFFH, khi từ FFFFH xuống 0000H thì cờ tràn ñược set lên 1, cờ tràn là bit TFx trong
thanh ghi ñiều khiển ñịnh thờiTCON. Ở chế ñộ ñịnh thời 16 bit này cờ tràn sau khi ñưa lên 1 thì sẽ tự ñưa về 0.
Chế ñộ 2: (chế ñộ tự nạp lại 8 bit).
Chế ñộ này byte thấp của bộ ñịnh thời (TLx) hoạt ñộng ñịnh thời 8 bit còn byte cao của bộ ñịnh thời làm nhiệm
vụ lưu giữ giá trị nạp lại. Khi bộ ñịnh thời ñếm từ FFH xuống 00H, không chủ cờ tràn của bộ ñịnh thời ñược set
lên 1 mà giá trị trong THx còn ñược nạp vào TLx, việc ñếm tiếp tục ñược thực hiện
Chế ñộ 3: (chế ñộ ñịnh thời chia xẻ).
Nó hoạt ñộng khác nhau ở các bộ ñịnh thời khác nhau. Bộ ñịnh thời 0 ở chế ñộ 3 ñược chia làm 2 bộ ñịnh thời 8
bit hoạt ñộng riêng lẻ TL0 và TH0, mỗi bộ ñịnh thời lúc này sẽ set cờ tràn tương ứng là TF0 và TF1khi xảy ra tràn.
Bộ ñịnh thời 1 không hoạt ñộng ở chế ñộ 3.
• Thanh ghi TCON là thanh ghi ñiều khiển hoạt ñộng ñịnh thời.
Bit Ký hiệu ðịa chỉ Mô tả
7 TF1 8FH Cờ tràn của bộ ñịnh thời 1, ñược set và clear bởi phần cứng.
6 TR1 8EH Bit ñiều khiển hoạt ñộng của bộ ñịnh thời 1, ñược set và clear bằng phần mềm.
5 TF0 8DH Cờ tràn của bộ ñịnh thời 0.
4 TR0 8CH Bit ñiều khiển hoạt ñộng của bộ ñịnh thời 0.
3 IE1 8BH Cờ ngắt ngoài 1.
2 IT1 8AH Cờ ngắt ngoài 1, ñiều khiển ngắt cạnh hoặc mức.
1 ET0 89H Cờ ngắt ngoài 0.

0 IT0 88H Cờ ngắt ngoài 0, ñiều khiển ngắt cạnh hoặc mức.
• Cách tính thời gian cho một hàm delay như sau:
Sử dụng nguồn clock ngoài 12MHz, khi ñó clock của bộ ñịnh thời là 1MHz suy ra thời gian mỗi lần bộ ñịnh thời
tăng lên 1 là 1µs.
10-28-2007, 04:25 PM
ví dụ khi bạn cần hàm delay 1ms=1000us như vậy bạn cần dùng ở chế ñộ 1(16 bit 65536)
nếu sử dụng thạch anh ngoài là 12MHz thì thời gian của mỗi lần tăng lên của Timer sẽ là 12000000/12=1us.
tính thời gian delay: thời gian delay=(65536-THx,TLXx+1).
tính toán rồi ñổi ra số HEX ta ñược THx,TLx+1=FC18, như vậy mình nạp giá trị vào cho THx=FC và TLx=17;
chương trình ñược viết như sau:
void delay()
{
TMOD=0x01; //sử dụng Timer0 ở chế ñộ 1
TL0=17;
TH0=FC;
TR0=1; //cho phép Timer0 chạy
while (TF0);//chờ TF0 lên mức 1
TR0=0; //cấm Timer
}
như vậy mỗi lần cần delay 1ms bạn gọi hàm này ra như sau: delay();
Nếu như bạn cần delay là bội của 1ms thì có thể viết chương trình có thể nhập giá trị cần delay vào luôn:
void delay(unsigned char time)
{
unsigned char x;
for(x=0;x<=time;x++)
{
TMOD=0x01; //sử dụng Timer0 ở chế ñộ 1
TL0=17;
TH0=FC;
TR0=1; //cho phép Timer0 chạy

vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
2 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
vitcon
tranpic
tranpic
while (TF0);//chờ TF0 lên mức 1
TR0=0; //cấm Timer
}
}
Ở ñây vì khai báo là unsigned char nên time có giá trị từ 0>>255;
10-29-2007, 10:11 PM
ví dụ khi bạn cần hàm delay 1ms=1000us như vậy bạn cần dùng ở chế ñộ 1(16 bit 65536)
nếu sử dụng thạch anh ngoài là 12MHz thì thời gian của mỗi lần tăng lên của Timer sẽ là 12000000/12=1us.
tính thời gian delay: thời gian delay=(65536-THx,TLXx+1).1
tính toán rồi ñổi ra số HEX ta ñược THx,TLx+1=FC18, như vậy mình nạp giá trị vào cho THx=FC và TLx=17;
chương trình ñược viết như sau:
void delay()
{
TMOD=0x01; //sử dụng Timer0 ở chế ñộ 1
TL0=17;
TH0=FC;
TR0=1; //cho phép Timer0 chạy
while (TF0);//chờ TF0 lên mức 1
TR0=0; //cấm Timer
}
như vậy mỗi lần cần delay 1ms bạn gọi hàm này ra như sau: delay();
Nếu như bạn cần delay là bội của 1ms thì có thể viết chương trình có thể nhập giá trị cần delay vào luôn:
void delay(unsigned char time)
{

unsigned char x;
for(x=0;x<=time;x++)
{
TMOD=0x01; //sử dụng Timer0 ở chế ñộ 1
TL0=17;
TH0=FC;
TR0=1; //cho phép Timer0 chạy
while (TF0);//chờ TF0 lên mức 1
TR0=0; //cấm Timer
}
}
Ở ñây vì khai báo là unsigned char nên time có giá trị từ 0>>255;
pác sinhvien chăm chỉ nhẩy!!!thax pác phát nhá!Nhưng em lở iu avr ùi!Sống chết j em cũng quyết tâm lấy avr
làm ñồ án!hehe.
10-30-2007, 04:46 PM
pác sinhvien chăm chỉ nhẩy!!!thax pác phát nhá!Nhưng em lở iu avr ùi!Sống chết j em cũng quyết tâm lấy avr
làm ñồ án!hehe.
haha cố lên Jimmy, vậy thì chúng mình thêm vào một box AVR nữa nha.
11-03-2007, 12:56 PM
câu hỏi ñặt ra: tại sao phải quét led??????
1. khi chúng ta sử dụng nhiều led ñể hiển thị không lẻ cho tất cả các led ñều sáng-> tổn hao công suất.
2. cứ 1 led ta phải tốn 7 chân như vậy nếu dùng 6 led thì tốn 42 chân -> không ñủ chân ñiều khiển, nếu dùng 4
led thì tốn 28 chân vậy vdk chỉ ñể hiển thị thôi sao,,,phí!!!!!!!!!!!!!
3. khi dùng quét led bạn chỉ cần 2 port ñể ñiều khiển hiển thị 8 led 7 ñoạn. Nếu dùng giải mã và encoder bạn chỉ
tốn 1 port ñể ñiều khiển hiển thị 16 led 7 ñoạn.
Phương pháp này là dựa trên hiện tượng lưu ảnh của mắt người, ta cho mỗi led sáng lên trong một khoảng thời
gian ñủ lâu cho mắt người lưu lại rồi tắt ñi cho led tiếp theo sáng lên cứ như vậy(giống cái ti vi ñó mà).
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
3 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=

Thanh Hai
tranpic
tranpic
vd: chương trình cho hiển thị từ 0 ñến 7 trên 8 led 7 ñoạn dùng quét led.
#include<AT89X52.h>
//bảng mã led 7 ñoạn
unsigned char ma[8]={64,121,36,48,25,18,2,120};
//chương trình con tạo thời gian trễ, do không cần chính xác nên không cần dùng ñến Timer, ở
//ñây gây trễ khoảng 1ms.
void delay(unsigned char loop)
{
unsigned char x,y;
for(x=0;x<=loop;x++)
{
for(y=0;y<33;y++);
}
}
//chương trình con cho hiển thị
void h_thi()
{
unsigned char x;
P2=1;
for(x=0;x<8;x++)
{
P0=ma[x];
delay(10);
P0=255;
delay(2);
P2=P2<<1;
}

}
//chương trình chính
void main()
{
h_thi();
}
11-08-2007, 07:34 PM
Ai viet bai nay ma noi sai roi do. Nhung phan mem chay tren OS cua may tinh moi tinh den chay nhanh hay
cham khi su dung Ngon ngu lap trinh nao! Con doi voi ho VDK 8051, no kg co OS, tat ca moi ngon ngu khi nap
cho 8051 deu bien dich ra 'ma may' roi moi nap cho 8051. Do do, viet bang bat ky ngon ngu nao cung chay voi
toc do nhu nhau thoi. Ngon ngu cap cao chi de tien loi cho nguoi lap trinh thoi, hihi.
Chao mung duoc den voi dien dan cua 08TDT, xin dc lam thanh vien nhe. Cac ban lam tot lam, hay chung suc
xay dung de cho dien dan cua minh ngay cang lon manh nha. Tui xin dc ho tro ca ve mat tinh than lan van de
kinh te, OK kg nao!
Thay Hai.
11-08-2007, 09:31 PM
chào thầy, cảm ơn thầy ñã tham gia với tụi em. Em viết mấy cái này bữa giờ chẳng thấy ai nói năng gì hết nên
buồn quá trời luôn :(.
Em nói chậm ở ñây là có lý do của em. Khi em dùng Keil và assem ñể viết 1 chương trình với giải thuật như nhau,
thì việc mà em nói các ngôn ngữ cấp cao sẽ làm cho VDK chậm hơn ñó chính là 2 file .hex dich ra không có cùng
một dung lượng(thường thì file .hex của ngôn ngữ cấp cao lớn hơn). ðiều ñó cho thấy khi dịch sang mã máy thì
ngôn ngữ cấp cao tốn bộ nhớ hơn, hay sẽ nhiều lệnh hơn ->chạy chậm hơn.
Việc này giống như lúc soạn thảo văn bản, nếu mình dùng notepad và word ñể viết 1 câu "chào bạn"với cùng fon
chữ, cở chữ; khi lưu lại chắc chắn file do word tạo ra sẽ lớn hơn file do notepad tạo ra.
không biết em có ñi lạc ñường khôg nhưng em nghĩ như vậy. Mong thầy hướng dẫn thêm.
11-10-2007, 03:58 PM
Phím nhấn là 1 công cụ giúp con người giao tiếp với máy tính cũng như VDK. Cũng như vơi led ñể tiết kiệm chân
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
4 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=

tranpic
ta cũng dùng phương pháp là quét phím. Với ma trận phím thì ta có thể xác ñịnh ñược phím thông qua số thứ tự
hàng và cột của phím ñó, cho nên ta sẽ viết chương trình nhận biết phím nào ñược nhấn thông qua 2 thông số ñó
là hàng và cột.
Ví dụ với ma trận 16 phím (4 hàng 4 cột) ta có bảng giá trị như sau:
0 1 2 3
4 5 6 7
8 9 A B
C D E F
Cột 1 2 3 4 phím số
+ + + + + +
hàng1 1 1 1 0 3
1 1 0 1 2
1 0 1 1 1
0 1 1 1 0
hàng2 1 1 1 0 7
1 1 0 1 6
1 0 1 1 5
0 1 1 1 4
hàng3 1 1 1 0 B
1 1 0 1 A
1 0 1 1 9
0 1 1 1 8
hàng4 1 1 1 0 F
1 1 0 1 E
1 0 1 1 D
0 1 1 1 C
Các vị trí của số 0 tương ứng với các phím trên bàn phím như (phím số)
Phương pháp thực hiện là ta sẽ cho các cột hoặc các hàng thứ tự cao-thấp-cao. Nếu có phím ñược nhấn thì hàng
hoặc cột tương ứng còn lại của phím ñó cũng sẽ xuống mức thấp, như vậy khi có phím nhấn thì sẽ có 1 cột và 1

hàng ở mức 0. Dựa vào bảng trên ta biết ñược ñó là phím nào ñược nhấn.
11-10-2007, 10:43 PM
ñây là bài viết ñơn giản. Dựa trên phương pháp ñã nêu ở trên.
#include<AT89X52.h>
unsigned char ma=0;
void delay(unsigned char timer)
{
unsigned char x,y;
for (x=0;x<timer;x++) for(y=0;y<13;y++);
}
void display()
{
switch (ma)
{
case 0: P2=255;
break;
case 215: P2=64; //so 0
break;
case 235: P2=121;//so 1
break;
case 219: P2=36; //so 2
break;
case 187: P2=48; //so 3
break;
case 237: P2=25; //so 4
break;
case 221: P2=18; //so 5
break;
case 189: P2=2; //so 6
break;

case 238: P2=120;//so 7
break;
case 222: P2=128;//so 8
break;
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
5 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
tranpic
tiger
tranpic
case 190: P2=16; //so9
break;
}
}
void button()
{
unsigned char loop=0,get=0,bh=0;
for (loop=0;loop<=3;loop++)
{
P3=~(1<<loop);//quet
ma=0;
bh=P3>>4;
if (bh!=15)
{
ma=P3;
while(P3==ma)
{
display();
}

}
}
}
void main()
{
P3=255;
while(1)
{
P2=255;//tat led khi ko nhan
button();
}
}
11-10-2007, 11:05 PM
[Only registered and activated users can see links]
11-10-2007, 11:18 PM
tìm cái host free mòn mỏi luôn mới up ñược cái hình lên, ví dụ ở trên là giải mã bàn phím. còn mấy cái mã cho
mấy phím dấu + - nữa nhưng buồn ngủ quá thôi nhờ các bạn ghi vào dùm. Ghi vào chỗ switch case ñó
mà :D
có thể các bạn có cách lấy mã hay hơn, xin gốm ý nha.
11-20-2007, 08:12 AM
Noi nhu vay la chưa ñúng hẳn rồi.
Dùng Assembly có thế mạnh là người dùng có thể ngày càng hiểu rõ phần cứng hơn, còn dùng C thì dễ mất ñi
cấu trúc phần cứng. Trong giai ñoạn các bạn chưa phải là chuyên gia nên học Assembly cho thật vững, có thể
xem ass là 70% và C là 30%, chủ yếu học cách viết ass sao cho có cấu trúc là ñưoc. ass hỗ trợ tất cả các kỹ năng
viết ass có cấu trúc giống như C thôi. Cái hay của C là khi chuyển ñổi qua vdk khác tập lệnh ass thì dễ dàng hơn.
phải vậy không thày?
Vi dụ như trong C ta dung lênh for hoặc while thì trong ass ta dùng djnz hoặc cjne. Trong C ta goi ct con thi trong
ass ta cung goi ct con (call), trong C ta co macro thi trong ass ta cung co macro (dung lệnh #define). Vấn ñề là
phai luyện tập thui.
Chuc moi nguoi thanh cong

01-14-2008, 04:01 PM
chương trình sử dụng timer ñê tính thời gian. Nhưng cũng không thể chạy ñúng ñược, ñể chạy ñúng thì cần dùng
IC thời gian thực của Dallat hoặc ñơn giản là kiếm ñồng hồ báo thức nào ko dùng nữa tháo ra lấy con IC của nó ta
thấy có phần nối với 2 sợi dây của cuộn dây, ñó là xung chuẩn 1s, lấy cấp vào cho chân T0, hoặc T1 của VDK
chuyển Timer thành Counter thế là chính xác ngay.
/*
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
6 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
noi 4 bit thap cua P0 vao BCD-7SEG
noi P2 vao 7SEG_CONTROL
*/
#include<AT89X52.h>
unsigned int over=0; //bien tinh timer tran
unsigned char second=0,min=0;hour=0; //bien gio, phut, giay
unsigned char cod[8]={0,0,0,0,0,0,0,0}; //mang chua so hien thi
//chuong trinh con tao thoi gian tre cho quet led
void delay(unsigned char time)
{
unsigned char x,y;
for(x=0;x<time;x++)
{
for(y=0;y<13;y++);
}
}
//chuong trinh phuc vu ngat timer0
void time0() interrupt 1
{ //cu 200 us thi tran 1 lan
over++;
if(over==4950) //gia tri tinh toan la 5000, tinh chinh lai 4950

{
over=0;
second++;
}
}
//chuong trinh tinh toan
void cal()
{
if(second==60)
{
second=0;
min++;
}
if(min==60)
{
min=0;
hour++;
}
if(hour==12)
{
hour=0;
}
//doan duoi la tach cac so gio, phut, giay ra thanh tung co so de hien thi
cod[0]=second%10;
cod[1]=second/10;
cod[3]=min%10;
cod[4]=min/10;
cod[6]=hour%10;
cod[7]=hour/10;
}

//chuong trinh con hien thi
void disp()
{
unsigned char k;
for(k=0;k<8;k++)
{
P0=cod[k];
if((k==2)||(k==5))
{
P0=255;
}
P2=~(1<<k);
delay(1);
P2=255;
}
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
7 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
}
//chuong trinh chinh
void main()
{
P0=255;
P2=255;
TMOD=2; //timer0 o che do 2 tu nap lai
TH0=54; //gia tri nap lai
TR0=1; //cho phep timer0 chay
ET0=1; //cho phep ngat timer0
EA=1; //cho phep ngat toan cuc

while(1)
{
cal(); //goi chuong trinh tinh toan
disp(); //goi chuong trinh hien thi
}
}
01-14-2008, 04:18 PM
chương trình giải mã ma trận phím hiển thị LCD giống như chương trình giải mã ma trận phím ñã viết ở trên chỉ
thêm vào phần hiển thị LCD.
ðể hiển thị LCD cần xem phần ñiều khiển LCD kèm theo.
/* P0 noi voi LCD data*/
/* ma tran phim noi voi P3*/
/* noi 4 bit thap cua P2 voi chan cam LCD_CONTROL*/
/* co the su dung board thi nghiem 89_v2 de chay chuong trinh*/
/* lien he 0902902287*/
#include<AT89X52.h>
sbit rs=P2^0; //P2_0
sbit rw=P2^1; //P2_1
sbit e=P2^2; //P2_2
sbit li=P2^3; //P2_3 dieu khien den cua LCD
unsigned char dem=0;
//chuong trinh con tao thoi gian tre
void delay(unsigned int time)
{
unsigned int x,y;
for(x=0;x<time;x++)
{
for(y=0;y<33;y++);
}
}

//
//chuong trinh con kiem tra lcd co ban ko
void busy()
{
rs=0;
rw=1;
P0_7=1; //phai set chan nay de kien tra LCD co ban khong
while(P0_7!=0)
{
e=0;
e=1;
}
}
//
//chuong trinh con xuat lenh len LCD
void lenh(unsigned char ma)
{
busy();
rs=0;
rw=0; //phai tao xung o chan E nhu sau LCD moi chay
e=1;
P0=ma;
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
8 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
e=0;
}
//
//chuong trinh con xuat du lieu len LCD
void dat(unsigned char ma)

{
busy();
rs=1;
rw=0; //phai tao xung o chan E nhu sau LCD moi chay
e=1;
P0=ma;
e=0;
}
//
//chuong trinh con cai dat LCD
void int_lcd()
{
delay(30); //doi
lenh(56); //8bit, 2 line
lenh(15); //display on, cursor on,blinking on
lenh(1); //clear display
lenh(2); //return home
}
//
//chuong trinh con su ly ma tran phim va hien thi ra LCD
void key()
{
unsigned char k=0,temp=0;
for(k=0;k<4;k++)
{
P3=~(1<<k);
temp=P3>>4;
if(temp!=15)
{
if(dem==0) lenh(1); //xoa man hinh cho lan nhan dau va cho khi bat dau nhan lai

switch(P3)
{
case 119:
while(temp!=15) //vong lap doi tha phim
{
temp=P3>>4;
}
delay(100); //chong nay phim
dat(48); //xuat so 0 len LCD
break;
case 123:
while(temp!=15) //vong lap doi tha phim
{
temp=P3>>4;
}
delay(100); //chong nay phim
dat(49); //xuat so 1 len LCD
break;
case 125:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(50);
break;
case 126:
while(temp!=15)
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20

9 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
{
temp=P3>>4;
}
delay(100);
dat(51);
break;
//
case 183:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(52);
break;
case 187:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(53);
break;
case 189:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);

dat(54);
break;
case 190:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(55);
break;
//
case 215:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(56);
break;
case 219:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(57);
break;
case 221:
while(temp!=15)
{

temp=P3>>4;
}
delay(100);
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
10 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
dat(65);
break;
case 222:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(66);
break;
//
case 231:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(67);
break;
case 235:
while(temp!=15)
{
temp=P3>>4;
}

delay(100);
dat(68);
break;
case 237:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(69);
break;
case 238:
while(temp!=15)
{
temp=P3>>4;
}
delay(100);
dat(70);
break;
}
dem++; //bien kiem tra so lan nhan phims
if(dem==16) //neu nhan 16 lan roi thi xuong dong
{
lenh(192); //xuong dong
}
if(dem==32) //neu nhan 32 lan thi xoa man hinh va quay ve dau dong
{
dem=0; //nap lai gia tri dem
lenh(2); //quay ve dau dong
}

}
}
}
//
//chuong trinh chinh
main()
{
P0=255;
P1=255;
P2=255;
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
11 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
l.bichhuu
tranpic
tranpic
siss
ductrung2959
tranpic
P3=255;
int_lcd(); //goi chuong trinh cai dat LCD
while(1) //vong lap vo tan
{
key(); //goi chuong trinh con xu ly ma tran phim
}
}
//bạn có thể sử dụng file sau làm thư viện cho LCD xem kết nối và câu lệnh sử dụng ở trong. các bạn chỉ cần
copy nó vào C:\Keil\C51\INC rồi sau ñó vào chương trình của bạn khai báo thêm dòng #include<lcd.c> rồi sau ñó
dùng vô tư. ví dụ :
#include<AT89X52.h>

#include<lcd.c>
void main()
{
P0=255;
P1=255;
P2=255;
P3=255;
int_lcd();
lenh(clr);
dat_str("have a good time");
mov(1,0);
dat_str("i am tranpic");
}
01-18-2008, 08:03 PM
pác sv có thể nói rõ hơn dc ko mình rất muốn học ñó chẳng hạn như là :viết 1 ñoạn chương trình ñể mình hiểu
thêm:confused: vì mình chưa bit.pac viết assem thì càng hay con ko thì viết c cũng dc, như " pác tiger " nói viết
assem thì hiểu phấn cứng hơn ñiều ñó là ñúng vì trong lớp ña số chỉ hiểu ass thôi nên pác viết gì thì tụi nó có
hiểu ñâu mà góp ý vì c chỉ dành cho những người ñã rành vi tụi mình chỉ học vdk mới 4 tháng thôi . vì thế tụi fai
tự học ñể góp ý cho pác nha . ñừng buồn tụi này nha:D
01-19-2008, 11:30 AM
mình ñã chú thích rất kĩ rồi mà, bạn nên ñọc các chú thích nữa chứ
02-18-2008, 10:53 PM
có thể nói ñây là ví dụ hay cho các bạn nghiền ngẫm về cách lập trình bằng ngôn ngữ c.
02-18-2008, 11:35 PM
pác sv có thể nói rõ hơn dc ko mình rất muốn học ñó chẳng hạn như là :viết 1 ñoạn chương trình ñể mình hiểu
thêm:confused: vì mình chưa bit.pac viết assem thì càng hay con ko thì viết c cũng dc, như " pác tiger " nói viết
assem thì hiểu phấn cứng hơn ñiều ñó là ñúng vì trong lớp ña số chỉ hiểu ass thôi nên pác viết gì thì tụi nó có
hiểu ñâu mà góp ý vì c chỉ dành cho những người ñã rành vi tụi mình chỉ học vdk mới 4 tháng thôi . vì thế tụi fai
tự học ñể góp ý cho pác nha . ñừng buồn tụi này nha:D
Tui cũng ñã có làm 1 topic nói về ngôn ngữ assem rùi ñó , sao bạn ko vô trong ñó xem ñi , có rất nhiều ở ñó ,

những bài ví dụ rất hay có thể mô phỏng trên protues .
Và về quét phím ma trận hiển thị LCD thì tui ñã cho bạn nguyên 1 cái ñồ án mà tui làm về nó ñó, vô trong ñó mà
xem, chú thích rất kỹ , mỗi câu lệnh ñều có chú thích
04-03-2008, 10:22 AM
cam on cac bac nhieu.
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
12 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
BOW
nhoang
nhoang
tranpic
vanhungesdk
tranpic
06-11-2008, 04:18 PM
ñây là chương trình ñồng hồ báo giờ sử dụng timer của 8051 ñể chạy thời gian nên ko chính xác về thời gian
các bạn có thể sử dụng các ic realtime ñể có thời gian chính xác.
06-11-2008, 05:40 PM
giờ mới vô box này, thấy nó phát triển quá chứ, ủng hộ tranpic 1 :nhau:
:dance:
06-15-2008, 09:18 PM
trapic post bài chỉ dẫn hay ñó, mình ñang muốn tìm hiểu về lập trình C cho 89c51 ñây bài bạn viết rất hay, có
ý nghĩa lắm ñó, post thêm nhiều nữa ñi bạn cho mọi người cùng học nào
06-15-2008, 09:19 PM
ah, mà sao mấy cái file trapic gời kèm theo ñó, về mở lên ko chạy ñược ( file viết trong Keil C ñó), sao mở lên nó
ko cho ñọc vậy
06-15-2008, 10:17 PM
ah, mà sao mấy cái file trapic gời kèm theo ñó, về mở lên ko chạy ñược ( file viết trong Keil C ñó), sao mở lên nó
ko cho ñọc vậy
sao ko ñược bạn dùng bản keil bao nhiêu vậy, tui có up chương trình ñó lấy về mà dùng

08-17-2008, 08:12 AM
tranpic ơi, bạn có thể chỉ giúp mình cách chống run cho phím nhấn ñược không. Chẳng hạn mình có 3 phim nhấn
lần lượt ở chân P1.0 ñến P1.2.Nếu P1.2 ñược nhấn 1 lần thì khi nhấn p1.0 hoặc p1.1 thì P2 tăng hoặc giảm 1 ñơn
vị,Nếu P1.2 ñược nhấn 2 lần thì khi nhấn p1.0 hoặc p1.1 thì P2 tăng hoặc giảm 2 ñơn vị,Nếu P1.2 ñược nhấn 3
lần thì thoát ra khỏi chế ñộ chỉnh sữa P2. Nhờ bạn giúp ñở
08-17-2008, 01:56 PM
tranpic ơi, bạn có thể chỉ giúp mình cách chống run cho phím nhấn ñược không. Chẳng hạn mình có 3 phim nhấn
lần lượt ở chân P1.0 ñến P1.2.Nếu P1.2 ñược nhấn 1 lần thì khi nhấn p1.0 hoặc p1.1 thì P2 tăng hoặc giảm 1 ñơn
vị,Nếu P1.2 ñược nhấn 2 lần thì khi nhấn p1.0 hoặc p1.1 thì P2 tăng hoặc giảm 2 ñơn vị,Nếu P1.2 ñược nhấn 3
lần thì thoát ra khỏi chế ñộ chỉnh sữa P2. Nhờ bạn giúp ñở
mình ko hiểu rõ là P1.2 ñược nhấn 2 lần là 1 lúc nhấn 2 lần hay là nhấn lần thứ hai(nghĩa là nhấn lần 1 ñể tăng
hoặc giảm 1 ñơn vị, nhấn thêm lần nữa ñể tăng hoặc giảm 2 ñơn vị; hay là nhấn P1.2 một cái chỉnh ñược 1 ñơn
vị, còn nến nhấn 2 cái chỉnh ñược 2 ñơn vị, nhấn 3 cái thoát)
mình viết 1 ví dụ như sau bạn xem thử nha:
P1.2 nhấn 1 cái thì khi P1.0 hoặc P1.1ñược nhấn sẽ tăng hay giảm P2 1 ñơn vị.
khi nhấn P1.2 2 cái 1 lúc thì sẽ cho phép thay ñổi P2 2 ñơn vị.
nhấn P1.2 3 cái liền nhau thì thoát.
chương trinh mình viết như sau bạn có thể thay ñổi như ý muốn.
#include<AT89X52.h>
void delay(unsigned char loop)
{
unsigned char x,y;
for(x=0;x<loop;x++)
{
for(y=0;y<33;y++);
}
}
main()
{
unsigned char dem=0,chinh=0;

while(1)
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
13 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
HERRO_AVR_PIC
tranpic
vanhungesdk
{
switch (P1)
{
case 251: //P1.2 duoc nhan
while(P1!=255); //doi cho P1.2 tha ra
delay(10); //tao tre de chong nay phim
dem++; //dem so lan nhan
if(dem==3) dem=0;
chinh=dem;
break;
case 254: //P1.0 duoc nhan
while(P1!=255); //doi cho P1.2 tha ra (co the bo di neu muon giu phim gia tri tu tang)
delay(10); //tao tre de chong nay phim(co the tang de co thoi gian tu tang nhu y muon)
dem=0;
P2+=chinh;
break;
case 253:
while(P1!=255);
delay(10);
dem=0;
P2-=chinh;
break;
}

}
}
mình viết như vậy chưa thật sự là hay nhất bạn hãy viết lại và tìm cách khác ñể có ñược 1 chương trình hoàn
thiện nha. Chúc bạn thành công
08-20-2008, 03:19 PM
ñây là chương trình ñồng hồ báo giờ sử dụng timer của 8051 ñể chạy thời gian nên ko chính xác về thời gian
các bạn có thể sử dụng các ic realtime ñể có thời gian chính xác.
bác tran pic thu dung nap lại 16bit của 8051 of at89c52 chua,,, thoi gian dam bao chính xác ñó
08-21-2008, 06:25 AM
bác tran pic thu dung nap lại 16bit của 8051 of at89c52 chua,,, thoi gian dam bao chính xác ñó
mình chưa thử, nên ko biết có chính xác ko. Bác làm rồi thì up lên cho anh em xem với.
08-31-2008, 09:22 AM
mình ko hiểu rõ là P1.2 ñược nhấn 2 lần là 1 lúc nhấn 2 lần hay là nhấn lần thứ hai(nghĩa là nhấn lần 1 ñể tăng
hoặc giảm 1 ñơn vị, nhấn thêm lần nữa ñể tăng hoặc giảm 2 ñơn vị; hay là nhấn P1.2 một cái chỉnh ñược 1 ñơn
vị, còn nến nhấn 2 cái chỉnh ñược 2 ñơn vị, nhấn 3 cái thoát)
mình viết 1 ví dụ như sau bạn xem thử nha:
P1.2 nhấn 1 cái thì khi P1.0 hoặc P1.1ñược nhấn sẽ tăng hay giảm P2 1 ñơn vị.
khi nhấn P1.2 2 cái 1 lúc thì sẽ cho phép thay ñổi P2 2 ñơn vị.
nhấn P1.2 3 cái liền nhau thì thoát.
chương trinh mình viết như sau bạn có thể thay ñổi như ý muốn.
#include<AT89X52.h>
void delay(unsigned char loop)
{
unsigned char x,y;
for(x=0;x<loop;x++)
{
for(y=0;y<33;y++);
}
}
main()

vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
14 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
vanhungesdk
tranpic
{
unsigned char dem=0,chinh=0;
while(1)
{
switch (P1)
{
case 251: //P1.2 duoc nhan
while(P1!=255); //doi cho P1.2 tha ra
delay(10); //tao tre de chong nay phim
dem++; //dem so lan nhan
if(dem==3) dem=0;
chinh=dem;
break;
case 254: //P1.0 duoc nhan
while(P1!=255); //doi cho P1.2 tha ra (co the bo di neu muon giu phim gia tri tu tang)
delay(10); //tao tre de chong nay phim(co the tang de co thoi gian tu tang nhu y muon)
dem=0;
P2+=chinh;
break;
case 253:
while(P1!=255);
delay(10);
dem=0;
P2-=chinh;

break;
}
}
}
mình viết như vậy chưa thật sự là hay nhất bạn hãy viết lại và tìm cách khác ñể có ñược 1 chương trình hoàn
thiện nha. Chúc bạn thành công
cảm ơn bạn nhiều nhé
08-31-2008, 10:31 AM
ko có j, ñây cũng là cơ hội cho mình học hỏi mà
09-06-2008, 07:38 AM
bạn tranpic ơi cho mình hỏi một tí, trong thư viện LCD mà bạn post trên diễn ñàn có ham mov 'void
mov(unsigned char row, unsigned char col)
{
lenh(128 | (row << 6) | col); //row =0 la hang dau,=1 la hang 2
}
"
Bạn có thể giải thich rỏ hộ mình ñược không, mình không hiểu chổ nay.Còn nữa nếu như mình muốn hiển thị ở 2
dòng: hàng 1 ñến hàng 2. khi quay lại hàng 1 mà mình muốn xóa hàng 1 ñể hiển thị dữ liệu mới còn hang 2 vẫn
dữ nguyên thì làm thế nào hả bạn. Cảm ơn bạn nhiều .
09-06-2008, 05:24 PM
bạn tranpic ơi cho mình hỏi một tí, trong thư viện LCD mà bạn post trên diễn ñàn có ham mov 'void
mov(unsigned char row, unsigned char col)
{
lenh(128 | (row << 6) | col); //row =0 la hang dau,=1 la hang 2
}
"
Bạn có thể giải thich rỏ hộ mình ñược không, mình không hiểu chổ nay.Còn nữa nếu như mình muốn hiển thị ở 2
dòng: hàng 1 ñến hàng 2. khi quay lại hàng 1 mà mình muốn xóa hàng 1 ñể hiển thị dữ liệu mới còn hang 2 vẫn
dữ nguyên thì làm thế nào hả bạn. Cảm ơn bạn nhiều .
ñể tiện mình tạo 1 file pdf kèm theo.

vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
15 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
vanhungesdk
tranpic
ganyfun
HERRO_AVR_PIC
ganyfun
việc bạn muốn viết lại dữ liệu ở dòng 1 mà ko xóa dòng 2 thì: quay lên ñầu dòng 1 và viết ra 16 kí tự thế là xong,
nếu dữ liệu của bạn ko ñủ 16 kí tự thì thêm vài khoảng trắng thế là ñủ.
mov(0,0);
dat_str("I Love You, baby");
09-07-2008, 08:34 AM
ñể tiện mình tạo 1 file pdf kèm theo.
việc bạn muốn viết lại dữ liệu ở dòng 1 mà ko xóa dòng 2 thì: quay lên ñầu dòng 1 và viết ra 16 kí tự thế là xong,
nếu dữ liệu của bạn ko ñủ 16 kí tự thì thêm vài khoảng trắng thế là ñủ.
mov(0,0);
dat_str("I Love You, baby");
Bây giờ thì mình hiểu rồi, ðang mới bắt ñầu tìm hiểu vi ñiều khiển nên còn nhiều thứ không biết lắm, còn phải
nhờ bạn giúp nhiều. Cảm ơn nhé :nhau::nhau::nhau::nhau::nhau::nhau:
09-07-2008, 11:50 AM
Bây giờ thì mình hiểu rồi, ðang mới bắt ñầu tìm hiểu vi ñiều khiển nên còn nhiều thứ không biết lắm, còn phải
nhờ bạn giúp nhiều. Cảm ơn nhé :nhau::nhau::nhau::nhau::nhau::nhau:
có j thắc mắc bạn cứ hỏi, nếu biết mình trả lời, nếu không biết mình sẽ hỏi người khác ñể trả lời bạn
:dance::dance::phe::phe::phe:
02-26-2009, 11:35 AM
chào các bạn mình có 1 vấn ñề cần hỏi mọi người ai biết giải thích dùm nha.mình lập trình bằng C. mình dùng
VDK 8051,bài tập của mình là thiết kế mạch dếm sản phẩm , mình sử dụng hồng ngoại ở bộ phát sáng nối với
mạch so sánh, khi có sản phẩm ñi qua che ánh sáng hồng ngoại thì mạch so sánh sẽ tạo ra 1 xung xung này dc
nối với ngắt ngoài của VDK làm bộ dếm tăng lên 1 và ñưa ra hiển thị trên led 7 thanh. mình không hiểu ngắt lắm

theo mình hiểu thì khi có ngắt xảy ra tức là có sản phẩm di qua bộ phát sáng thì VDK sẽ gọi chương trình phục
vụ ngắt của minh (mình dịnh nghĩa bit EA=1).mình chưa hiểu giải thuật lắm ai có thể chỉ co mình dược không
CẢM ƠN NHIỀU
02-26-2009, 01:24 PM
chào các bạn mình có 1 vấn ñề cần hỏi mọi người ai biết giải thích dùm nha.mình lập trình bằng C. mình dùng
VDK 8051,bài tập của mình là thiết kế mạch dếm sản phẩm , mình sử dụng hồng ngoại ở bộ phát sáng nối với
mạch so sánh, khi có sản phẩm ñi qua che ánh sáng hồng ngoại thì mạch so sánh sẽ tạo ra 1 xung xung này dc
nối với ngắt ngoài của VDK làm bộ dếm tăng lên 1 và ñưa ra hiển thị trên led 7 thanh. mình không hiểu ngắt lắm
theo mình hiểu thì khi có ngắt xảy ra tức là có sản phẩm di qua bộ phát sáng thì VDK sẽ gọi chương trình phục
vụ ngắt của minh (mình dịnh nghĩa bit EA=1).mình chưa hiểu giải thuật lắm ai có thể chỉ co mình dược không
CẢM ƠN NHIỀU
cái này ñể ñơn giản thì bạn viết một chương trình ngắt ngoài ví dụ ngắt ngoài 0
bit EA chỉ là biến cho phép ngắt toàn cục thôi, tức là cho phép tất cả các ngắt, còn cho phép ngắt ngoài 0 thì bạn
phải cho bit EX0 =1
+ viết chương trình ngắt ngoài 0:
unsigned int dem=0;
void demsanpham() interrupt 0 //vị trí của ngắt nhảy vào khi xảy ra sự kiện
{
dem++;
}
+ trong chương trình main ta chỉ việt ñọc giá trị dem về và hiển thị ra led 7ñoạn thui
void main()
{
//khởi ñộng ngắt ngoài và các biến khác phục vụ trong chương trình
// ??????
while(1)
{
hien_thi(dem);
}
}

vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
16 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
03-03-2009, 09:11 AM
bạn hero_avr_pic ơi mình dùng thuật toán như bạn nói nhưng không hiểu sao khi mô phỏng bằng proteus mạch
lại không chạy. bạn có thể kiểm tra giúp mình không,hoặc ai trong diễn ñàn thạo C có thể giúp mình không.mình
cảm ơn nhiều
ñây là phần lập trình của mình
#include <at89x51.h>
#define Aled1 P2_0
#define Aled2 P2_1
#define Aled3 P2_2
#define Aled4 P2_3
#define Aled5 P2_4
#define Aled6 P2_5
#define Aled7 P2_6
#define Aled8 P2_7
#define data P0
unsigned char led1,led2,led3,led4,led5,led6,led7,led8;
unsigned char maled7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6 7};
unsigned long dem;
void demsanpham() interrupt 0
{
dem++;
}
void convert_bcd(unsigned long temp)
{
led8 = temp % 10;
temp = temp / 10;
led7 = temp % 10;

temp = temp / 10;
led6 = temp % 10;
temp = temp / 10;
led5 = temp % 10;
temp = temp / 10;
led4 = temp % 10;
temp = temp / 10;
led3 = temp % 10;
temp = temp / 10;
led2 = temp % 10;
temp = temp / 10;
led1 = temp % 10;
temp = temp / 10;
}
void delay_us(unsigned int x)
{
unsigned int i;
for(i=0;i<x;i++) {}
}
void display()
{
data = ~ maled7[led8]; Aled1 = 0; delay_us(50); Aled1 = 1;
data = ~ maled7[led7]; Aled2 = 0; delay_us(50); Aled2 = 1;
data = ~ maled7[led6]; Aled3 = 0; delay_us(50); Aled3 = 1;
data = ~ maled7[led5]; Aled4 = 0; delay_us(50); Aled4 = 1;
data = ~ maled7[led4]; Aled5 = 0; delay_us(50); Aled5 = 1;
data = ~ maled7[led3]; Aled6 = 0; delay_us(50); Aled6 = 1;
data = ~ maled7[led2]; Aled7 = 0; delay_us(50); Aled7 = 1;
data = ~ maled7[led1]; Aled8 = 0; delay_us(50); Aled8 = 1;
}

vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
17 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
void main()
{
EA = 1;
EX0 = 1;
P2 = 0x00;
P0 = 0;
while (1)
{
convert_bcd(dem);
display();
}
}
03-03-2009, 06:18 PM
bạn hero_avr_pic ơi mình dùng thuật toán như bạn nói nhưng không hiểu sao khi mô phỏng bằng proteus mạch
lại không chạy. bạn có thể kiểm tra giúp mình không,hoặc ai trong diễn ñàn thạo C có thể giúp mình không.mình
cảm ơn nhiều
ñây là phần lập trình của mình
#include <at89x51.h>
#define Aled1 P2_0
#define Aled2 P2_1
#define Aled3 P2_2
#define Aled4 P2_3
#define Aled5 P2_4
#define Aled6 P2_5
#define Aled7 P2_6
#define Aled8 P2_7

#define data P0
unsigned char led1,led2,led3,led4,led5,led6,led7,led8;
unsigned char maled7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6 7};
unsigned long dem;
void demsanpham() interrupt 0
{
dem++;
}
void convert_bcd(unsigned long temp)
{
led8 = temp % 10;
temp = temp / 10;
led7 = temp % 10;
temp = temp / 10;
led6 = temp % 10;
temp = temp / 10;
led5 = temp % 10;
temp = temp / 10;
led4 = temp % 10;
temp = temp / 10;
led3 = temp % 10;
temp = temp / 10;
led2 = temp % 10;
temp = temp / 10;
led1 = temp % 10;
temp = temp / 10;
}
void delay_us(unsigned int x)
{
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong

file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
18 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
HERRO_AVR_PIC
unsigned int i;
for(i=0;i<x;i++) {}
}
void display()
{
data = ~ maled7[led8]; Aled1 = 0; delay_us(50); Aled1 = 1;
data = ~ maled7[led7]; Aled2 = 0; delay_us(50); Aled2 = 1;
data = ~ maled7[led6]; Aled3 = 0; delay_us(50); Aled3 = 1;
data = ~ maled7[led5]; Aled4 = 0; delay_us(50); Aled4 = 1;
data = ~ maled7[led4]; Aled5 = 0; delay_us(50); Aled5 = 1;
data = ~ maled7[led3]; Aled6 = 0; delay_us(50); Aled6 = 1;
data = ~ maled7[led2]; Aled7 = 0; delay_us(50); Aled7 = 1;
data = ~ maled7[led1]; Aled8 = 0; delay_us(50); Aled8 = 1;
}
void main()
{
EA = 1;
EX0 = 1;
P2 = 0x00;
P0 = 0;
while (1)
{
convert_bcd(dem);
display();
}
}

bạn cho xem file mô phỏng ñi
có vậy mới biết tại sao ko mô phỏng ñược chứ
03-03-2009, 06:51 PM
ñây là kết quả mô phỏng chương trình của bạn. Nói chung là chạy nhưng cần sửa chỗ chương trình phục vụ ngắt
1 chút:
void demsanpham() interrupt 0
{
EA=0;
while(!P3_2);
dem++;
EA=1;
}
[Only registered and activated users can see links]
03-03-2009, 07:55 PM
bạn hero_avr_pic ơi mình dùng thuật toán như bạn nói nhưng không hiểu sao khi mô phỏng bằng proteus mạch
lại không chạy. bạn có thể kiểm tra giúp mình không,hoặc ai trong diễn ñàn thạo C có thể giúp mình không.mình
cảm ơn nhiều
ñây là phần lập trình của mình
#include <at89x51.h>
#define Aled1 P2_0
#define Aled2 P2_1
#define Aled3 P2_2
#define Aled4 P2_3
#define Aled5 P2_4
#define Aled6 P2_5
#define Aled7 P2_6
#define Aled8 P2_7
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
19 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=

#define data P0
unsigned char led1,led2,led3,led4,led5,led6,led7,led8;
unsigned char maled7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6 7};
unsigned long dem;
void demsanpham() interrupt 0
{
dem++;
}
void convert_bcd(unsigned long temp)
{
led8 = temp % 10;
temp = temp / 10;
led7 = temp % 10;
temp = temp / 10;
led6 = temp % 10;
temp = temp / 10;
led5 = temp % 10;
temp = temp / 10;
led4 = temp % 10;
temp = temp / 10;
led3 = temp % 10;
temp = temp / 10;
led2 = temp % 10;
temp = temp / 10;
led1 = temp % 10;
temp = temp / 10;
}
void delay_us(unsigned int x)
{
unsigned int i;

for(i=0;i<x;i++) {}
}
void display()
{
data = ~ maled7[led8]; Aled1 = 0; delay_us(50); Aled1 = 1;
data = ~ maled7[led7]; Aled2 = 0; delay_us(50); Aled2 = 1;
data = ~ maled7[led6]; Aled3 = 0; delay_us(50); Aled3 = 1;
data = ~ maled7[led5]; Aled4 = 0; delay_us(50); Aled4 = 1;
data = ~ maled7[led4]; Aled5 = 0; delay_us(50); Aled5 = 1;
data = ~ maled7[led3]; Aled6 = 0; delay_us(50); Aled6 = 1;
data = ~ maled7[led2]; Aled7 = 0; delay_us(50); Aled7 = 1;
data = ~ maled7[led1]; Aled8 = 0; delay_us(50); Aled8 = 1;
}
void main()
{
EA = 1;
EX0 = 1;
P2 = 0x00;
P0 = 0;
while (1)
{
convert_bcd(dem);
display();
}
}
ñó chỉ là thuật toán ñơn giản ñể bạn có thể dựa vào ñó giải quyết vấn ñề vấn ñề thui còn ñể trở thành một
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
20 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
ganyfun

ganyfun
tranpic
trantuan25187
tranpic
trantuan25187
duongdaide2005
ganyfun
chương trình hoàn chỉnh bạn phải thêm các diều kiện ktra (ñảm bảo chính xác cho chương trình
mà):-c:-c:-c:-c:-c:-c:-c
03-04-2009, 08:55 AM
Tớ ñã mô phỏng thành công chương trình rồi cám ơn bạn hero_avr_pic và bạn tranpic nhé
03-04-2009, 09:01 AM
nhưng mà bạn tranpic ơi trong sơ ñồ nguyên lý của mình không có cổng not. ý mình là có phương pháp nào thay
cho cái cổng not ñó không,không dùng có ñược không? nếu không dùng thì phải như thế nào
03-04-2009, 11:20 AM
nhưng mà bạn tranpic ơi trong sơ ñồ nguyên lý của mình không có cổng not. ý mình là có phương pháp nào thay
cho cái cổng not ñó không,không dùng có ñược không? nếu không dùng thì phải như thế nào
cái cổng nót ñó thay cho con transistor chứ j
chỗ này dùng led anode (+) chung, bạn dùng mức thấp ñể kích led qua con PNP như vậy con PNP lúc này có vai
trò như cổng not rồi còn j.( tức kích mức - mà nó cho ra mức + ñể sáng led)
03-21-2009, 09:59 AM
anh tranpic và mọi người giúp em với,em mới học keil c,em chưa biết nhiều về LCD,các anh có thể mô tả vầ viết
cho em một ñoạn code về hiển thị ký tự cho LCD ñược không,em xin cảm ơn nhiều,nếu có thì cho em thêm hình
ảnh mô phỏng protues nha.
03-21-2009, 04:24 PM
mình ñã viết sẵn 1 cái thư viện cho lcd 16x2 ở ñây [Only registered and activated users can see links] bạn down
về sau ñó chép nó vào ñường dẫn C:\Keil\C51\INC sau ñó bạn vào keil gọi ra mà dùng nha,
chương trình ví dụ:
#include<at89x52.h>
#include<lcd.c>

void main()
{
P0=255;
P1=255;
P2=255;
P3=255;
int_lcd();
dat_str("Ton Duc Thang");
mov(1,5);
dat_str("Dien tu");
while(1);
}
[Only registered and activated users can see links]
03-22-2009, 09:50 AM
em cảm ơn anh nha
04-02-2009, 12:04 PM
bai hay,dang can ,cam on cac bac
04-12-2009, 05:34 PM
tranpic ơi lần trước bạn có mô phỏng giúp mình mạch ñếm sản phẩm mọi việc ñều ổn nhưng khi mình làm mạch
thật thì cái phần cảm biến hồng ngoại của mình nó lại chạy không như ý muốn. mình gửi mạch lên ñây nhờ bạn
xem giúp mình nha. trong mạch con biến trở không nêu rõ giá trị lên mình không biết dùng biến trở 10k có ñúng
không.
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
21 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
ganyfun
tranpic
ganyfun
tranpic
ganyfun

tranpic
trantuan25187
<a href="[Only registered and activated users can see links]" target="_blank"><img src="[Only registered and
activated users can see links]" border="0" alt="mach cam bien hong ngoai"></a>
mình làm mạch rồi nhưng nó không xuất ñược tín hiệu ra vi ñiều khiển. bạn giúp mình xem mạch này có ổn
không
04-12-2009, 05:36 PM
ñây là mạch của mình
[Only registered and activated users can see links]
04-13-2009, 01:58 AM
ủa con transistor c1815 bạn mắc ngược vậy sao chạy ñược mà ñòi có xung
04-13-2009, 07:18 AM
tranpic oi mac nhu the nao thi dung ban chi cho minh voi
04-13-2009, 12:03 PM
ñổi chân E với chân C lại chứ sao
04-13-2009, 09:30 PM
nhờ tranpic xem giúp mình xem mạch cảm biến hồng ngoại này dùng có ñược không mạch hông ngoại ở trên
mình post lên nó không xuất ñược xung sang vi diều khiển mà mình ñã ñổi chân E và C rồi vẫn không ñược
ñây là mạch của mình:
[Only registered and activated users can see links]
xem hộ mình nhe mình cảm ơn
04-13-2009, 10:13 PM
cả hai mạch theo mình ñều chạy hết chủ yếu là xem bạn có làm sai chỗ nào ko và bạn phải biết sửa sai
mạch 1 với ñiều kiện ñổi 2 chân E và C lại:
khi led nhận, nhận ñược hồng ngoài từ led phát thì nó làm thay ñổi ñiện áp tại chân +của con opam và bạn phải
chỉnh giá trị ñiện áp tại chân trừ của con opam sao cho khi led nhận nhận hồng ngoại thì ñiện áp tại chân + lớn
hơn ñiện áp tại chân - và khi ko nhận thì ñiện áp tại chân - lớn hơn ở chân +, như vậy khi ñiện áp ở chân + lớn
hơn ñiện áp ở chân - thì ngõ ra của opam là Vcc sẽ kích dẫn transistor và tạo ñược 1 cạnh xuống, khi ñiện áp tại
chân + bé hơn chân - thì ngõ ra của opam là gnd sẽ làm cho transistor ngừng dẫn => tạo ñược cạnh lên.
tương tự mạch dượi cũng vậy bạn à

04-22-2009, 12:06 AM
ñây là bài viết ñơn giản. Dựa trên phương pháp ñã nêu ở trên.
#include<AT89X52.h>
unsigned char ma=0;
void delay(unsigned char timer)
{
unsigned char x,y;
for (x=0;x<timer;x++) for(y=0;y<13;y++);
}
void display()
{
switch (ma)
{
case 0: P2=255;
break;
case 215: P2=64; //so 0
break;
case 235: P2=121;//so 1
break;
case 219: P2=36; //so 2
break;
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
22 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
ganyfun
ganyfun
unreal
case 187: P2=48; //so 3
break;
case 237: P2=25; //so 4

break;
case 221: P2=18; //so 5
break;
case 189: P2=2; //so 6
break;
case 238: P2=120;//so 7
break;
case 222: P2=128;//so 8
break;
case 190: P2=16; //so9
break;
}
}
void button()
{
unsigned char loop=0,get=0,bh=0;
for (loop=0;loop<=3;loop++)
{
P3=~(1<<loop);//quet
ma=0;
bh=P3>>4;
if (bh!=15)
{
ma=P3;
while(P3==ma)
{
display();
}
}
}

}
void main()
{
P3=255;
while(1)
{
P2=255;//tat led khi ko nhan
button();
}
}
chào các bạn,mình mới tìm hiểu về Keil C,anh tranpic có thể giải thích rõ hơn cho em hiểu về hàm button() ñược
ko,anh có thể giải thích thuật toán và chú thích từng dòng lệnh trong hàm button() ñược ko???em vẫn chưa hiểu
về hàm ñó,em xin cảm ơn
06-17-2009, 05:36 PM
lần trước mình làm mạch ñếm sản phẩm code viết rồi chạy mô phỏng cũng ñã chạy rồi nhưng mà khi làm mạch
thật thì code lại không chạy theo ý muốn. mình không biết code có sai không nhưng mô phỏng thấy chạy.
Transpic cũng mô phỏng chạy cho mình mình ñã cám ơn nhưng giờ làm mạch thật thì code ấy lại không
chạy,không biết làm sao bây giờ ai tư vấn cho mình với
06-17-2009, 05:37 PM
nó chạy lung tung lắm chả hiểu tại sao
06-17-2009, 06:40 PM
@trantuan : không biết mình có ñúng kg nhưng theo những gì mình biết thì nó như thế này :D
void button()
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
23 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
tranpic
ganyfun
tranpic
ganyfun

tranpic
daoxuankien
{
unsigned char loop=0,get=0,bh=0; // khai báo biến
for (loop=0;loop<=3;loop++) // dùng vòng lặp for quét 4 hàng phím
{
P3=~(1<<loop);
//quet dịch trái loop bit rồi ñảo trạng thái ñể quét hàng
// loop = 0 : p3 = 1110 ; loop = 1 : p3 = 1101 cứ thế ñến loop = 3
ma=0; // biến tạm lưu trữ mã phím
bh=P3>>4; // dịch phải 4 bit ñể lấy 4 bit cao. Rồi kt với 15 ( 1111) xem có bấm phím nào kg ?
if (bh!=15) // nếu có nhấn
{
ma=P3; // gán ma = gt ñưa vào p3
while(P3==ma) // trong khi còn nhấn thì gọi display() ñưa giá trị ra led
{
display();
}
}
}
}
06-17-2009, 11:05 PM
lần trước mình làm mạch ñếm sản phẩm code viết rồi chạy mô phỏng cũng ñã chạy rồi nhưng mà khi làm mạch
thật thì code lại không chạy theo ý muốn. mình không biết code có sai không nhưng mô phỏng thấy chạy.
Transpic cũng mô phỏng chạy cho mình mình ñã cám ơn nhưng giờ làm mạch thật thì code ấy lại không
chạy,không biết làm sao bây giờ ai tư vấn cho mình với
ai vậy mình làm mạch ñếm sản phẩm cho bạn à? sao ko nhớ nhỉ :^o:^o
06-18-2009, 05:46 PM
tranpic ơi ở ñầu trang 5 của mục này ấy bạn mô phỏng cho mình mạch ñếm sản phẩm nhưng không hiểu sao
code mô phỏng thì ñúng mà mạch thật thì nó chạy lung tung lắm. có gì không ổn không tranpic code mô phỏng

ấy, chỉ hộ tớ với. mạch tớ làm rồi nhưng nạp code vào chạy rất lung tung không theo ý muốn.
06-18-2009, 09:54 PM
tranpic ơi ở ñầu trang 5 của mục này ấy bạn mô phỏng cho mình mạch ñếm sản phẩm nhưng không hiểu sao
code mô phỏng thì ñúng mà mạch thật thì nó chạy lung tung lắm. có gì không ổn không tranpic code mô phỏng
ấy, chỉ hộ tớ với. mạch tớ làm rồi nhưng nạp code vào chạy rất lung tung không theo ý muốn.
bạn nói nó chạy lung tung là chạy sao. Quay video up lên tui nói cho,
led 7 ñoạn bạn dùng loại j, mạch làm sao,
06-28-2009, 04:07 PM
mình không có máy ảnh.mình dùng led anốt chung, mạch chạy hình dung như thế này : mạch ñếm lung tung lúc
số này lúc số khác và có 1 ñặc ñiểm là các led hiển thị giống nhau ( tức là chưa quét led ñược ñúng không) mình
không hiểu sao mô phỏng thì kết quả perfect mà khi làm mạch nạp code vào thì very bad! help me why? thank so
much!
06-28-2009, 08:40 PM
mình không có máy ảnh.mình dùng led anốt chung, mạch chạy hình dung như thế này : mạch ñếm lung tung lúc
số này lúc số khác và có 1 ñặc ñiểm là các led hiển thị giống nhau ( tức là chưa quét led ñược ñúng không) mình
không hiểu sao mô phỏng thì kết quả perfect mà khi làm mạch nạp code vào thì very bad! help me why? thank so
much!
bạn nên up cái mạch của bạn lên chứ nói vầy bó tay.:-O:-O:-O:-O:-O
06-29-2009, 01:05 PM
chào các bạn.mình cũng mới học VDK nhưng chưa biết nhiều lắm.Ai có giải thuật lập trình 8051 cho 32 led thì
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
24 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=
daoxuankien
unreal
tranpic
daoxuankien
HERRO_AVR_PIC
daoxuankien
daoxuankien

kidcdt
kidcdt
send cho dùm mình.hoặc up code lên ñây ñể những ai chưa biết như mình xem luôn.Mình xin cảm ơn.
06-29-2009, 03:59 PM
ai có code ñiều khiển 32 led sáng tắt dùng 8051 bằng ngôn ngữ c send cho mình qua mail
hoặc share code lên ñây cho ai chưa biết thì học hỏi.giúp mình với ñang cần gấp.
06-29-2009, 08:29 PM
Phải nói là 32 cái led ñó nó sáng tắt như thế nào chứ nói không không ai mà biết ñc. Sao giúp bạn ñược
Ai có cách nào ñk 32led mà chỉ dùng 1 port thôi ñc kg ?
06-29-2009, 09:18 PM
Phải nói là 32 cái led ñó nó sáng tắt như thế nào chứ nói không không ai mà biết ñc. Sao giúp bạn ñược
Ai có cách nào ñk 32led mà chỉ dùng 1 port thôi ñc kg ?
chỉ cần mấy chân thôi chứ cần j 1 port.
có rất nhiều cách ñể ñiều khiển ñược 32 hay nhiều hơn bằng 1 port; dùng ghi dich, ghi dịch+chốt (74595), phân
kênh, port mở rộng (mất 2 port) (chưa nghĩ ra)
tốt nhất là dùng 74595 vừa rẻ vừa viết ñược nhiều hiệu ứng.
07-07-2009, 09:22 PM
các bác có thể chỉ cho e lập trình 32 led tắt sáng thế nào cũng ñc.ý của e là xem các bác có giải thuật như thế
nào ñể từ ñó e có thể vận dụng và viết nhiều kiểu theo ý mình.Có thể sử dụng ít port càng tốt.các bác post cả
hình ảnh lên cho em dễ xem và học tập nha.e mới học vñk nên biết ít lắm.Cảm ơn các bác ñã bớt chút thời gian
quan tâm và trả lời cho em.
Nếu có thể thì send cho em code và sơ ñồ mạch nguyên lý cho em qua mai nha.Mail của em là
hoặc
Một lần nữa thank all.:-/
07-08-2009, 09:12 PM
các bác có thể chỉ cho e lập trình 32 led tắt sáng thế nào cũng ñc.ý của e là xem các bác có giải thuật như thế
nào ñể từ ñó e có thể vận dụng và viết nhiều kiểu theo ý mình.Có thể sử dụng ít port càng tốt.các bác post cả
hình ảnh lên cho em dễ xem và học tập nha.e mới học vñk nên biết ít lắm.Cảm ơn các bác ñã bớt chút thời gian
quan tâm và trả lời cho em.
Nếu có thể thì send cho em code và sơ ñồ mạch nguyên lý cho em qua mai nha.Mail của em là

hoặc
Một lần nữa thank all.:-/
cái của bạn hoàn toàn tương tự như viết một bảng ñèn quang báo vậy ñó
nên nếu bạn cần giải thuật, hay phần cứng cho việc ñiều khiển 32 con led thì mời qué thăm qua bài quang báo
cùng trong box này lun ban tranpic cũng có chỉ cách này, và có cả phần cứng
good luck:)):)):)):)):)):)):)):)):)):)):))
07-09-2009, 07:44 AM
cảm ơn bác nha.có gì em hỏi sau
07-09-2009, 11:16 AM
hjc bác cho em link ñến bài quang báo hộ em ñược không em không có thời gian tìm.thời gian thì gấp quá nên
các bác giúp em ñược không? thanks các bác trước.
09-10-2009, 09:47 PM
ñây này: [Only registered and activated users can see links]
cũng khá chi tiết ñó bạn!!!
09-10-2009, 09:59 PM
các bác có làm giao tiếp nối tiếp 1 8051 master với 2 8051 slaver chưa!! mình ñang làm nhưng gặp phải rắc rối tí
vi ñiều khiển họ 8051! với ngôn ngữ C [Lưu Trữ] - Welcome www.khong
file:///D:/HOC%20TAP/THUC%20HANH/Lap%20trinh/8051/vi%20
25 of 29 3/18/2010 12:36 =™‾£ø√ε‾™=

×