1. Trang chủ
  2. » Giáo án - Bài giảng

lập trình c căn bản (hướng dẫn làm đồ án)

29 971 3

Đ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

Định dạng
Số trang 29
Dung lượng 1,2 MB

Nội dung

Giao tiếp LCD 16x2 chế độ 4 bit dữ liệu GIAO TIẾP MAX7219LED MA TRẬN ĐƠN SẮC 8x8 LẬP TRÌNH ĐIỀU KHIỂN LED 7 ĐOẠN 1 SỐ Điều khiển 6 led dùng 3 IO. BÀN PHÍM MA TRẬN 4x4 Đo điện áp 05000mV dùng bộ ADC, hiển thị LCD. NHIỆT KẾ ĐIỆN TỬ ADC 12 BIT MCP3204 TIMER BỘ ĐỊNH THỜI

Trang 1

[HƯỚNG DẪN LẬP TRÌNH PIC CĂN BẢN]

BÀI 1: DIGITAL OUTPUT

GIAO TIẾP MAX7219-LED MA TRẬN ĐƠN SẮC 8x8

1 Phần cứng:

-Max7219 giao tiếp MCU bằng 3 IO:

DIN(1): Dữ liệu vào nối tiếp

LOAD(12): Chốt dữ liệu, cho phép hiển thị

CLK(13): Xung nhịp clock

-Đặc tính:

Quét led độc lập - không phụ thuộc vào vi điều khiển

Vi điều khiển chỉ việc đưa dữ liệu vào các thanh ghi nhớ ứng với từng digit (1 led 7 đoạn/ 1 hàng trong led ma trận)

Dữ liệu không bị mất khi chưa có dữ liệu mới được đưa vào

Tương tự như 74HC595, các IC Max7219 nối dữ liệu với nhau bằng cách nối Dout của IC trước với Din của IC sau

2 Phần mềm:

Khai báo tiền xử lý:

#define LOAD PIN_A1

#define CLK PIN_A2

#define DIN PIN_A0

#define NUM 3 //Số IC được sử dụng, cũng ứng với số led ma trận

Trang 3

II CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH VIẾT TRÊN CCS:

1 Cấu trúc chung:

- Khai báo tiền xử lý:

- Các chương trình con

- Chương trình chính

> Ta đặt chương trình chính cuối cùng để tránh phải khai báo nhiều trong khai báo tiền xử lý

> Chương trình đứng phía dưới được phép gọi chương trình phía trên mà không cần khai báo chương trình cần gọi ở tiền xử lý

2 Khai báo tiền xử lý:

#include<device.h> //Khai báo thư viện biên dịch của PIC đang sử dụng ví dụ: #include<16F877A.h>

//Thư viện các dòng PIC chứa trong C:\Program Files\PICC\Devices

#device ADC=10 //Chỉ khai báo khi Chip có bộ chuyển đổi ADC 10bit

#fuses HS, NOWDT //Khai báo "cầu chì", cần chú ý khai báo HS là dùng dao động cao tần bên ngoài như thạch anh

//Nếu dùng dao động tần số thấp (<=4MHz), ta khai báo như sau: #fuses XT

//Nếu sử dụng dao động nội (chỉ Chip nào có hỗ trợ): #fuses XT, INTRC_IO

//Khai báo NOWDT không sử dụng "đồng hồ chó" WDT - chống treo Chip khi rơi vào vòng lặp chết

#use delay(clock=xM) //Khai báo tần số xung nhịp cấp cho core xử lý, x là tần số dao động (MHz) Ví dụ: #use delay(clock=20M)

//Nếu dùng dao động nội thì clock=4M

#define A B //Thay thế B bằng A, A sẽ mang mọi đặc tính của B Ví dụ #define LED PIN_A0 thay thế PIN_A0 bằng LED

BÀI 1: DIGITAL OUTPUT [TT]

I GIỚI THIỆU CÔNG CỤ LẬP TRÌNH, MÔ PHỎNG:

