2.2 Mođun eZ430-RF2500
2.2.3.3 Tập lệnh ngôn ngữ C
Để viết chương trình cho vi điều khiển yêu cầu người lập trình cần có kiến thức lập trình cơ bản, nhóm thực hiện để tài chỉ xin liệt kê cấu trúc các lệnh thường dùng để thuận tiện cho người học:
• if (biểu thức luận lý) {khối lệnh;} • if (biểu thức luận lý) {khối lệnh 1;} else {khối lệnh 2;} • if (biểu thức luận lý 1) {khối lệnh 1;}
else if (biểu thức luận lý 2) {khối lệnh 2;} …………. else {khối lệnh n;} • switch (biểu thức) {case giá trị 1 : lệnh 1; break; case giá trị 2 : lệnh 2; break; case giá trị n : lệnh n; break;} • switch (biểu thức) {case giá trị 1 : lệnh 1; break; case giá trị 2 : lệnh 2; break; case giá trị n : lệnh n; default : lệnh; [ break;] }
• for (biểu thức 1; biểu thức 2; biểu thức 3) {khối lệnh;} • while (biểu thức) {khối lệnh;} • do {khối lệnh;} while (biểu thức); 2.2.3.4 Chỉ thị tiền xử lý: a. #include
Cú pháp: #include <filename> hoặc # include “filename”. Tên file có thể (.h) hoặc (.c).
Ví dụ: #include "msp430x22x4.h"
Ta đã khai báo thư viện cho vi điều khiển MSP430x22x4. b. # define
Dùng để định nghĩa biến hoặc giá trị trong header file.
Ví dụ: Từ tần số tham chiếu 32KHz, ta có thể thiết lập các giá trị tần số khác nhau (ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO).
#define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz Sử dụng các BIT đã được định nghĩa trong header file:
#define LED1 BIT3 #define LED2 BIT4
c.
#ifdef ,#en dif:
Bổ xung các dịng code cho chương trình kiểm tra. d.
#pragma basic_template_matching
Sử dụng trước một hàm mẫu để khai báo sử dụng các thuộc tính đầy đủ của bộ nhớ MSP430 IAR C/C++ Compiler Reference Guide.
Ví dụ: # pragma basic_template_matching template<typename T> void fun(T *); fun((int __data16 *) 0);
/* Template parameter T becomes int __data16 */ e.
# warning message
Sử dụng chỉ thị tiền xử lý này để nhận được các tin nhắn cảnh báo lỗi.
2.2.3.5 Các hàm xử lý số:
Các hàm xử lý số được giới thiệu trong help, người học có thể tìm hiểu để biết chi tiết, sau đây là một số hàm cơ bản:
• abs() : Hàm lấy giá trị tuyệt đối.
• asin(), acos(), atan() : là các hàm arcsin, arccos, arctan.
• sin(), cos(), tan() : các hàm lượng giác cơ bản.
• pow() : hàm tính lũy thừa.
• sqrt(): hàm tính căn bậc 2.
• exp(): hàm mũ ex.
• rand(): lấy giá trị ngẫu nhiên.
2.2.3.6 Các hàm hỗ trợ đặc biệt:
1) __cc_version1
Ví dụ: __cc_version1 int func(int arg1, double arg2) Chức năng: Gọi chương trình con trong C.
2) __set_R4_register
Ví dụ: void __set_R4_register(unsigned short);
Chức năng: Ghi giá trị đặc biệt vào thanh ghi R4, chức năng này chỉ sử dụng khi R4 bị khóa.
3) __set_SP_register
Ví dụ: void __set_SP_register(unsigned short);
Chức năng: Ghi một giá trị đặc biệt vào con trỏ ngăn xếp SP. 4) __swap_bytes
Ví dụ: unsigned short __swap_bytes(unsigned short);
Chức năng: Trèn vào một giá trị và đảo ngược giá trị phần trên và phần dưới:
__swap_bytes(0x1234) returns 0x3412 5) __set_interrupt_state
Cú pháp: void __set_interrupt_state(__istate_t);
Chức năng: Phục hồi trạng thái ngắt bằng cách thiết lập giá trị trả về bằng hàm __get_interrupt_state.
6) __interrupt Ví dụ:
#pragma vector=0x14
Là hàm dùng chỉ thị tới một hoặc nhiều ngắt. Khai báo bằng chỉ thị tiền xử lý # pragma vetor= (địa chỉ của các véc tơ ngắt).
7) __no_operation
Cú pháp: void __no_operation(void); Chức năng: Trèn một lệnh NOP. 8) __low_power_mode_n
Cú pháp: void __low_power_mode_n(void);
Chức năng: Sử dụng chế độ nguồn thấp của MSP430, n có giá trị 0-4. 9) __get_R4_register
Cú pháp: unsigned short __get_R4_register(void); Chức năng: Trả về giá trị của thanh ghi R4.
10) __get_SP_register
Cú pháp: unsigned short __get_SP_register(void); Chức năng: Trả về giá trị của con trỏ ngăn xếp SP. 11) __get_SR_register
Cú pháp: unsigned short __get_SR_register(void);
Chức năng: Trả về giá trị của thanh ghi trạng thái xử lý SR 12) __get_interrupt_state
Cú pháp: __istate_t __get_interrupt_state(void); Chức năng: Trở về trạng thái ngắt tồn cục Ví dụ: __istate_t s = __get_interrupt_state(); __disable_interrupt();
/* Do something */ __set_interrupt_state(s); 13) __delay_cycles
Cú pháp: void __delay_cycles(unsigned long cycles);
Chức năng: Trèn một chương trình tạo trễ với thời gian được chỉ định. 14) __enable_interrupt
Cú pháp: void __enable_interrupt(void);
Chức năng: Cho phép ngắt bằng cách trèn vào lệnh EI. 14) __disable_interrupt
Cú pháp: void __disable_interrupt(void);
Chức năng: Cấm ngắt bằng cách trèn vào lệnh DI. 15) __bis_SR_register
Cú pháp: void __bis_SR_register(unsigned short); Chức năng: Set các bit trong thanh ghi trạng thái.
16) __bis_SR_register_on_exit
Cú pháp: void __bis_SR_register_on_exit(unsigned short);
Chức năng: Set các bit trong thanh ghi trạng thái xử lý khi trỏ về từ chương trình phục vụ ngắt.
17) __bic_SR_register
Cú pháp: void __bic_SR_register(unsigned short); Chức năng: Xóa bit trong thanh ghi trạng thái xử lý 18) __bic_SR_register_on_exit
Cú pháp: void __bic_SR_register_on_exit(unsigned short);
Chức năng: Xóa các bít thanh ghi trạng thái xử lý khi trở về từ một ngắt.
CHƯƠNG 3
THIẾT KẾ PHẦN CỨNG MỞ RỘNG PORT VÀ CÁC BÀI THỰC
3.1 Vấn đề đặt ra:
Như đuợc giới thiệu ở trên bộ thí nghiệm eZ430-RF2500 cho ta 18 chân bên ngoài để sử dụng điều khiển những thiết bị khác . Do kết cấu của quy cách đóng gói ta khơng sử dụng được 4 chân (chân số 1-4), một chân mass (chân số 12), hai chân đuơc sử dụng để điều khiển tụ thạch anh cho con CC2500 (chân số 13 và 14). Cuối cùng ta cịn lại 11 chân, với 11 chân ta chỉ có thể điều khiển những thiết bị đơn giản. Một yêu cầu được đề ra là làm sao để có thể điều khiển những thiết bị cần nhiều chân điều khiển (Một ví dụ đơn giản là điều khiển 32 led đơn sáng). Từ vấn đề trên nhóm đã quyết định sử dụng IC 74HC595 để mở rộng Port.
Và trong qúa trình làm thực nghiệm 1 vấn đề nữa cũng đã nảy sinh . Vì vi điều khiển MSP430 là loại tiết kiệm năng lượng nên mức logic 1 của nó chỉ ở 3.6V (Đó là lý thuyết) cịn trong thực nghiệm khi đo chỉ được khoảng 3.2V . Gây khó khăn trong việc xử lý cũng như điều khiển các thiết bị khác, vì với 3.2V các loại thiết bị khác khơng hiểu được đó là mức logic 1 hay 0. Chính vì lý do đó nhóm đã sử dụng thêm IC 2803, một IC đệm đảo điện áp.
Với 2 vấn đề trên nhóm đã sử dụng 2 IC 74HC595 và 2803 để giải quyết,và chúng ta sẽ nói qua về 2 IC này.
3.2 Các IC sử dụng trong việc mở rộng Port:3.2.1 IC 74HC595: 3.2.1 IC 74HC595:
3.2.1.1 Giới thiệu:
IC 74HC595 có các đặc điểm sau: + IC có 16 chân.
+ 8 bit nối tiếp ở ngõ vào.
+ 8 bít nối tiếp hoặc song song ở ngõ ra.
+ Chốt thanh ghi dịch với 3 trạng thái ở ngõ ra. + Tần số nhịp xung clock là 100MHz.
Hình 49: Sơ đồ chân IC 74HC595
Chức năng từng chân:
+ Chân 15: Ngõ ra dữ liệu song song bit 0. + Chân 1 - 7: Ngõ ra dữ liệu song song bit 1 – 7. + Chân 8: Nối Mass.
+ Chân 9: Ngõ ra dữ liệu nối tiếp.
+ Chân 10: Reset (Hoạt động mức thấp). + Chân 11: Nhận xung clock.
+ Chân 12: Chốt dữ liệu ngõ ra.
+ Chân 13: Cho phép ngõ ra (Hoạt động mức thấp). + Chân 14: Ngõ vào dữ liệu nối tiếp.
+ Chân 16: Cấp nguồn (5V).
3.2.1.3 Cấu tạo và nguyên tắc hoạt động:3.2.1.3.1 Cấu tạo: 3.2.1.3.1 Cấu tạo:
Hình 50: Cấu tạo IC 74HC5959
Bên trong gồm 8 con FlipFlop D mắc nối tiếp . Từ tầng 0 - 7 cho ngõ ra từ Q0 - Q7 .
3.2.1.3.2 Nguyên tắc hoạt động:Bảng sự thật: Bảng sự thật: Bảng 16: Bảng sự thật IC 74HC595 Trong đó: + H: Mức điện áp cao. + L: Mức điện áp thấp.
+ ↑: Chuyển đổi điện áp từ thấp lên cao. + ↓: Chuyển đổi điện áp từ cao xuống thấp. + n.c.: Khơng thay đổi.
Dạng sóng điều khiển:
Hình 51: Dạng sóng điều khiển IC 74HC595
Hình 52: Ngun lý hoạt động
Để IC hoạt động ta phải nối chân số 10 lên nguồn 5V (không tác động Reset) và nối chân số 13 xuống Mass ( cho phép ngõ ra ). Với dữ liệu 8 bit dữ liệu được đưa vào chân 14 của IC, cứ sau mỗi xung clock được đưa vào chân số 11 của IC thì bit thứ 1 của dữ liệu đầu vào được đưa ra ở ngõ ra. Vậy sau 8 xung clock cung cấp cho chân số 11 thì 8 bit dữ liệu đầu vào sẽ được đưa ra ở ngõ ra từ Q0 – Q7. Khi 8 bit dữ liệu được đưa ra ở ngõ ra như vậy, chúng ta cần 1 xung clock cung cấp cho chân số 12 của IC để chốt dữ liệu đầu ra (Dù có thêm xung clock cung cấp cho chân số 11 thì đầu ra vẫn khơng thay đổi). Lúc này ta sẽ có 8 bit dữ liệu đầu ra từ Q0 - Q7 trùng khớp với 8 bit dữ liệu được đưa ở đầu vào. Muốn dịch bao nhiêu bit thì ta cần bấy nhiêu xung clock rồi đưa 1 xung chốt để đẩy dữ liệu ra ngoài.
Ở đây nếu muốn dịch số bit lớn hơn 8 thì ta cần nối tiếp thêm IC 74HC595. Nếu là 16 bit thì cần 2 IC, 24 bit thì 3 IC, 32 bit thì 4 IC …. Ta dùng chân số 9 của con thứ nhất nối tiếp vào chân dữ liệu đầu vào của con thứ 2 (chân số 14) và dùng chân số 9 của con thứ 2 nối tiếp vào chân dữ liệu đầu vào của con thứ 3, cứ thế tiếp tục. Muốn dịch bao nhiêu bit thì cần bấy nhiêu xung clock và 1 xung chốt để đẩy dữ liệu ra ngồi. Ở đồ án này, nhóm chỉ cần dịch 16 bit dùng 2 IC 74HC595 nối tiếp. Dùng 3 tầng như thế để có dịch được 48 bit.
3.2.2 IC 2803: 3.2.2.1 Giới thiệu:
IC 74HC595 có các đặc điểm sau: + IC có 18 chân.
+ Vi mạch gồm 8 cổng đệm đảo, đầu ra cực thu hở. + Dòng ngõ ra lên tới 500mA.
+ Điện áp ngõ ra lên tới 95V.
Hình 53: Sơ đồ chân IC 2803
Chức năng từng chân:
+ Chân 1 - 8: Điện áp ngõ vào. + Chân 9: Nối Mass.
+ Chân 10: Nối nguồn chuyển đổi (5V,12V). +Chân 11 – 18: Điện áp đảo ngõ ra.
3.2.2.3 Nguyên lý hoạt động:
Hình 54: Nguyên lý hoạt động của IC 2803
Vì mạch chỉ cần dùng điện áp 5V, nên ở đây nối chân 10 của IC2803 lên điện áp 5V (muốn dùng điện áp bao nhiêu thì nối chân số 10 với điện áp đó). Khi có điện áp ngõ vào là 0V IC sẽ đệm lên thành 5V và khi điện áp ngõ vào nhỏ hơn 5V IC sẽ đệm xuống thành 0V. Như thế sẽ cho ra 2 mức logic 1 và 0 để chúng ta có thể sử dụng trong các mạch điều khiển khác.
3.3 Phưong pháp mở rộng Port: 3.3.1 Sơ đồ nguyên lý:
Hình 55: Sơ đồ nguyên lý mở rộng Port
3.3.2 Nguyên lý hoạt động:
Ở đây ta dùng 3 tầng thanh ghi dịch, mỗi tầng sử dụng dịch 16 bit, vậy tổng cộng ta có thể sử dụng 48 bit ghi dịch. Dùng các chân vi điều khiển MSP430F2274 qua IC 2803 để điều khiển các thanh ghi dịch. Chân số 9 của IC 74HC595 thứ 1 nối với chân số 14 của IC 74HC595 thứ 2 tạo thành tầng thứ nhất 16 bit. Chân số 9 của IC 74HC595 thứ 3 nối với chân số 14 của IC 74HC595 thứ 4 tạo thành tầng thứ hai 16 bit. Chân số 9 của IC 74HC595 thứ 5 nối với chân số 14 của IC 74HC595 thứ 6 tạo thành tầng thứ ba 16 bit.
Hình 56: Sơ đồ mạch in mở rộng Port
Hình 57: Mạch hồn chỉnh
3.3.5 Giới thiệu bộ Kit thí nghiệm:
Bộ Kit thí nghiệm bao gồm: + Nguồn cung cấp 12V. + 32 Led đơn có chung Vcc.
+ 8 Led 7 đoạn ANot chung, theo kiểu quét Led. Điều khiển với mức logic 0.
+ 1 LCD 16x2, với 8 đường dữ liệu, 3 đường điều khiển.
+ 1 Led ma trận 8x8, với 2x8 đường điều khiển cột ( màu xanh hoặc đỏ) và 8 đường điều khiển hàng. Điều khiển với mức logic 1.
+ 1 ma trận phím 4x4 với 8 đường điều khiển.
3.4 Các bài tập ứng dụng:3.4.1 Quy ước chung: 3.4.1 Quy ước chung:
+ Chân 7 của eZ430-RF2500T là chân xung clock của 3 tầng ghi dịch. + Chân 12 của eZ430-RF2500T là chân Mass chung.
+ Chân 18 của eZ430-RF2500T là chân dữ liệu vào của tầng thứ nhất thanh ghi dịch.
+ Chân 16 của eZ430-RF2500T là chân điều khiển xung chốt của tầng thứ nhất thanh ghi dịch.
+ Chân 15 của eZ430-RF2500T là chân dữ liệu vào của tầng thứ hai thanh ghi dịch.
+ Chân 17 của eZ430-RF2500T là chân điều khiển xung chốt của tầng thứ hai thanh ghi dịch.
+ Chân 9 của eZ430-RF2500T là chân dữ liệu vào của tầng thứ ba thanh ghi dịch.
+ Chân 11 của eZ430-RF2500T là chân điều khiển xung chốt của tầng thứ ba thanh ghi dịch.
+ Chân 5, 6, 8, 10 của của eZ430-RF2500T được nối qua IC 2803 dùng để điều khiển tuỳ ý.
+ Chân 13,14 không sử dụng được.
3.4.2 Các lưu ý trước khi sử dụng:3.4.2.1 Cách truy xuất bit trong C: 3.4.2.1 Cách truy xuất bit trong C:
Như đã nghiêm cứu ở trên, vi điểu khiển MSP430 thường truy xuất Byte, muốn truy xuất bit ta phải định nghĩa lại vùng nhớ của nó.
Một cách truy xuất bit được sử dụng là:
union reg { // Khai báo 1 byte với 8 bit struct bit { // Khai báo bit trong 1 byte unsigned char b0:1; // Khai báo bit thứ 1
unsigned char b1:1; // Khai báo bit thứ 2 unsigned char b2:1; // Khai báo bit thứ 3
unsigned char b3:1; // Khai báo bit thứ 4 unsigned char b4:1; // Khai báo bit thứ 5 unsigned char b5:1; // Khai báo bit thứ 6 unsigned char b6:1; // Khai báo bit thứ 7 unsigned char b7:1; // Khai báo bit thứ 8 }_BIT; // Tên của bit trong byte unsigned char _BYTE; // Tên của byte
};
Ví dụ: Để khai báo chân xuất / nhập của Port 2 là:
union reg* _P2_DIRECT = (union reg*)0x2A ; // Định nghĩa vùng nhớ 0x2A là _P2_DIRECT, dùng điều khiển Port 2 là xuất hay nhập.
union reg* _P2_IN = (union reg*)0x28 ; // Định nghĩa vùng nhớ 0x28 là _P2_IN, dùng điều khiển các bit nhập của Port 2.
3.4.2.2 Cách mở rộng Port:
Ví dụ: Đưa dữ liệu 0xA4BC ra tầng thứ hai của thanh ghi dịch: Lưu đồ:
Kết nối phần cứng:
+ Nối chân 7 của eZ430-RF2500T làm chân xung clock tầng ghi dịch. + Nối chân 15 của eZ430-RF2500T làm chân dữ liệu vào của tầng thứ hai thanh ghi dịch.
+ Nối chân 17 của eZ430-RF2500T làm chân điều khiển xung chốt của tầng thứ hai thanh ghi dịch.
+ Nối chân 12 của eZ430-RF2500T làm chân Mass chung. Chương trình:
void MoRongP2(unsigned int q); // Khai báo hàm mở rộng tầng thứ hai union reg { // Khai báo 1 byte 8 bit
struct bit { unsigned char b0:1; unsigned char b1:1; unsigned char b2:1; unsigned char b3:1; unsigned char b4:1; unsigned char b5:1; unsigned char b6:1; unsigned char b7:1; }_BIT;
unsigned char _BYTE; };
union reg* _P3_DIRECT = (union reg*)0x1A ; // Định nghĩa vùng nhớ 0x1A union reg* _P3_OUT = (union reg*)0x19 ; // Định nghĩa vùng nhớ 0x19 union reg* _P2_DIRECT = (union reg*)0x2A ; // Định nghĩa vùng nhớ 0x2A union reg* _P2_OUT = (union reg*)0x29 ; // Định nghĩa vùng nhớ 0x29
int main(void) // Chương trình chính
{
WDTCTL = WDTPW + WDTHOLD; // Dừng ngắt
_P3_DIRECT->_BYTE = 0xff; // Định nghĩa Port 3 là xuất _P2_DIRECT->_BYTE = 0xff; // Định nghĩa Port 2 là xuất volatile unsigned int a; // Biến khai báo trong RAM
{
a=0xA4BC; // Gán a = A4BC
MoRongP2(a); // Mở rộng tầng 2 với 16 bit của a
} }
void MoRongP2(unsigned int e) // Hàm mở rộng tầng thứ 2 {
volatile unsigned int f,g,h; // Biến khai báo trong RAM f=0x8000; // Gán f=8000
g=16; // Cho g=16
while(g>0) // Trong khi g>0 thì thực hiện {
h = e&f; // h = e and f if ( h == f) // Nếu h=f {
}
Else // ngược lại h không =f {