12/08/2018, 14:53
Lập trình C cho hệ thống nhúng (P2- Lập trình nhúng với micro controller V850E)
1. Giới thiệu về micro controller V850E V850 là một dòng vi điều khiển của hãng NEC được sử dụng rộng rãi trong các hệ thống nhúng với nhiều mục đích khác nhau. Vơi ưu điểm lượng tiêu thụ điện năng thấp , mức nhiễu nhỏ trong khi vẫn mang lại một hiệu suất cao và được tích hợp nhiều chức năng. Một ...
1. Giới thiệu về micro controller V850E
V850 là một dòng vi điều khiển của hãng NEC được sử dụng rộng rãi trong các hệ thống nhúng với nhiều mục đích khác nhau. Vơi ưu điểm lượng tiêu thụ điện năng thấp , mức nhiễu nhỏ trong khi vẫn mang lại một hiệu suất cao và được tích hợp nhiều chức năng. Một số đặc tính của của V850
- Thời gian thực thi tối thiểu : 15.6ns (Tần số nội 64Mhz)
- Kiến trúc 32bit
- Có 32 thanh 32bit đa mục đích
- Cấu trúc nhân/chia
- Lưu trữ và sử dụng được các kiểu long/short
- Môi trường phát triển : PM+
2. Cấu trúc một chương trình trong hệ thống nhúng
- Ngay sau khi reset, chương trình sẽ thực hiện khởi tạo thiết lập phần cứng (xung nhịp clock, cấu hình các chân GPIO, khai báo các ngoại vi sẽ sử dụng trong chương trình …).
- Bước tiếp theo là là cấu hình phần mềm, cài đặt chế độ cho các ngoại vi, đăng ký các hàm xử lý ngắt…
- Sau khi đã xong các bước thiết lập và khởi tạo, chương trình sẽ đi vào vòng lặp vô hạn. Trong vòng lặp này sẽ có các hàm xử lý các sự kiện xảy ra đối với hệ thống. Trong vòng lặp vô hạn thường có thêm Watchdog timer để phát hiện và reset chương trình khi bị treo (chương trình quá thời gian quy định ở watchdog).
3. Khởi tạo CPU cho micro controller V850
- Khởi tạo những thanh ghi đặc biệt PCC dùng để điểu khiển clock của bộ vi xử lý
/************************************************************************************************************/ /*CPU Init */ /************************************************************************************************************/ __asm("mov 0x00, r10"); __asm("st.b r10, PRCMD [r0]"); __asm("st.b r10, PCC [r0]"); __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop");
- Thực hiện vòng lặp detect thanh ghi PLL nhằm mục đích biết được việc khởi tạo CPU ở trên đã hoàn thành hay chưa.
/************************************************************************************************************/ /* Detect PLL Register to confirm CPU Init finished */ /************************************************************************************************************/ for (ulCount=0 ; ulCount<0xFFFFFFFF ; ulCount++) { PLLCTL = 0x03; if ((PLLCTL & 0x02) == 0x02) { break; } }
- Khởi tạo các port cho CPU , trong một hệ thống ta có thể không cần thiết phải sử dụng tất cả các tài nguyên phần cứng của CPU , nhưng đối với một lập trình viên hệ thống nhúng có kinh nghiệm thì việc khởi tạo tất cả các phần cứng là bắt buộc. Các pin của CPU có thể mang nhiều chức năng khác nhau nên tùy mục đích sử dụng và thiết kế phần cứng mà chúng ta sẽ khởi tạo đúng cho chức năng đó. Dưới đây là ví dụ khởi tạo Port 0(8 pin) với các chức năng thay đổi độ rộng xung, và Input/ Output.
/************************************************************************************************************/ /*Port 0 Initial */ /************************************************************************************************************/ P0 = 0x00; PM0 = 0xC3; PMC0 = 0x00; PFC0 = 0x00; PFCE0 = 0x00; PU0 = 0x00;
Đừng quên khởi tạo cho các port còn lại nhé.
- Khởi tạo Watchdog Timer ・Chương trình chính của một CPU về bản chất là một vòng lặp chính vô hạn nên trong quá trình xử lý , khi gặp một lỗi dẫn đến không thể thoát khỏi một vòng lặp con nào đó thì sẽ dẫn đến CPU bị treo. Do đó chúng ta cần Watchdog Timer để reset lại chương trình. ・Watchdog Timer được quyết định dựa vào thời gian hoàn thành một vòng lặp chính .Trong vòng lặp chính , chúng ta chạy rất nhiều chương trình con thì nếu chúng ta thiết lập Watchdog timer ngắn , thì CPU chưa kịp hoàn thành một vòng chương trình chính đã bị Reset . Vì vậy theo kinh nghiệm thì sau khi bạn đã hoàn thành chương trình , chúng ta nên dùng oscilloscope (máy hiện sóng) để tiến hành đo một thời gian xử lý của mộ vòng chương trình chính , sau đó sẽ set lại thời gian cho WatchDog Timer.
#define WDCS_2_26 0x07 /* Overflow time 2^26/fxx: 1048.5ms */ WDTE = 0xAC; WDTM =(0x40 | WDCS_2_26);