III CÁC LỆNH XỬ LÝ:

set_tris_x(8 bit value); //Nếu I.O cố định thì gọi hàm này 1 lần trong config

//Cài đặt các port x là ngõ vào/ra value ở binary, bit nào giá trị 1 là ngỏ vào, 0 là ngỏ ra

//VD: set_tris_a(0b00111001); port A có bit 0,3,4,5 là ngỏ vào, 1,2,6,7 là ngỏ ra

output_x(8 bit value); //Sử dụng khi có khai báo set_tris_x(); Có thể gọi nhiều lần

//Xuất ngỏ ra cho port x VD: ouput_a(0b01010101);

//bit mang giá trị 1 là mức cao (5V), mức thấp là 0V

output_high(PIN_name); //Xuất mức cao chân PIN_name VD: output_high(PIN_A0);

output_low(PIN_name); //Xuất mức thấp chân PIN_name VD: output_low(PIN_A0);

output_bit(PIN_name, x); //Xuất mức x ở chân PIN_name Mức thấp x=0, cao x=1

output_float(PIN_name); //Trạng thái ngỏ ra cao trở

> Khi ta set trạng thái thì trạng thái được giữ nguyên cho đến khi ta set trạng thái khác hoặc mất điện

delay_us(16 bit value); //Delay micro giây

delay_ms(16 bit value); //Delay mili giây

IV VÍ DỤ:

Trang 5

BÀI 1: DIGITAL OUTPUT [TT]

I LẬP TRÌNH ĐIỀU KHIỂN LED 7 ĐOẠN 1 SỐ:

1 Xác định phần cứng:

- Xác định loại led 7 đoạn: âm cực chung (CC), dương cực chung (CA)

- Kết nối với IO vi điều khiển tuỳ ý sao cho dễ thi công mạch Chú ý sử dụng 1 port 8 IO để dễ điều khiển

2 VD mẫu:

Điều khiển 1 led 7 đoạn CA kết nối port B của PIC16F877A, hiển thị từ 0 đến 9 Các bước thực hiện như sau: Qui định IO:

Bit 0: A Bit 1: B Bit 2: C Bit 3: D

Bit 4: A Bit 5: E Bit 6: F Bit 7: DP

Bit 0: A Bit 1: B Bit 2: C Bit 3: D

Bit 4: A Bit 5: E Bit 6: F Bit 7: DP

PIN_C0: CA0 PIN_C1: CA1

Quét led thực tế là cho lần lượt từng led 7 đoạn sáng - tại 1 thời điểm chỉ có 1 led 7 đoạn sáng, thời gian thay đổi giữa các

led rất nhỏ (vài us/ms) nên mắt không phân biệt được và thấy chúng sáng đồng thời

Mắt chỉ phân biệt được dao động <22Hz, trên 22Hz ta thấy vật dao động đứng im

Trang 6

set_tris_b(0x00);

unsigned char i=0, count=0, chuc, dv; //Các biến

while(true)

{

chuc=i/10; // i là số nguyên, phép "/" là chia lấy phần nguyên

dv=i%10; // i là số nguyên, phép "%" là chia lấy phần dƣ

output_low(PIN_C1); //Tắt led hàng đơn vị

output_b(ma_7doan[chuc]); //Xuất mã hàng chục

output_high(PIN_C0); //Cho phép led hàng chục sáng

delay_ms(1); //Tạo trễ để nhìn thấy led sáng

output_low(PIN_C0); //Tắt led hàng chục

output_b(ma_7doan[dv]); //Xuất mã hàng đơn vị

output_high(PIN_C1); //Cho phép hàng đv sáng

delay_ms(1); //Tạo trễ để hiển thị

count++; //Cho biến đếm tự tăng 1 đơn vị

if(count==250) //Khi biến đếm =250 ứng với 500ms do 2 lệnh delay_ms(1) phía trên hết 2 ms {

i++; //Tăng i lên 1 đơn vị

if(i>=100) i=0; //Khi i>=100 thì reset về 0 Tức mạch đếm từ 00-99

count=0; //Reset biến đếm sau 250 lần đếm

}

}

}

