1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Giáo trình vi điều khiển cơ bản dùng c++

57 1,8K 45
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Giáo Trình Vi Điều Khiển Cơ Bản Dùng C++
Trường học Trường Đại Học Công Nghệ
Chuyên ngành Vi Điều Khiển
Thể loại Giáo Trình
Định dạng
Số trang 57
Dung lượng 1,1 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

giáo trình vi điểu khiển cở bản bằng ngôn ngữ lập trình C

Trang 1

Ngôn ngữ lập trình C cơ bản cho 8051

Ngôn Ng L p Trình C C B n Cho 8051 ữ Lập Trình C Cơ Bản Cho 8051 ập Trình C Cơ Bản Cho 8051 ơ Bản Cho 8051 ản Cho 8051

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 Khi sử dụng ngôn ngữ C người lập trình không cần hiểu sâu sắc về cấu trúc của bộ

vi điều khiển Có nghĩa là với một người chưa quen với một vi điểu khiển cho trước sẽ xây dựng được chương trình một cách nhanh chóng hơn, do không phải mất thời gian tìm hiểu kiến trúc của vi điều khiển đó Và việc sử dụng lại các chương trình đã xây dựng trước đó cũng dễ dàng hơn, có thể sử dụng toàn bộ hoặc sửa chữa một phần.

2 Ngôn ngữ C

2.1 Kiểu dữ liệu

2.1.1 Kiểu dữ liệu trong C

Trang 2

Kiểu Số Byte Khoảng giá trị

* Khai báo biến:

- Cú pháp: Kiểu_dữ_liệu Vùng_nhớ Tên_biến _at_ Đia_chỉ;

Ví dụ: Unsigned char data x;

- Khi khai báo biến có thể gán luôn cho biến giá trị ban đầu.

Ví dụ: Thay vì: unsigned char x;

x = 0;

Ta chỉ cần: unsigned char x = 0;

- Có thể khai báo nhiều biến cùng một kiểu một lúc.

Ví dụ: Unsigned int x,y,z,t;

Trang 3

- Chỉ định vùng nhớ: từ khoá “Vùng_nhớ” cho phép người dùng có thể chỉ ra vùng nhớ sử dụng để lưu trữ các biến sử dụng trong chương trình Các vùng nhớ có thể

sử dụng là:

CODE, DATA, DATAB, IDATA, PDATA, XDTA Khi không khai báo vùng nhớ trình dịch Keil C sẽ mặc định đó là vùng nhớ DATA.

CODE Bộ nhớ mã nguồn chương trình

DATA Bộ nhớ dữ liệu gồm 128 Byte thấp của RAM trong vi điều khiển

BDATA Bộ nhớ dữ liệu có thê định địa chỉ bit, nằm trong vùng nhớ DATA

IDATA Bộ nhớ dữ liệu gồm 128 Byte cao của RAM trong vi điều khiển chỉ có

ở một số dòng vi điều khiển sau này

PDATA Bố nhớ dữ liệu ngoài gồm 256 Byte, được truy cập bởi địa chỉ đặt

trên P0

XDATA Bộ nhớ dữ liệu ngoài có dung lượng có thể lên đến 64 KB, được truy

cập bởi địa chỉ đặt trên P0 và P2

* Định nghĩa lại kiểu

- Cú pháp: Typedef Kiễu_dữ_liệu Tên_biến;

- Tên_biến sau này sẽ được sử dụng như một kiểu dữ liệu mới và có thể dùng để khai báo các biến khác.

Ví dụ: Typedef int m5[5];

Trang 4

Dùng tên m5 khai báo hai biến tên a và b có kiểu dữ liệu là mảng 1 chiểu 5 phần tử: m5 a,b;

2.1.2 Kiểu dữ liệu trong Keil C

- sbit, sfr, sfr16: dùng để định nghĩa các cho các thanh ghi chức năng hoặc các cổng trên vi điều khiển dùng để truy nhập các đoạn dữ liệu 1 bit, 8 bit, 16 bit.

2.1.3 Mảng

Mảng là một tập hợp nhiều phần tử cùng một kiểu giá trị và chung một tên Các phần tử của mảng phân biệt với nhau bởi chỉ số hay số thứ tự của phần tử trong dãy phẩn tử Mỗi phần tử có vai trò như một biến và lưu trữ được một giá trị độc lập với các phần tử khác của mảng.

Mảng có thể là mảng một chiều hoặc mảng nhiều chiều.

Trang 5

