Bài 1: Ngôn ngữ C – Trình dịch Keil C
I. Ngôn ngữ C cho vi điều khiển
1, Giới thiệu ngôn ngữ C
Trong kỹ thuật lập trình vi điều khiển nói chung, ngôn ngữ lập trình được sử dụng thường chia làm 2 loại: Ngôn ngữ bậc thấp và Ngôn ngữ bậc cao.
Ngôn ngữ bậc cao là các ngôn ngữ gần vơi ngôn ngữ con người hơn, do đó việc lập trình bằng các ngôn ngữ này trở nên dễ dàng và đơn giản hơn. Có thể kể đến một số ngôn ngữ lập trình bậc cao như C, Basic, Pascal trong dó C là ngôn
ngữ thông dụng hơn cả trong kỹ thuật vi điều khiển. Về bản chất, sử dụng các ngôn ngữ này thay cho ngôn ngữ bậc thấp là giảm tải cho lập trình viên trong việc nghiên cứu các tập lệnh và xây dựng các cấu trúc giải thuật. Chương trình viết bằng ngôn ngữ bậc cao cũng sẽ được một phần mềm trên máy tính gọi là trình biên dịch (Compiler) chuyển sang dạng hợp ngữ trước khi chuyển sang mã máy.
81 trang |
Chia sẻ: phuongt97 | Lượt xem: 365 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Đề cương bài giảng Ứng dụng lập trình C cho vi điều khiển 8051, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ế độ khác của bộ định thời là chế độ 0(chế độ bộ định thời 13 bit, bộ định thời/bộ đếm 8 bit, định tỷ lệ trước 5 bit ) và chế độ 3(chế độ bộ định thời chia tách) ở đay không giới thiệu.
1.2. Ngắt của bộ định thời.
- nguyên tắc sử dụng bộ định thời ở chế độ ngắt:
+ khai báo ngắt của bộ định thời muốn sử dụng
+ nguồn gây ngắt.
+ chương trình chính và chương trình phục vụ ngắt.
- với ngắt định thời việc khai báo nguồn ngắt bao gồm việc khai báo ngắt toàn cục là EA = 1 và khai báo ngắt cho từng bộ định thời muốn dùng ET0 = 1(timer0) và ET1 = 1(timer1)
- Nguồn báo ngắt định thời(với cả 2 chế độ) đều là khi bộ đếm tràn(khi cờ TFx = 1), khi cờ TFx = 1 thì vi điều khiển kết thúc công việc hiện tại ở chương trình chính và chuyển vào chương trình phục vụ ngắt căn cứ theo địa chỉ của chương trình phục vụ ngắt.khi thực hiện xong chương trình phục vụ ngắt vi điều khiển quay trở về chương trình tại nơi bị gián đoạn khi trước.
- Tóm lại ngắt định thời là việc ta sử dụng bộ định thời tạo trễ một khoảng thời gian được tính toán trước, sau khoảng thời gian này 1 công việc ta mong muốn sẽ được thực hiện ở chương trình phục vụ ngắt. công việc đó có thể coi là độc lập với công việc ở chương trình chính
- các công việc lập trình sử dung ngắt định thời :
+ tính toán thời gian trễ mong muốn và công việc muốn thực hiện sau khoảng thời gian đó.
+ khai báo ngắt định thời trong chương trình chính (EA=1, ETX=1).
+ lựa chon bộ định thời và chế độ của nó trong thanh ghi TMOD
+ khởi động bộ định thời.
+ Xây dựng chương trình chính và các chương trình con cần thiết.
+ xây dựng chương trình phục vụ ngắt thực hiện 1 công việc mong muốn (xác định rõ địa chỉ ngắt theo thứ tự ngắt trong bảng vector ngắt)
- Chú ý: trong chương trình phục vụ ngắt các bạn phải xoá cờ báo tràn TFx và nạp lại giá trị cho bộ định thời với chế độ 1 còn chế độ 2 thì không cần.
1.3. bài toán:
Bài toán 1: sử dụng bộ định thời với ngắt của nó tạo một xung vuông với tần số 1kHZ đối xứng (50% mức 1 và 50% mức 0 ) trên chân P1.0.
Bài giải:
- ta có : f = 1kHZ → T = 1/1000s = 1000us → TON = TOFF = T/2 = 500us. Như vậy chu kì xung là đối xứng nên hai phần này bộ đếm đếm giống nhau(tạo trễ khoảng thời gian bằng nhau). nửa chu kì đầu bộ đếm tạo trễ 500us cho mức 0, sau khi bộ đếm đếm đến giá trị đỉnh của thanh ghi chứa là FFFF thì cờ báo TFx = 1 gây ngắt, vi điều khiển phải chuyển vào chương trình phục vụ ngắt và sẽ lật trạng thái xung ra. Trong nửa chu kì còn lại cũng như vậy và cứ như thế.
- Do thời gian trễ là 500us do đó ta chọn chế độ 16 bit, sử dụng kết quả từ ví dụ trên để nạp giá trị ban đầu cho TH và TL.
- Chương trình điều khiển:
/*================khai bao thu vien===============*/
#include
/*=============khai bao bien=====================*/
sbit xung = P1^0;
/*==============khai bao ham ==================*/
/*--------------------------chuong trinh phuc vu ngat timer0 tao xung--------------------*/
void timer0_int(void) interrupt 1
{
TF0=0; // xoa co bao tran timer0
xung = !xung; // tao muc 1 ra chan P1.0
TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz)
TL0 = 0x0c;
}
/*=============chuong trinh chinh=============*/
void main(void)
{
EA = 1; // cho phep ngat toan cuc
ET0 = 1; // cho phep ngat T0
TMOD = 0x01; // timer0 che do 1
xung = 0; //gia tri ban dau cua xung muon tao
TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz)
TL0 = 0x0c;
TR0 = 1; // khoi dong timer
while(1) PCON|=1; //khong lam gi ca de doi ngat.
}
Bài toán 2: sử dụng bộ định thời với ngắt của tạo đồng hồ số hiển thị lên LCD.
+ Chương trình:
/*================khai bao thu vien===============*/
#include
#include
#define LCDdata P2
sbit RS=P3^0;
sbit RW=P3^1;
sbit EN=P3^2;
sbit BF=LCDdata^7;
#include"lcd.h"
/*=============khai bao bien=====================*/
unsigned char data Time[8];
unsigned char data i;
/*==============khai bao ham ==================*/
void T10ms(void) interrupt 1 using 0
{
TR0=0;
TH0=0xD8;
TL0=0xEF;
TR0=1;
if(Time[0]==9){
Time[0]=0;
if(Time[1]==9){
Time[1]=0;
if(Time[2]==9){
Time[2]=0;
if(Time[3]==5){
Time[3]=0;
if(Time[4]==9){
Time[4]=0;
if(Time[5]==5){
Time[5]=0;
if(Time[6]==9&&Time[7]<2){
Time[6]=0;
Time[7]++;
}else if(Time[6]==3&&Time[7]==2){
Time[6]=0;
Time[7]=0;
}else Time[6]++;
}else Time[5]++;
}else Time[4]++;
}else Time[3]++;
}else Time[2]++;
}else Time[1]++;
}else Time[0]++;
LCDwrite(Time[7]+48);LCDwrite(Time[6]+48);LCDwrite(':');
LCDwrite(Time[5]+48);LCDwrite(Time[4]+48);LCDwrite(':');
LCDwrite(Time[3]+48);LCDwrite(Time[2]+48);LCDwrite(':');
LCDwrite(Time[1]+48);LCDwrite(Time[0]+48);
LCDcontrol(0xC0);
}
/*==============Chuong trinh chinh ==================*/
void main()
{
TMOD|=1;
EA=1;
ET0=1;
TH0=0xD8;
TL0=0xEF;
for(i=0;i<8;i++)Time[i]=0;
LCDinit();
LCDwrites("Dong ho so");
LCDcontrol(0xC0);
TR0=1;
while(1)PCON|=1;
}
2. Lập trình với các ngắt ngoài của vi điều khiển.
2.1. Khái niệm:
- bộ vi điều khiển 8051có hai ngắt ngoài là INT0 và INT1 với 2 chân tác động đầu vào tương ứng là P3.2 và P3.3.
- Ngắt ngoài là ngắt của vi điều khiển mà tác động ngắt ở đây chính là các tác động bên ngoài của vi điều khiển tác động vào vi điều khiển thong qua các chân ngắt đưới dạng một tín hiệu điện áp dạng xung.
- tác động ngắt ngoài có hai dạng là tác động theo dạng mức và dạng sườn.
+ kích hoạt theo mức: ở chế độ này các chân INT0 và INT1 bình thường ở mức cao giống như các chân khác của vi điều khiển, khi có tín hiệu mức thấp cấp tới thì tín hiệu này kích hoạt ngắt. lưu ý là trước khi thực hiện lệnh cuối cùng của chương trình phục vụ ngắt thì mức thấp tại các chân ngắt phải được chuyển lên mức cao, nếu không sẽ lại gây ra một ngắt ngay lập tức.
+ Kích hoạt theo sườn: bình thường các chân ngắt của vi điều khiển ở mức cao, khi có tín hiệu tác động vào chúng có dạng sườn xuống thì sẽ tác động ngắt.
- Để sử dụng chế độ ngắt này thì phải tác động vào thanh ghi TCON cụ thể là TCON.1=1 hoặc IT0=1 thì cho phép ngắt ngoài 0 kích hoạt sườn, còn TCON.2=1 hoặc IT1=1 thì cho phép ngắt ngoài 1 kích hoạt sườn.
2.2. cách lập trình:
- Để lập trình cho ngắt của vi điều khiển ta phải thực sự hiệu bản chất của ngắt và quá trình thực hiện ngắt của vi điều khiển diễn ra.
- mẫu viết hàm ngắt như sau:
Void name(void)interrupt x(x là số thứ tự ngắt ngoài x = 0 hoặc 2)
{
//chương trình phục vụ ngắt
}
- Trong chương trình chính ta phải có thao tác thiết lập việc cho phép các ngắt được sử dụng.
2.3. bài toán:
sử dụng ngắt ngoài của vi điều khiển với nhiệm vụ là: bình thường vi điều khiển bật một Led đơn tại chân P1.0 và khi có ngắt ngoài thì tắt Led ở P1.0 và bật Led ở chân P1.1 sau 1s thì bật lại Led P1.0 và tắt Led P1.1.
Bài giải:
/*==================Bo tien xu li===================*/
#include // Dinh kem file thu vien
#define bat 1 // Dinh nghia gia tri bat den Led
#define tat 0 // Dinh nghia gia tri tat den Led
/*==================khai bao bien==================*/
sbit Led1 = P1^0; // Khai bao bi?n Led ki?u bit chan P1.0
sbit Led2 = P1^1; // Khai bao bi?n Led ki?u bit chan P1.0
/*================= Khai bao hàm==================*/
/*------------------------------ham tre -------------------------------------*/
void delay(long time)
{
while(time--);
}
void INT_0(void) interrupt 0 // chuong trinh phuc vu ngat
{
Led1=tat;
Led2=bat;
delay(25000);
Led1=bat;
Led2=tat;
}
/*--------------------------------ham chinh--------------------------------*/
void main(void)
{
EA=1; // cho phep ngat toan cuc
EX0=1; // cho phep ngat ngoai 0
IT0=1; //ngat kich phat suon
Led1=bat;
Led2=tat;
while(1);
}
Bài 6: Điều khiển động cơ DC, động cơ Servo, động cơ bước
1. Đông cơ DC
2. Động cơ Servo
3. Động cơ bước (Step motor)
Điều khiển động cơ bước với tốc độ tăng dần từ 5 đến 100 v/p, mỗi lần chuyển tốc độ tăng 5v/p thời gian chuyển 1s, hiển thị tốc độ trên LCD.
+ Chương trình:
#include
#include
#define LCDdata P2
sbit RS=P3^0;
sbit RW=P3^1;
sbit EN=P3^2;
sbit BF=LCDdata^7;
#include"lcd.h"
unsigned char data Bytecao1,Bytethap1;
unsigned char data Buoc,Nbuoc;
unsigned char data Mbuoc[4]={144,192,96,48};
void viewspeed(unsigned char speed);
void Xuly(unsigned char Nspeed);
void Dkdongco(void) interrupt 1 using 0
{
TR0=0;
TH0=Bytecao1;
TL0=Bytethap1;
TR0=1;
P1=Mbuoc[Buoc];
Buoc++;
if(Buoc==4)Buoc=0;
}
void Xuly(unsigned char speed)
{
unsigned int data Chuki1,Chuki2;
unsigned int data tam1,tam2;
TR0=0;
viewspeed(speed);
Nbuoc=200;
tam2=10000/Nbuoc;
tam1=6000/speed;
Chuki1=tam1*tam2;
Chuki2=65535-Chuki1;
Bytecao1=Chuki2/256;
Bytethap1=Chuki2%256;
TR0=1;
}
void delay(unsigned long time)
{
while(time--);
}
void viewspeed(unsigned char speed)
{
unsigned char data a1,a2;
LCDcontrol(0xc0);
a1=speed%10;
speed=speed/10;
a2=speed%10;
speed=speed/10;
LCDwrite(speed+48);
LCDwrite(a2+48);
LCDwrite(a1+48);
LCDwrites("(vong/phut)");
}
void main()
{
unsigned char data i;
TMOD=17;
EA=1;
LCDinit();
ET0=1;
LCDcontrol(0x80);
LCDwrites("CT DK DC buoc" );
LCDcontrol(0xc0);
LCDwrites("V:5-100(v/p)");
delay(100000);
while(1){
Buoc=2;
for(i=5;i<101;i=i+5){
LCDcontrol(0x01);
LCDcontrol(0x80);
LCDwrites("CT DK DC buoc" );
Xuly(i);
delay(500000);
}
}
}Bài 7: Giao tiếp Vi điều khiển với Máy tính
I. Cổng truyền thông nối tiếp
1. Thanh ghi SCON – SBUF
II. Xây dựng chương trình
1. Chương trình VB
+ Giao diện
+ Thuật toán
+ Chương trình:
Option Explicit
Dim Mau As Byte
Private Sub cbcolor_Click()
If (cbcolor.Text = "Mau do") Then
Mau = 1
txtchu.ForeColor = &HFF&
lbHienthi.ForeColor = &HFF&
ElseIf (cbcolor.Text = "Mau xanh") Then
Mau = 2
txtchu.ForeColor = vbGreen
lbHienthi.ForeColor = &HFF00&
ElseIf (cbcolor.Text = "Mau cam") Then
Mau = 3
txtchu.ForeColor = &H80FF&
lbHienthi.ForeColor = &H80FF&
End If
End Sub
Private Sub cbcolor_GotFocus()
SendKeys "%{DOWN}"
End Sub
Private Sub cmdCode_Click()
MsgBox Code(txtchu)
End Sub
Private Sub cmdExit_Click()
If MSComm1.PortOpen Then
MSComm1.PortOpen = False
End If
End
End Sub
Function Code(s As String) As String
Dim i As Integer
s = Replace(s, " ", "")
For i = 1 To Len(s)
Code = Code & " " & Asc(Mid(s, i, 1))
Next
End Function
Private Sub OpenPort()
Dim s As String
MSComm1.Settings = "57600,N,8,1"
MSComm1.CommPort = 1
MSComm1.PortOpen = True
MSComm1.InputLen = 0
s = MSComm1.Input
MsgBox "Port did open"
End Sub
Private Sub cmdOpenport_Click()
If MSComm1.PortOpen Then
MSComm1.PortOpen = False
End If
OpenPort
End Sub
Private Sub cmdSend_Click()
Dim s As String
If MSComm1.PortOpen = False Then
MsgBox "Port did not open"
OpenPort
End If
If MSComm1.PortOpen Then
txtchu.Text = UCase(txtchu.Text)
s = Chr(Mau) & Chr(Len(txtchu.Text)) & txtchu.Text & Chr(255)
Do While (MSComm1.OutBufferCount > 0)
Loop
MSComm1.Output = s
End If
End Sub
Private Sub cmdStop_Click()
MSComm1.Output = Chr(250)
MsgBox "Port Stoped"
End Sub
Private Sub Form_Load()
txtchu.ForeColor = vbRed
txtchu.Text = "DO AN GHEP NOI"
Mau = 1
End Sub
Private Sub Form_Resize()
If (Me.WindowState = 1) Then
Me.Height = 4000
Me.Width = 7230
End If
End Sub
Private Sub txtchu_GotFocus()
txtchu.SelStart = 0
txtchu.SelLength = Len(txtchu)
End Sub
2. Chương trình vi điều khiển
+ Thuật toán
+ Chương trình:
/************Khai bao tien xy ly***************/
#include
/*********Dinh nghia hang so mau**********/
#define Mdo 1
#define Mxanh 2
#define Mcam 3
/*****Khai bao mang ki tu gom chu so va chu cai****/
unsigned char code Mchar[36][7]={
48,0,126,129,129,129,126,/*0*/
49,0,0,33,65,255,1,/*1*/
50,0,99,135,137,145,97,/* 2 */
51,0,66,129,145,145,110,/* 3 */
52,0,24,40,72,255,8,/* 4 */
53,0,226,145,145,145,142,/* 5 */
54,0,118,137,137,137,70,/* 6 */
55,0,128,135,136,144,224,/* 7 */
56,0,110,145,145,145,110,/* 8 */
57,0,102,145,145,145,110,/* 9 */
65,0,63,72,136,72,63,/* A */
66,0,255,145,145,145,110,/* B */
67,0,126,129,129,129,70,/* C */
68,0,255,129,129,129,126,/* D */
69,0,255,145,145,145,129,/* E */
70,0,255,144,144,144,128,/* F */
71,0,126,129,129,137,78,/* G */
72,0,255,16,16,16,255,/* H */
73,0,129,129,255,129,129,/* I */
74,0,2,129,130,252,128,/* J */
75,0,255,24,36,66,129,/* K */
76,0,255,1,1,1,1,/* L */
77,0,255,64,32,64,255,/* M */
78,0,255,96,24,6,255,/* N */
79,0,126,129,129,129,126,/* O */
80,0,255,144,144,144,96,/* P */
81,0,126,129,133,130,125,/* Q */
82,0,255,144,144,144,111,/* R */
83,0,98,144,144,144,78,/* S */
84,0,128,128,255,128,128,/* T */
85,0,254,1,1,1,254,/* U */
86,0,252,2,3,2,252,/* V */
87,0,255,12,3,12,255,/* W */
88,0,199,40,16,40,199,/* X */
89,0,224,16,15,16,224,/* Y */
90,0,131,133,153,161,193/* Z */
};
/*******Dinh nghia cac chan va cac cong dieu khien*****/
sfr Pxanh=0x90;
sfr Pdo=0xA0;
sbit Clear=P3^4;
sbit Data=P3^3;
sbit Clock=P3^2;
/**************Khai bao bien toan cuc*************/
unsigned char data Ktnhan,nhanmau,j,i,Maxc,Count,nLap;
unsigned char data Mau,Chay,tam,dem;
unsigned char data MC[76],MQ[32];
/**********Khoi ham chuong trinh**********/
// Ham ngat noi tiep
void Ngatnoitiep(void) interrupt 4 using 0
{
if(RI){
RI=0;
tam=SBUF;
if(tam==250){
Chay=1;i=j=77;dem=8;
Count=0;
Clear=0;
}else{
if(nhanmau){
Mau=tam;
Chay=1;i=j=77;dem=8;
Count=nhanmau=0;
P1=P2=0;
Clear=0;
}else if(tam==255){
Clear=1;
Chay=0;
Ktnhan=nhanmau=1;
}else{
if(Ktnhan){
Maxc=tam;
Ktnhan=0;
}else if(Count<76&&Count<Maxc){
MC[Count]=tam;
Count++;
}
}
}
}
}
void Khoitao(void)
{
PCON|=128;
EA=1;
ES=1;
SM0=0;
SM1=1;
Ktnhan=nhanmau=1;
Chay=1;
P0=P1=P2=0;
P3_0=1;
nLap=1;
}
// Ham tao tre
void delay(void)
{
unsigned char data i;
i=10;
while(i--);
}
// Ham hien thi mau cam
void Cam(void)
{
while(nLap--)
{
Data=1;
for(j=0;j<32;j++){
Clock=1;
Data=0;
Clock=0;
Pdo=Pxanh=MQ[j];
delay();
Pxanh=Pdo=0;
}
}
}
// Ham hien thi mau xanh
void Xanh(void)
{
while(nLap--)
{
Data=1;
for(j=0;j<32;j++){
Clock=1;
Data=0;
Clock=0;
Pxanh=MQ[j];
delay();
Pxanh=0;
}
}
}
// Ham hien thi mau do
void Do(void)
{
while(nLap--)
{
Data=1;
for(j=0;j<32;j++){
Clock=1;
Data=0;
Clock=0;
Pdo=MQ[j];
delay();
Pdo=0;
}
}
}
// Ham thay doi mang hien thi
void change(void)
{
MQ[0]=MQ[1];MQ[1]=MQ[2];MQ[2]=MQ[3];MQ[3]=MQ[4];
MQ[4]=MQ[5];MQ[5]=MQ[6];MQ[6]=MQ[7];MQ[7]=MQ[8];
MQ[8]=MQ[9];MQ[9]=MQ[10];MQ[10]=MQ[11];MQ[11]=MQ[12];
MQ[12]=MQ[13];MQ[13]=MQ[14];MQ[14]=MQ[15];MQ[15]=MQ[16];
MQ[16]=MQ[17];MQ[17]=MQ[18];MQ[18]=MQ[19];MQ[19]=MQ[20];
MQ[20]=MQ[21];MQ[21]=MQ[22];MQ[22]=MQ[23];MQ[23]=MQ[24];
MQ[24]=MQ[25];MQ[25]=MQ[26];MQ[26]=MQ[27];MQ[27]=MQ[28];
MQ[28]=MQ[29];MQ[29]=MQ[30];MQ[30]=MQ[31];
}
// Ham tim vitri ki tu hien thi trong bang chu cai va chu so
unsigned char Chiso(unsigned char chr)
{
unsigned char data End,Start,Mid,Mctam;
if(chr==Mchar[0][0]){
return 0;
}else if(chr==Mchar[35][0]){
return 35;
}else{
End=35;
Start=0;
while(1){
Mid=(End+Start)/2;
Mctam=Mchar[Mid][0];
if(chr==Mctam){
return Mid;
}else if(chr<Mctam){
End=Mid;
}else{
Start=Mid;
}
}
}
}
void Chaychu(void)
{
unsigned char vitri;
for(j=0;j<32;j++){
MQ[j]=0;
}
for(i=0;i<Count;i++)
{
if(MC[i]==32){
change();
MQ[31]=0;
if(Mau==Mxanh)Xanh();
else if(Mau==Mdo)Do();
else Cam();
change();
MQ[31]=0;
if(Mau==Mxanh)Xanh();
else if(Mau==Mdo)Do();
else Cam();
}else{
vitri=Chiso(MC[i]);
for(dem=1;dem<7;dem++){
change();
MQ[31]=Mchar[vitri][dem];
if(Mau==Mxanh)Xanh();
else if(Mau==Mdo)Do();
else Cam();
}
}
}
if(!Chay){
for(i=0;i<32;i++){
change();
MQ[31]=0;
if(Mau==Mxanh)Xanh();
else if(Mau==Mdo)Do();
else Cam();
}
}
}
// Chuong trinh chinh
void main()
{
Khoitao();
REN=1;
while(1){
while(Chay);
Chaychu();
}
}
Các file đính kèm theo tài liệu này:
- de_cuong_bai_giang_ung_dung_lap_trinh_c_cho_vi_dieu_khien_80.doc