BÀI 1: DIGITAL OUTPUT [TT2]

I Giao tiếp LCD 16x2 chế độ 4 bit dữ liệu:

1 Kết nối phần cứng:

Trang 7

unsigned char string[17];

Các config trong void main():

sprintf(string,"chuỗi cần hiển thị %kiểu dữ liệu",biến dữ liệu);

LCD_Gotoxy(vị trí, hàng);//Chữ được in ra từ vị trí 0-15, hàng(trên là 0, dưới là 1)

LCD_Puts(string);//Gửi dữ liệu trong mảng string lên LCD để hiển thị ra

Hiển thị chữ "DEE-TDTu" ở chính giữ, hàng trên

Hiển thị chữ "CLB Dien Tu TEC" ở hàng dưới trong vòng 2s

Đếm từ 0-99 ở hàng dưới, hàng trên giữ nguyên

Trang 8

74HC595 kết nối với vi điều khiển qua 3 chân:

SH_CP(11): Chân xung nhịp clock

ST_CP(12): Chân chốt dữ liệu - cho phép xuất dữ liệu trong thanh ghi tạm ra các chân

DS(13): Chân nhận dữ liệu nối tiếp

> Giúp mở rộng ngỏ ra số cho vi điều khiển

> Đồng bộ hoá dữ liệu đầu ra Vào nối tiếp, ra song song

2 Phần mềm:

Khai báo tiền xử lý:

#define EXP_OUT_ENABLE PIN_A2 //Chân ST_CP

#define EXP_OUT_CLOCK PIN_A0 //Chân SH_CP

#define EXP_OUT_DO PIN_A1 //Chân DS

#define NUMBER_OF_74595 2 //Số IC sử dụng IC nào có chân DS nối với MCU là IC thứ 0, kế tiếp

Trang 9

#include <12F629.h>

#fuses XT, INTRC_IO, NOMCLR, NOWDT

#use delay(clock=4M)

#define EXP_OUT_ENABLE PIN_A2

#define EXP_OUT_CLOCK PIN_A0

#define EXP_OUT_DO PIN_A1

Trang 10

Trạng thái này hỗ trợ cho việc quét led, các giao tiếp cần trạng thái thứ 3, chuyển mạch

Sử dụng tối ƣu các IO hơn

Khi sử dụng, không cần khai báo gì khác, chỉ việc gọi hàm output_float(IO_name);

VD: output_float(PIN_A0);// Cho ngỏ ra chân A0 ở trạng thái cao trở

VD: Điều khiển 6 led dùng 3 IO

BÀI 2: DIGITAL INPUT

Khai báo tiền xử lý:

/*Sử dụng cho ngỏ vào là 1 port*/

Trang 11

#use fast_io(port) //Khai báo sử dụng port vừa vào vừa ra

#bit name=pin_address // Đặt tên 1 bit cụ thể của port

> port A,B,C,D,E có địa chỉ lần lượt là: 0x05,0x06,0x07,0x08,0x09

> pin của port có địa chỉ từ 0-7

VD: Ta muốn đặt tên in5 cho chân số 5 của port C ta khai báo như sau:

#bit in5=0x07.5

/*Sử dụng ngỏ vào là IO bất kì*/

Không khai báo gì

Khai báo config:

set_tris_port(8 bit value);//Sử dụng cho ngỏ vào port hoặc bit của port

> Thanh ghi tris sẽ qui định IO tương ứng là vào khi nhận bit giá trị 1 và ra khi nhận bit giá trị 0 VD: Qui định C là port vào 8 bit: set_tris_c(0xff);

Qui định C là port vào 3 bit đầu: set_tris_c(0x07);

> Sử dụng ngỏ vào là IO bất kỳ ta không cần khai báo config