Khai báo:

- Cú pháp: Tên_kiểu Vùng_nhớ Tên_mảng[số_phần_tử_mảng];

Khi bỏ trống số phần tử mảng ta sẽ có mảng có số phần tử bất kì.

Ví dụ: Unsigned int data a[5],b[2] [3];

Với khai báo trên ta sẽ có: mảng a là mảng một chiều 5 phần tử Mảng b là mảng hai chiều, tổng số phần tử là 6.

Chỉ số của mảng bắt đầu từ số 0 Mảng có bao nhiêu chiều phải cung cấp đầy đủ bấy nhiêu chỉ số.

Ví du: Phần tử mảng 2 chiều:

b[0] [1] là đúng

Khi viết: b[0] là sai

2.1.4 Con trỏ

Khi ta khai báo một biến, biến đó sẽ được cấp phát một khoảng nhớ bao gồm một

số byte nhất định dùng để lưu trữ giá trị Địa chỉ đầu tiên của khoảng nhớ đó chính là địa chỉ của biến được khai báo.

Con trỏ là một biến dùng để chứa địa chỉ mà không chứa giá trị, hay giá trị của con trỏ chính là địa chỉ khoảng nhớ mà nó trỏ tới.

Trang 6

Với các vùng nhớ cụ thể con trỏ tới vùng nhớ đó chiếm dung lượng phụ thuộc vào

độ lớn của vùng nhớ đó Con trỏ tổng quát khi không xác định trước vùng nhớ sẽ

có dung lượng lớn nhất vì vậy tốt nhất nên sử dụng con trỏ cụ thể.

Loại con trỏ Kích thước

Con trỏ tổng quát 3 byte

Khai báo biến con trỏ:

- Cú pháp: Kiểu_Dữ_liệu Vùng_nhớ *Tên_biến;

- Ví dụ: int *int_ptr;

long data *long_ptr;

- khi không chỉ rõ vùng nhớ con trỏ sẽ được coi là con trỏ tổng quát.

2.1.5 Kiểu dữ liệu cấu trúc

Trang 7

Kiểu dữ liệu cấu trúc là một tập hợp các biến, các mảng và cả các kiểu cấu trúc khác được biểu thị bởi một tên duy nhất kiểu dữ liệu cấu trúc dùng để lưu trữ các giá trị, thông tin có liên quan đến nhau.

Định nghĩa và khai báo biến cấu trúc:

- Định nghĩa: Typedef struct {

Khai báo các biến thành phần;

Trang 8

Trong đó Biến_2 có thể là giá trị xác định cũng có thể là biến.

Trang 9

& Phép và (AND) Bit_1 & Bit_2

^ Phép hoặc loại trừ (XOR) Bit_1 ^ Bit_2

Trang 10

*= a*=5 <=> a=a*5 /= a/=5 <=> a=a/5

%= a%=5 <=> a=a%5

2.3 Cấu trúc chương trình C

2.3.1 Cấu trúc chương trình

* Cấu trúc:

1 Khai báo chỉ thị tiền xử lý

2 Khai báo các biến toàn cục

3 Khai báo nguyên mẫu các hàm

4 Xây dựng các hàm và chương trình chính

* Ví dụ:

// Khai báo chỉ thị tiền xử lý:

Trang 11

#include<string.h>

#define Led1 P1_0

//********************************* // Khai báo biến toàn cục:

Unsigned char code Led_arr[3];

Unsigned char data dem;

Unsigned int xdata X;

//********************************* // Khai báo nguyên mẫu hàm

Void delay(unsigned int n);

bit kiemtra(unsigned int a);

//********************************* // Xây dựng các hàm và chương trình chính: void delay(unsigned int n)

Trang 12

Mã chương trình chính;

}

Bit kiemtra(unsigned int a)

{

Khai báo biến cục bô;

Mã chương trình kiểm tra biến a;

}

Chú ý: Hàm không khai báo nguyên mẫu phải được xây dựng trước hàm có lời gọi

hàm đó Ở ví dụ trên do hàm “bit kiemtra(unsigned int a)” đã được khai báo nguyên mẫu hàm ở trên nên có thể xây dựng hàm ở bất kì vị trí nào trong chương trình.

Tuy nhiên chúng ta nên khai báo nguyên mẫu hàm trước hàm main, và xây dựng các hàm phụ ở sau hàm main Như thế sẽ tạo thói quen lập trình gọn gàng hơn, và cũng tạo thuận lợi hơn cho việc xem lại code, tìm kiếm và sửa lỗi sau này.