Các lệnh xử lý:

/*Sử dụng cho ngỏ vào là 1 port*/

byte value=ingput_port(); //Lưu giá trị ngỏ vào port vào biến value có kiểu dữ liệu là byte int1 value=pin_address; //Lưu giá trị của pin cụ thể của port vào viến value có kiểu dữ liệu 1 bit /*Sử dụng ngỏ vào là IO bất kì*/

int1 value=input(PIN_name); //Lưu giá trị của IO vào biến value kiểu 1 bit

VD mẫu: Sử dụng PIC16F877A

Dùng 1 IO E1 để bật tắt 1 đèn nối với PIN_B0 của port B

Dùng port C để bật tắt các đèn tương ứng của port D

Dùng pin 3,4,5 để bật tắt đèn nối với pin 0,1,2 của port A

Trang 13

BÀI 2: DIGITAL INPUT [TT1]

BÀN PHÍM MA TRẬN 4x4

1 Phần cứng:

- Bàn phím ma trận là 1 giải pháp giúp tiết kiệm IO vi điều khiển

- Cấu tạo phím ma trận 4x4 gồm: 4 IO hàng và 4 IO cột và kết nối như hình vẽ

- Với 8 IO ta có thể tạo ra 16 phím bấm, nếu sử dụng IO riêng lẻ ta phải dùng 16 IO

2 Phần mềm:

Chép và ghi đè file key_4x4.c đính kèm file PDF này vào "C:\Program Files\PICC\Drivers"

- Phương pháp điều khiển:

Ở ví dụ này, ta dùng 4 hàng phát xung và 4 cột nhận xung

Các IO hàng đặt ở chế độ output, 4 IO cột cở chế độ input

Ta lần lượt cho các IO hàng lên mức cao Cứ mỗi lần như thế ta lại kiểm tra 4 IO cột Nếu cột nào có mức logic cao, tức nút

được nhấn thì trả về giá trị cột và giá trị hàng tại thời điểm đó

Dựa vào thông số trả về, ta quy định giá trị phím nhấn

- Khai báo tiền xử lý:

#define ROW1 PIN_C0

#define ROW2 PIN_C1

#define ROW3 PIN_C2

#define ROW4 PIN_C3

#define COL1 PIN_C4

#define COL2 PIN_C5

#define COL3 PIN_C6

#define COL4 PIN_C7

Trang 14

/*Giao tiep phim ma tran*/

#define ROW1 PIN_C0

#define ROW2 PIN_C1

#define ROW3 PIN_C2

#define ROW4 PIN_C3

#define COL1 PIN_C4

#define COL2 PIN_C5

#define COL3 PIN_C6

#define COL4 PIN_C7

if(code=='C') output_low(RST); //Nếu mã phím là C thì cho chân RST tích cực

else if((code!=temp)&&(code!=' ')) //Ngược lại, nếu mã phím khác mã trước đó và khác mã khoảng trống thì in mã mới ra LCD

Trang 15

BÀI 3: ANALOG INPUT

I Giới thiệu:

- Một số dòng PIC có hỗ trợ bộ chuyển đổi tín hiệu tương tự sang số với độ phân giải 8/10 bit

- Bộ chuyển đổi tương tự sang số gọi là ADC (Analog to Digital Converter)

- Ý nghĩa:

> Nhiều bạn chưa học xử lý số tín hiệu nên AD tạm giải thích như sau:

+ Độ phân giải (số bit phân giải) là 8 hoặc 10bit, tức có 2^8=256 hoặc 2^10=1024 giá trị số được chuyển đổi (số bậc phân giải)

+ Áp tham chiếu: Là điện áp chuẩn, lớn nhất, điện áp này được chia đều cho số bậc phân giải

VD minh hoạ với độ phân giải là 2 bit (4 bậc phân giải) Áp tham chiếu Vref=9V

Giá trị analog Giá trị số

9V 3

6V 2

3V 1

0V 0

Ta thấy, nếu ngỏ vào [0V;3V) ADC=0, [3V;6V) ADC=1, [6V;9V) ADC=2, [9V; ) ADC=3

> Với PIC, giá trị ADC min=Vfref-=0, ADC max=Vref+

Công thức chung để tính giá trị mỗi bậc ADC của PIC là:

Vref/((2^bit)-1)

II Phần cứng:

- Cần kiểm tra datasheet xem chip sử dụng có bộ ADC hay không

- Một số dòng PIC, ADC chỉ có 8 bit, hầu hết là có 2 độ phân giải 8/10 bit

- Trong Proteus, chân ANx là chân vào của tín hiệu analog Một chip có thể có nhiều ngỏ vào analog

- Với PIC, áp tham chiếu tối đa là 5V, nếu sử dụng áp khác thì cần cấp áp chuẩn vào chân có kí hiệu Vref

III Phần mềm:

1 Khai báo tiền xử lý:

#device ADC=8 //Chế độ 8 bit

#device ADC=10 //Chế độ 10 bit

> Khai báo ngay sau khai báo #include<device.h> và trước khai báo #fuses

2 Khai báo config:

setup_adc(ADC_CLOCK_INTERNAL); //Chu kỳ lấy mẫu 2-6us

setup_adc_ports(pin name); //Chọn port vào analog Tối đa 2 port, phân cách bằng dấu phẩy

set_adc_channel(value); //Đi chung với setup_adc_port() tương ứng Chỉ khai báo lệnh này khi dùng 1 port analog

> Xem trong file device.h

3 Hàm lấy giá trị ADC:

/*Dùng 1 port analog*/

delay_us(20); //Delay tối thiểu để lấy mẫu

float value=read_adc();

/*Dùng 2 port analog*/

set_adc_channel(x);

delay_us(20);

float value1=read_adc();

set_adc_channel(y);

delay_us(20);

float value2=read_adc();

/*Dùng trên 2 port analog*/

setup_adc_ports(pin name);

set_adc_channel(x);

delay_us(20);

float value2=read_adc();

Trang 16

float temp, adc;

unsigned int16 vol;

adc=read_adc(); //Đọc giá trị ADC

temp=(5000*adc)/1023; //Chuyển về giá trị điện áp (mV)

vol=(unsigned int16)temp; //Lấy phần nguyên của số thực temp sprintf(string,"%04ld %04ldmV",(unsigned int16)adc, vol);

Trang 17

- Để đo được nhiệt độ bằng phương pháp điện tử, ta phải chuyển năng đại lượng nhiệt (dạng phi điện)

về dạng tín hiệu điện với một

tỉ lệ chuyển đổi tương đối tuyến tính Phương pháp chuyển đổi này là cơ sở hình thành cảm biến mà cụ thể ở đây là cảm biến nhiệt

- Trên thị trường có nhiều loại cảm biến nhiệt với cấu tạo và phương thức chuyển đổi sang tín hiệu điện khác nhau Khá phổ biến

hiện nay là cảm biến nhiệt LM35

Đo nhiệt độ dùng LM35 với các yêu cầu sau:

+ Hiển thị led 7 đoạn 4 số

+ Tầm đo 0-99 độ C Vượt quá sẽ báo lỗi

#define CA1 PIN_B4 //Pin lái cực dương led hàng nghìn

#define CA2 PIN_B5 //Pin lái cực dương led hàng trăm

#define CA3 PIN_B6 //Pin lái cực dương led hàng chục

#define CA4 PIN_B7 //Pin lái cực dương led hàng đv

#define LOW output_low

#define HIG output_high

unsigned char ma_7doan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //Mã led 7 đoạn

unsigned char digit[4]; //Mảng nhớ mã hiển thị cho từng led 7 đoạn

Trang 18

Đọc adc và chuyển giá trị adc sang nhiệt độ