2.3.2 Chỉ thị tiền xử lý

Các chỉ thị tiền sử lý không phải là các lệnh của ngôn ngữ C mà là các lệnh giúp cho việc soạn thảo chương trình nguồn C trước khi biên dịch Khi dịch một chương trình C thì không phải chính bản chương trình nguồn mà ta soạn thảo được dịch Trước khi dịch, các lệnh tiền xử lý sẽ chỉnh lý bản gốc, sau đó bản chỉnh

lý này sẽ được dịch Có ba cách chỉnh lý được dùng là:

+ Phép thay thế #Define

Trang 13

+ Phép chèn tệp #Include

+ Phép lựa chọn biên dịch #Ifdef

Các chỉ thị tiền xử lý giúp ta viết chương trình ngắn gọn hơn và tổ chức biên dịch, gỡ rối chương trình linh hoạt, hiệu quả hơn.

* Chỉ thị #Define: Chỉ thị #define cho phép tạo các macro thay thế đơn giản.

- Cú pháp: #Define Tên_thay_thế dãy_kí_tự

Một Tên_thay_thế có thể được định nghĩa lại nhiều lần, nhưng trước khi định nghĩa lại phải giải phóng định nghĩa bằng chỉ thị:

#Undef Tên_thay_thế

- Ví dụ: #define N 100

* Chỉ thị #Include: Chỉ thị #include báo cho trình biên dịch nhận nội dung của tệp

khác và chèn vào tệp chương trình nguồn mà ta soạn thảo.

- Cú pháp:

Cách 1: #include<tên_tệp>

Cách 2: #include“tên_tệp”

Trang 15

Ở cách 1: nếu tên_macro đã được định nghĩa thì “Đoạn chương trình” sẽ được dịch, ngược lại thì “Đoạn chương trình” sẽ bị bỏ qua.

* Chỉ thị #Ifndef: Chỉ thị #ifndef này thường dùng để biên dịch các tệp thư viện.

Ở cách 1: nếu tên_macro chưa được định nghĩa thì “Đoạn chương trình” sẽ được

dịch, ngược lại thì “Đoạn chương trình” sẽ bị bỏ qua.

2.3.3 Chú thích trong chương trình

Việc viết chú thích trong trình nhằm mục đích giải thích ý nghĩa của câu lệnh, đoạn chương trình hoặc hàm hoạt động như thế nào và làm gì Viết chú thích sẽ giúp cho người đọc có thể hiểu được chương trình dễ dàng và nhanh chóng hơn,

Trang 16

sửa lỗi đơn giản hơn hoặc giúp cho ta xem lại chương trình cũ mà ta đã làm trở lên nhanh hơn.

Chú thích trong chương trình sẽ không ảnh hưởng đến chương trình mà ta soạn thảo vì trình dịch sẽ bỏ qua tất cả lời chú thích khi biên dịch chương trình sang mã máy.

Lời giải thích được đặt sau dấu “//” nếu chú thích chỉ viết trên một dòng hoặc trong cặp dấu “\*” và “*\”.

Trang 17

Giải thích: nếu dieu_kien đúng thì xử lí “Đoạn chương trình 1” bên trong còn

sai thì xử lý “Đoạn chương trình 2”.

+ Câu lệnh lựa chọn - Switch:

Trang 18

//các câu lệnh

}

Giải thích: Tuỳ vào biến có giá trị bằng giá trị của Case nào thì thực hiện các

câu lệnh tương ứng trong Case đó, sau đó thoát khỏi cấu trúc nhờ câu lệnh

“break;” Nếu không có Case nào phù hợp thì thực hiện các câu

Giải thích: x là biến, n là giá trị xác định Trước tiên vòng lặp sẽ gán giá trị ban

đầu cho biến: x=n, rồi kiểm tra nếu điều_kiện đúng thì thực hiện các câu lệnh xử

lý, sau đó thực hiện Phép_toán nhằm tác động đến điều kiện Sau đó lại kiểm tra lại điều_kiện, nếu còn đúng thì thực hiện tiếp, nếu sai sẽ thoát khỏi vòng lặp Các thành phần trong vòng for có thể không cần khai báo,for sẽ bỏ qua

phần đó, nhưng vẫn phải có đủ 2 dấu “;”.

+ Vòng lặp không xác định - while:

Cấu trúc: while(dieu_kien)

{

Trang 19

// các câu lệnh

}