Cứ 10mV thì đƣợc 1 độ C Tầm toàn thang Vref= 5V= 5000mV thì đo đƣợc 500 độ Vậy ta xem nhƣ tầm toàn thang Vref= 500 thì công thức tính nhiệt độ nhƣ sau: to=(Vref*adc)/1023=(500*read_adc())/1023;

*/

temp=0.5+((500.0*read_adc())/1023.0); //Cộng 0.5 là làm tròn đến hàng đơn vị doC=(unsigned int8) temp; //Lấy phần nguyên của nhiệt độ

count=0; //Reset biến đếm

Trang 19

sử dụng IC ADC chuyên dụng để kết nối với PIC Bài viết hôm nay, mình xin giới thiệu IC MCP3204 là IC

ADC 12 bit do Microchip sản

xuất

- Thông số kỹ thuật:

+ 12 bit ADC

+ 4 kênh ngỏ vào analog

+ Cho phép sử dụng áp tham chiếu khác áp nguồn

+ Giao tiếp 4 dây theo kiểu giao tiếp SPI - sẽ tìm hiểu kỹ các phần sau, nhƣng về cơ bản ta cần kết nối IC với PIC bằng 4 IO

bất kỳ với các chức năng: IO tạo xung clock, IO cho phép, IO dữ liệu vào, IO dữ liệu ra Về bản chất, giữa PIC

và IC ADC chỉ

truyền nhận tín hiệu số

+ Nguồn nuôi 5VDC

II Lập trình:

CCS đã hỗ trợ sẵn thƣ viện giao tiếp nên ta không cần phải "sáng tạo" làm gì

Thƣ viện chứa tại: "C:\Program Files\PICC\Drivers\mcp3204.c"

1 Khai báo tiền xử lý:

#define MCP3204_CLK PIN_B0 //IO xung nhịp

#define MCP3204_DIN PIN_B1 //IO ghi dữ liệu

Trang 20

#define MCP3204_DOUT PIN_B2 //IO nhận dữ liệu

#define MCP3204_CS PIN_B3 //IO chọn chip

#define MCP3204_DIN PIN_B1

#define MCP3204_DOUT PIN_B2

#define MCP3204_CS PIN_B3

#include<MCP3204.c>

unsigned char string[17];

unsigned int32 vol;

temp=read_analog_mcp(i,1); //Đọc giá trị ADC ở channel thứ i

temp=0.5+((temp*5000)/4095); //Tính giá trị điện áp (mV) và làm tròn đến hàng đv

vol=(unsigned int32)temp; //Lấy phần nguyên của giá trị

Trang 21

[HƯỚNG DẪN LẬP TRÌNH PIC CĂN BẢN]

BÀI 4: TIMER - BỘ ĐỊNH THỜI

I Giới thiệu:

- Tốc độ xử lý của PIC16 tối đa là 5 MIPS (Million Instructions Per Second) tức 5 triệu

lệnh mỗi giây ứng với nguồn cấp xung 20MHz

- PIC16 có tốc độ core xử lý (fcore) bằng ¼ tốc độ nguồn cấp xung nhịp (fosc) Tức xung

nhịp cấp cho PIC hoạt động được đưa qua bộ chia 4 trước khi đưa vào core

Bộ định thời của PIC16 hoạt động dựa trên xung nhịp core xử lý Tuy nhiên, PIC

không dùng trực tiếp xung nhịp của core để định thời mà đưa nó qua một bộ chia

trước gọi là prescaler Sau khi qua bộ chia trước, xung nhịp mới được cấp vào thanh

ghi định thời Vậy xung nhịp từ nguồn xung đến được thanh ghi định thời có tốc độ

là:

Cứ 1 xung nhịp (ftimer) thì giá trị thanh ghi tăng lên 1 Khi thanh ghi đạt giá trị max mà

tiếp tục có xung nhịp thì cờ tràn định thời sẽ được set

Ngày đăng: 26/05/2016, 12:42

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w