Giả thích: Trước tiên chương trình sẽ kiểm tra điều_kiện, nếu đúng thì thực hiện

các câu lệnh, sau đó quay lại kiểm tra điều_kiện Còn nếu điều_kiện sai thì thoát khỏi vòng lặp ngay

Giả thích: Trước tiên đoạn chương trình thực hiện các câu lệnh sau đó kiểm

trađiều_kiện nếu đúng thì lặp lại thực hiện các câu lệnh tiếp, nếu sai thì thoát khỏi vòng lặp.

Bài 1: Tạo xung vuông dùng vi điều khiển - Lập trình C cơ bản

Tạo xung vuông dùng vi điều khiển

Đây là chương trình đơn giản các bạn có thể tự mình tìm hiểu và chỉnh sửa theo ý mình, tất cả các dòng code đều được mình chú thích dễ hiểu

#include <REGX51.H> //Khai bao thu vien

Trang 20

sbit led=P1^0; //Khai bao chan P1_0 kieu bit

void main(){ //Chuong trinh chinh

ed=0; //Cho LED tat khi cap nguon

delay(20); //Tao tre 1 giay

while(1){ //Vong lap vo tan

led=1; //led sang 0.5 giay

Để hiểu được bài này bạn cần xem lại bài Ngôn ngữ lập trình C cơ bản cho 8051

Ta sẽ xét đoạn code sau:

#include //Khai bao thu vien

// VD: delay(20) == 20x50 = 1000ms = 1s

void delay(unsigned char time){//Chuong trinh tao tre

unsigned int t;

for(t=0;t<time;t++){

Trang 21

unsigned char q; //Khai bao kieu du lieu unsigned char cho bien q

unsigned char m1[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //Khai bao mang du lieu void main(){ //Chuong trinh chinh

P0=0x00; //Cho Post P0 ve muc logic 0

delay(20); //Tao tre 1 giay

while(1){ //Vong lap vo tan

for(q=0;q<8;q++){ //Vong lap co dieu kien

delay(10); //tre 0.5 giay

P0=m1[q]; //xuat du lieu mang ra post P0

Để đổi từ Bin sang Hex bạn có thể sd máy tinh để chuyển cho nhanh, VD casio FX-570MS vào

chế độ BASE, nút log = BIN; ^ = HEX; x 2 = DEC

fx500ms cũng đổi được nhưng phải chuyển hệ cho nó (REG )

Như vậy ta sử dụng vòng lặp for để truy xuất toàn bộ mã trên ra post của vi điều khiển để điều

khiển cho LED sáng chẳng hạn

vòng lặp for sẽ kiểm tra biến q , ban đầu set q=0 thì so sánh q q++ tức tự tăng thêm 1, q=1 và cho tới khi điều kiện sai 8<8 thì vòng lặp sẽ thoát ko thực hiện code trong {} nữa

Trang 22

Chạy xong thì lại bị vòng lặp vô tận while(1) cho lặp đi lặp lại quá trình trên.

Code trên sẽ cho led sáng lần lượt từ P0_0 tới P0_7 rồi lặp lại nhờ vòng lặp while(1)

Bài 3: Viết chương trình con - Lập trình C cơ bản

Viết chương trình con

Bài viết này sẽ giúp bạn tạo ra chương trình con và khai báo để chạy nó

Để tạo ctr con thì khá đơn giản VD:

Trang 23

void main(){ //Chương trình chính

while(1){ //Vòng lặp vô tận

ten_ctr(); //Chương trình con vừa tạo

}

}

Lưu ý chương trình con phải dc khai báo trước main() để có thể chạy dc.

Để truyền dữ liệu cho ctr con ta chỉ cần khai báo 1 biến bất kỳ trong dấu () vd:

void ten_ctr2(unsigned int a){

// Nội dung code xử lý dữ liệu lấy từ biến a=2000

Nếu có nhiều dữ liệu thì chỉ việc đánh dấu phẩy ngăn cách

Đây là code trong code led trái tim của mình, tạo ctr con hiệu ứng để tiện thay đổi hiệu ứng cũng như thứ tự xuất hiện hiệu ứng mà mình muốn:

unsigned char m1[8]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; //thuan 0 -> 7

unsigned char m2[8]={0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; //nguoc 7 -> 0

void h_ung_1(){ //Hieu ung 1

Trang 25

Bài 4: Lập trình LED đơn chạy chữ Happy New Year 2014 đơn giản

L p trình LED đ n ch y ch Happy New Year 2014 đ n gi n ập Trình C Cơ Bản Cho 8051 ơ Bản Cho 8051 ạy chữ Happy New Year 2014 đơn giản ữ Lập Trình C Cơ Bản Cho 8051 ơ Bản Cho 8051 ản Cho 8051

Các bạn đã nhìn thấy rất nhiều các biển quảng cáo led nó chạy như thế nào rồi, tại sao nó lại nháy dc như vậy thì hôm nay mình sẽ hướng dẫn các bạn làm ra nó, nhưng chỉ ở mức cơ bản dễ làm thui nha Các bạn đã biết Quảng cáo led bây giờ họ ko lập trình truyền thống nữa mà dùng phần mềm chuyên dụng để thiết kế làm rất ngắn thời gian thi công cho nên ta ko thế bắt trước theo họ được ví dụ như sáng mờ dần đó là họ dùng MCU chuyên dụng

Thôi ko nói dài dòng nữa ta sẽ đi vào vấn đề chính luôn :)

Đầu tiên ta quay lại kiến thức tin học một chút, đó là cách chuyển đổi bit giữa các hệ, ta chuyển

từ BIN-HEX nhằm ko muốn mất thời gian tính toán ta dùng luôn máy tính casio chuyển cho nhanh

Trang 26

Máy FX500MS ai đã biết cách vào hệ mà ta hay nghịch để viết chữ ấy nếu ko biết thì hỏi ng xung quanh, xong ta bấm MODE tới phần có 3 hệ SD | REG | BASE thì ta chọn BASE (đây là hệchuyển đổi bit) OK

Với máy FX570MS thì ta bấm MODE rồi chọn BASE luôn ko phải chuyển hệ, với các máy cao cấp hơn cũng tương tự

Vì code của chúng ta dùng mã HEX lên ta sẽ chuyển đổi BIN(nhị phân) sang HEX(hệ 16)

Nút log = BIN, nút ^ = HEX, nút x2 = DEC(hệ thập phân)

Nhấn nút "log" để nhập mã nhị phân 8 bit: VD: 11011010 nhấn nút "=" xong nhấn nút "^" để

chuyển sang mã HEX ta được 11011010 = DA (viết trong trình biên dịch keilC là 0xDA) thế là xong phần chuyển đồi ta bắt đầu vào viết chương trình

Lắm rõ hơn bạn lên xem lại các bài 1,2,3

CODE:

#include <REGX51.H>

void delay(unsigned char t){

//Chuong trinh tao tre 50ms

unsigned char w; //khai bao bien

unsigned char m1[8]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; //mang bit

void lan_luot(){//ctr con nhay lan luot

P0=P2=0xff; //tat ca tat

delay(20);

for(w=0;w<8;w++){ //Vong lap for

P0=m1[w]; //xuat mang m1 ra P0 chieu thuan

delay(10); //0.5s

}

Trang 28

Chu NEW o P0 co ma sang la 0x1F = 0001 1111 Chu YEAR o P2 co ma sang la 0xF0 = 1111 0000 Chu 2014 o P2 co ma sang la 0x0F = 0000 1111 */ P0=0xe0; //chu happy sang

delay(20);

P0=0x1F; //chu new sang

delay(20);

P0=0xff; //Tat P0 dong thoi

P2=0xF0; //chu year sang

//Code by vuthai - SangTaoClub.Net

/*Chu Happy New Year 2014 co tat ca 16 ky tu dung P0 va P2 de dieu khien chu vi 8x2=16 Dung muc logic 0 de lam chu sang*/

void main(){ //Chuong trinh chinh

P0=P2=0x00; //Tat ca sang

delay(20); //Tre 1s do 20x50=1000ms=1s TMOD=0x01;

while(1){

lan_luot(); //Goi ctr con nhay lan luot

xen_ke(); //Goi ctr con nhay xen ke

nhap_nhay(); //Goi ctr con nhap nhay nhay_chu(); //Goi ctr con nhay chu

// co the viet them

}

}

Mạch nguyên lý:

Ngày đăng: 26/12/2013, 10:13

HÌNH ẢNH LIÊN QUAN

2. Sơ đồ chân IC: - Giáo trình vi điều khiển cơ bản dùng c++
2. Sơ đồ chân IC: (Trang 32)
Bảng vector ngắt: - Giáo trình vi điều khiển cơ bản dùng c++
Bảng vector ngắt: (Trang 35)

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w