Kênh Tên Miền chuyên cung cấp tên miền đẹp, giá rẻ! Hãy liên hệ kỹ thuật: 0914205579 - Kinh doanh: 0912191357 để được tư vấn, hướng dẫn miễn phí, Cảm ơn quý khách đã ủng hộ trong thời gian qua!
Saturday, December 7, 2013

Cortex là gì? Kiến trúc co bản của SMT32 - ARM Cortex M3

Trong vài nam trở lại đây, một trong những xu huớng chủ yếu trong các thiết kế với vi điều khiển là sử dụng các chip ARM7 và ARM9 nhu một vi điều khiển đa dụng. 
Ngày nay các nhà sản xuất IC đưa ra thị truờng hon 240 dòng vi điều khiển sử dụng lõi ARM. Tập đoàn ST Microelectronic vừa cho ra mắt dòng STM32, vi điều khiển đầu tiên dựa trên nền lõi ARM Cortex-M3 thế hệ mới do hãng ARM thiết kế, lõi ARM Cortex-M3 là sự cải tiến của lõi ARM7 truyền thống, từng mang lại sự thành công vang dội cho công ty ARM.
Dòng STM32 thiết lập các tiêu chuẩn mới về hiệu suất, chi phí, cung nhu khả nang đáp ứng các ứng dụng tiêu thụ nang luợng thấp và tính điều khiển thời gian thực khắc khe.



1.1 Cortex là gì? 



Dòng ARM Cortex là một bộ xử lí thế hệ mới đua ra một kiến trúc chuẩn cho nhu cầu đa dạng về công nghệ. Không giống nhu các chip ARM khác, dòng Cortex là một lõi xử lí hoàn thiện, dua ra một chuẩn CPU và kiến trúc hệ thống chung.

Dòng Cortex gồm có 3 phân nhánh chính: dòng A dành cho các ứng dụng cao cấp, dòng R dành cho các ứng dụng thời gian thực nhu các đầu đọc và dòng M dành cho các ứng dụng vi điều khiển và chi phí thấp. STM32 đuợc thiết kế dựa trên dòng Cortex-M3, dòng Cortex-M3 đuợc thiết kế đặc biệt để nâng cao hiệu suất hệ thống, kết hợp với tiêu thụ nang luợng thấp, CortexM3 đuợc thiết kế trên nền kiến trúc mới, do đó chi phí sản xuất đủ thấp để cạnh tranh với các dòng vi điều khiển 8 và 16-bit truyền thống.

Các chip ARM7 và ARM9 đuợc các nhà sản xuất bán dẫn thiết kế với giải pháp riêng của mình, đặc biệt là phần xử lí các các ngắt đặc biệt (exception) và các ngắt thông thuờng (interrupt). Cortex-M3 đưa ra một lõi vi điều khiển chuẩn nhằm cung cấp phần tổng quát, quan trọng nhất của một vi điều khiển, Trang 6 Author: ARMVN Kiến trúc co bản của SMT32 - ARM Cortex M3 www.arm.vn bao gồm hệ thống ngắt (interrupt system), SysTick timer (đuợc thiết kế cho hệ điều hành thời gian thực), hệ thống kiểm lỗi (debug system) và memory map. Không gian địa chỉ 4Gbyte của Cortex-M3 đuợc chia thành các vùng cho mã chuong trình, SRAM, ngoại vi và ngoại vi hệ thống.

Không giống với ARM7 đuợc thiết kế theo kiến trúc Von Neumann (bộ nhớ chuong trình và bộ nhớ dữ liệu chung với nhau), Cortex-M3 đuợc thiết kế dựa theo kiến trúc Harvard (bộ nhớ chuong trình và bộ nhớ dữ liệu tách biệt với nhau), và có nhiều bus cho phép thực hiện các thao tác song song với nhau, do đó làm tang hiệu suất của chip. Không giống với các kiến trúc ARM truớc đó, dòng Cortex cho phép truy cập dữ liệu không xếp hàng (unaligned data, vì chip ARM là kiến trúc 32bit, do đó tất cả các dữ liệu hoặc mã chuong trình đều đuợc sắp sếp khít với vùng bộ nhớ là bội số của 4byte). Ðặc điểm này cho phép sử dụng hiệu quả SRAM nội. Dòng Cortex còn hỗ trợ việc đặt và xoá các bit bên trong hai vùng 1Mbyte của bộ nhớ bằng phuong pháp gọi là bit banding. Ðặc điểm này cho phép truy cập hiệu quả tới các thanh ghi ngoại vi và các cờ đuợc dùng trên bộ nhớ SRAM mà không cần một bộ xử lí luận lí (Boolean processor).

 Khối trung tâm của STM32 là bộ xử lí Cortex-M3. Bộ xử lí Cortex-M3 là một vi diều khiển duợc tiêu chuẩn hoá gồm một CPU 32bit, cấu trúc bus (bus structure), don vị xử lí ngắt có hỗ trợ tính nang lồng ngắt vào nhau (nested interrupt unit), hệ thống kiểm lỗi (debug system) và tiêu chuẩn bố trí bộ nhớ (standard memory layout). Một trong những thành phần chính của lõi Cortex-M3 là NVIC (Nested Vector Interrupt Controller). NVIC cung cấp một cấu trúc ngắt chuẩn cho tất cả các vi diều khiển duợc thiết kế dựa trên lõi Cortex và cách xử lí các ngắt dặc biệt (exceptional interrupt). NVIC cung cấp các vector ngắt chuyên dụng lên tới 240 nguồn ngắt từ ngoại vi, mỗi nguồn ngắt dó có thể duợc uu tiên hoá với các mức riêng biệt. NVIC duợc thiết kế dể xử lí các ngắt dòi hỏi thời gian dáp ứng cực kì nhanh (extremely fast interrupt).


Thời gian từ lúc nhận một tín hiệu ngắt cho tới khi thực thi dòng lệnh dầu tiên trong trình phục vụ ngắt chỉ là 12 chu kì xung nhịp. Công việc này duợc thực hiện tự dộng bởi một vi chuong trình (microcode) duợc cài sẵn trong CPU. Trong truờng hợp xuất hiện các interrupt lồng nhau (tức là xảy ra ngắt khi dang xử lí ngắt truớc dó), NVIC sử dụng một phuong thức gọi là “tail chain” cho phép ngắt liên tiếp duợc phục vụ với dộ trễ chỉ có 6 chu kì xung nhịp. Trong suốt giai doạn luu trữ dữ liệu lên vùng nhớ stack dể bắt dầu thực thi chuong trình phục vụ ngắt, một ngắt có mức uu tiên cao hon ngắt hiện tại có thể cạnh tranh với (pre-empt) ngắt hiện tại mà không chịu bất kì trì hoãn nào. Cấu trúc ngắt cung di kèm với chế dộ tiết kiệm nang luợng của trong lõi Cortex-M3. CPU có thể duợc cấu hình tự dộng vào chế dộ tiết kiệm nang luợng sau khi thoát khỏi ngắt. Sau dó lõi tiếp tục ngủ cho dến khi một exception (ngắt dặc biệt) xuất hiện. Mặc dù Cortex-M3 duợc thiết kế nhu là một lõi chi phí thấp (low cost core), nhung nó vẫn là một CPU 32-bit và vẫn hỗ trợ hai chế dộ hoạt dộng: Thread và Handler, mỗi chế dộ có thể duợc cấu hình với mỗi vùng stack riêng biệt của nó, diều này cho phép thiết kế các phần mềm phức tạp và hỗ trợ các hệ diều Trang 8 Author: ARMVN Kiến trúc co bản của SMT32 - ARM Cortex M3 www.arm.vn hành thời gian thực. Lõi Cortex có hỗ trợ một timer 24-bit tự dộng nạp lại giá trị, nó sẽ cung cấp một ngắt timer dều dặn cho một nhận RTOS (Real Time Operating System). Các chip ARM7 vả ARM9 có hai tập lệnh (tập lệnh ARM 32-bit và tập lệnh Thumb 16-bit), trong khi dó dòng Cortex duợc thiết kế hỗ trợ tập lệnh ARM Thumb-2, tập lệnh này duợc pha trộn giữa tập lệnh 16 và 32bit, nhằm dạt duợc hiệu suất cao của của tập lệnh ARM 32-bit với mật dộ mã chuong trình tối uu của tập lệnh Thumb 16-bit. Tập lệnh Thumb-2 duợc thiết kế dặc biệt dành cho trình biên dịch C/C++, tức là các ứng dụng dựa trên nền Cortex hoàn toàn có thể duợc viết bằng ngôn ngữ C mà không cần dến chuong trình khởi dộng viết bằng assembler nhu ARM7 và ARM9. 1.2 Một vài dặc diểm nổi bật của STM32 ST dã dua ra thị truờng 4 dòng vi diều khiển dựa trên ARM7 và ARM9, nhung STM32 là một buớc tiến quan trọng trên duờng cong chi phí và hiệu suất (price/performance), giá chỉ gần 1 Euro với số luợng lớn, STM32 là sự thách thức thật sự với các vi diều khiển 8 và 16-bit truyền thống. STM32 dầu tiên gồm 14 biến thể khác nhau, duợc phân thành hai nhóm: dòng Performance có tần số hoạt dộng của CPU lên tới 72Mhz và dòng Access có tần số hoạt dộng lên tới 36Mhz. Các biến thể STM32 trong hai nhóm này tuong thích hoàn toàn về cách bố trí chân (pin) và phần mềm, dồng thời kích thuớc bộ nhớ FLASH ROM có thể lên tới 128K và 20K SRAM.

Kiến trúc của STM32 nhánh Performance và Access Trang 9 Author: ARMVN Kiến trúc co bản của SMT32 - ARM Cortex M3 www.arm.vn Dòng STM32 có hai nhành, nhánh Performance hoạt động với xung nhịp lên đến 72Mhz và có đầy đủ các ngoại vi, nhánh Access hoạt động với xung nhịp tối đa 36Mhz và có ít ngoại vi hon so với nhánh Performance.

 1.2.1 Sự tinh vi
Thoạt nhìn thì các ngoại vi của STM32 cung giống nhu những vi điều khiển khác, nhu hai bộ chuyển đổi ADC, timer, I2C, SPI, CAN, USB và RTC. Tuy nhiên mỗi ngoại vi trên đều có rất nhiều đặc điểm thú vị. Ví dụ nhu bộ ADC 12-bit có tích hợp một cảm biến nhiệt độ để tự động hiệu chỉnh khi nhiệt độ thay đổi và hỗ trợ nhiều mode chuyển đổi. Mỗi bộ timer có 4 khối capture compare, mỗi khối timer có thể liên kết với các khối timer khác để tạo ra một mảng các timer tinh vi. Một timer cao cấp chuyên hỗ trợ điều khiển động cơ, với 6 đầu ra PWM với dead time lập trình đuợc và một đuờng break input sẽ buộc tín hiệu PWM sang một trạng thái an toàn đã đuợc cài sẵn. Ngoại vi nối tiếp SPI có một khối kiểm tổng CRC bằng phần cứng cho 8 và 16 word hỗ trợ tích cực cho giao tiếp thẻ nhớ SD hoặc MMC. STM32 có hỗ trợ thêm 7 kênh DMA (Direct Memory Access).

Mỗi kênh có thể đuợc dùng để truyền dữ liệu đến các thanh ghi ngoại vi hoặc từ các thanh ghi ngoại vi đi với kích thuớc từ (word) dữ liệu truyền đi có thể là 8/16 hoặc 32-bit. Mỗi ngoại vi có thể có một bộ điều khiển DMA (DMA controller) đi kèm dùng để gửi hoặc đòi hỏi dữ liệu nhu yêu cầu. Một bộ phân xử bus nội (bus arbiter) và ma trận bus (bus matrix) tối thiểu hoá sự tranh chấp bus giữa truy cập dữ liệu thông qua CPU (CPU data access) và các kênh DMA. Ðiều dó cho phép các don vị DMA hoạt động linh hoạt, dễ dùng và tự động điều khiển các luồng dữ liệu bên trong vi điều khiển. STM32 là một vi điều khiển tiêu thụ nang luợng thấp và đạt hiệu suất cao.

Nó có thể hoạt động ở điện áp 2V, chạy ở tần số 72MHz và dòng tiêu thụ chỉ có 36mA với tất cả các khối bên trong vi điều khiển đều đuợc hoạt động. Kết hợp với các chế độ tiết kiệm nang luợng của Cortex, STM32 chỉ tiêu thụ 2µA khi ở Trang 10 Author: ARMVN Kiến trúc co bản của SMT32 - ARM Cortex M3 www.arm.vn chế độ standby. Một bộ dao động nội RC 8MHz cho phép chip nhanh chóng thoát khỏi chế độ tiết kiệm nang luợng trong khi bộ dao động ngoài đang khởi động.

Khả nang nhanh đi vào và thoát khỏi các chế độ tiết kiệm nang luợng làm giảm nhiều sự tiêu thụ nang luợng tổng thể.

 1.2.2 Sự an toàn 
 Ngày nay các ứng dụng hiện đại thuờng phải hoạt động trong môi truờng khắc khe, đòi hỏi tính an toàn cao, cung nhu đòi hỏi sức mạnh xử lý và càng nhiều thiết bị ngoại vi tinh vi. Ðể dáp ứng các yêu cầu khắc khe đó, STM32 cung cấp một số tính nang phần cứng hỗ trợ các ứng dụng một cách tốt nhất. Chúng bao gồm một bộ phát hiện điện áp thấp, một hệ thống bảo vệ xung clock và hai bộ watchdogs. Bộ đầu tiên là một watchdog cửa sổ. Watchdog này phải đuợc làm tuoi trong một khung thời gian xác dịnh. Nếu nhấn nó quá sớm, hoặc quá muộn, thì watchdog sẽ kích hoạt. Bộ thứ hai là một watchdog độc lập, có bộ dao động bên ngoài tách biệt với xung nhịp hệ thống chính. Hệ thống bảo vệ xung nhịp có thể phát hiện lỗi của bộ dao động chính bên ngoài (thuờng là thạch anh) và tự động chuyển sang dùng bộ dao động nội RC 8MHz.

1.2.3 Tính bảo mật 
 Một trong những yêu cầu khắc khe khác của thiết kế hiện đại là nhu cầu bảo mật mã chuong trình để ngan chặn sao chép trái phép phần mềm. Bộ nhớ Flash của STM32 có thể duợc khóa dể chống truy cập đọc Flash thông qua cổng debug. Khi tính nang bảo vệ đọc đuợc kích hoạt, bộ nhớ Flash cung đuợc bảo vệ chống ghi để ngan chặn mã không tin cậy đuợc chèn vào bảng vector ngắt. 

Hướng Dẫn Lập Trình ARM - LPC1343

Nội Dung:
Giới Thiệu về LPC1343
+ Giới thiệu LPCXpresso LPC1343 board
+ Hướng dẫn Lập Trình cho LPC1343 bằng LPCXpresso IDECode Red
        + Cài đặt LPCXpresso IDE Code red
        + Tạo Project trong LPCXpresso IDE Code red
        + Code mẫu ARM LPC1343

Giới Thiệu về LPC1343
+ LPC1343 thuộc dòng Vi điều khiển ARM Cortex-M3, kiến trúc Harvard.
+ Hoạt động ở tần số CPU lên đến 72MHz.
+ 32KB bộ nhớ chương trình, 8KB SRAM, USB Device.
+ USB 2.0, UART hỗ trợ RS-485, I2C, 42 PINs I/O
+ WatchDog Timer
...

Sơ Đồ Khối

Các PIN


Kit phát triển: LPCXpresso development board



+ Trên Board gồm 2 thành phần: LPC-Link và Target.
+ LPC-Link là một mạch nạp với 1 dăm 10 PINs dành cho việc kết nối vớicác thiết bị khác. Bên cạnh đó nó được kết nối sẵn với bo mạch LPC1343 qua một giao diện USB để tiến hành nạp Kit, debug.
+ LPC1343 có thể dễ dàng kết nối ra ngoài qua các chân được nối sẵn.

Hướng dẫn Lập Trình cho LPC1343

Cài đặt chương trình
+ Để lập trình ứng dụng cho Kit LPCXpresso LPC1343, ta sử dụng trình biên dịch LPCXpresso IDE - Code Red.
+ Để Download phần mềm: các bạn vào trang http://lpcxpresso.code-red-tech.com/LPCXpresso/ tạo tài khoản:


Đăng nhập vào và Download:

Chọn Windows (Hoặc Linux)

Chọn bản mới nhất:


... đợi tải về, cài đặt theo mặc định.

Sau khi cài đặt, chạy phần mềm. Để kích hoạt FULL phần mềm, các bạn vào Help -> Product activation -> Create Serial number and Activate:


Coppy Serial number lại:

Nhấn OK, giao diện làm việc của LPCXpresso IDE sẽ tự động chuyển đến trang đăng ký cho bạn: (hoặc bạn có thể đăng nhập lại vào website ở trên)

Sau khi nhập Serial number vào, ấn send me my activation code, Code sẽ được gửi vào email đăng ký của bạn:

Coppy code, vào Help -> Product activation -> Enter Activation code và nhập Code. Xong ok!







Các Bước Tạo Project trong LPCXpresso IDE

Bước 1: chọn nơi chứa Project
+ Chọn File -> Switch Workspace -> Other, rồi chọn thư mục mong muốn.
(ta nên tạo riêng 1 thư mục cho Project, và coppy file thư viện chính (CMSIS) vào cùng Folder này)



Bước 2: Nhập thư viện CMSIS
+ Thư viện CMSISv2p00_LPC13xx.zip cho LPC1343 - Download tại đây!
Chọn Import Project(s) -> Browse, chọn đến thư viện CMSIS 2.0 LPC13xx.






Sau khi add, thư viện sẽ hiển thị trong thẻ Project Ex.








Bước 3: Tạo Project mới
Trong thẻ Quickstart: Chọn New project ->  NXP LPC1300 -> C Project -> Next:




Đặt tên Project:



Chọn loại LPC cụ thể (LPC1343):



Bỏ chọn mục Enable CRP in the target image -> Finish:


Chương trình chính của chúng ta sẽ được viết trong file main.c, chúng ta sẽ viết thử 1 chương trình nháy LED ở chân P0.7:



Bước 4: Thêm các file thư viện cần thiết


+ Để thực hiện chương trình nháy LED, chúng ta cần phải cấu hình các chân của LPC, thực hiện trễ, do đó ta cần đến 2 file thư viện là gpio.c, gpio.h và timer32.c, timer32.h. Tiến hành kéo thả các file đó vào thư mục src trong Project:
+ Các bạn có thể download một số thư viện ở đây




Bước 5: Viết chương trình

Chương trình trong hàm main.c:
#include "LPC13xx.h"                        /* LPC13xx definitions */
#include "gpio.h"
#include "timer32.h"

/* Main Program */

int main (void)
{
  init_timer32(0, TIME_INTERVAL); //cấu hình timer0
  enable_timer32(0);                            //cho phép timer0 hoạt động

  GPIOInit();                                       //khởi tạo GPIO
  GPIOSetDir( 0 , 7 , 1 );                    //Đặt chân P0.7 là đầu ra "1"

  while (1)                                /* Loop forever */
  {

     GPIOSetValue( 0 , 7 , 1 );             //Set chân P0.7 lên "1"
     delay32Ms(0,500);                        //trễ 500Ms
     GPIOSetValue( 0 , 7 , 0 );             //Set chân P0.7 về "0"
     delay32Ms(0,500);                        //trễ 500Ms
  }
}



Bước 6: Thêm đường dẫn đến các thư mục chứa thư viện


+ Ở đây ta sử dụng các thư viện của CMSIS trong thư mục inc, src của nó, và các thư viện khác trong thư mục chính src của Project. Do đó ta cần phải chỉ rõ đường dẫn đến các thư mục này:
+ Chuột phải vào tên của Project trong thẻ Project Ex -> chọn Properties:



+ Cửa sổ Properties hiện ra: Chọn C/C++ Build -> Settings -> Tool Settings -> Includes -> Ấn vào biểu tượng Add -> Workspace -> chọn Folder muốn Add -> Ok (8) -> Lại chọn tiếp các Folder còn lại -> Sau khi Add hết ấn Ok (9) :






Bước 7: Build chương trình
Trong thẻ Quickstart chọn Build 'demo' [Debug] , đợi cho chương trình Build xong -> xuất hiện thông báo:




Bước 8: Nạp vào Board LPC1343
+ Dùng Cable USB kết nối Board LPC1343 với PC.
+ Nạp chương trình: mở Folder Debug trong giao diện Project -> chuột phải vào file demo.axf -> Chọn Binary Utilities -> Program Flash :




+ Kết quả sau khi nạp xong: (LED trên Board sẽ nháy theo như chương trình)




Một số chương trình mẫu: Download ở đây!

Cấu Trúc Cơ bản STM32- Sử Dụng ADC Của STM32F103RC

Ở bài này chúng ta sẽ tiếp cận cách sử dụng bộ ADC của STM32F103RC thông qua các ứng dụng chuyển đổi giá trị tín hiệu tương tự sang số.
  1 Môi trường phát triển phần cứng

1.1 Hỗ trợ ADC của GEM3v0.1
Ở board GEM3v0.1, có nhiều chân được thiết kế dành riêng cho các tác vụ tổng hợp như: GPIOs, PWM, ADC, DAC, TIMER, Temperature sensor,…
Ở hình trên ta thấy chân số 14 của STM32F103x được thiết kế đa chức năng. Ở ví dụ này, chúng ta sẽ sử dụng nó như là đầu vào dữ liệu cho bộ ADC.
Một số đặc tính cơ bản của bộ ADC của STM32F103x:
    + Độ phân giải 12-bit và tần suất lấy mẫu là 56MHz(khoảng 1us một mẫu).
    + 18 kênh chuyển đổi trong đó: 16 kênh dành cho tín hiệu ngoại được đánh số lần lượt từ: AIN0,AIN1,…AIN15; 2 kênh còn lại dành cho cảm biến nhiệt nội và vôn kế nội.
    + Bộ ADC được cấp nguồn riêng từ 2.4V đến 3.6V.
    + Hỗ trợ 2 loại chuyển đổi: regular, injected.
Ở board GEM31v0.1, bộ ADC được cấp nguồn trực tiếp 3.3V. Điện áp tham chiếu Vref+ bằng 3.3V.
Độ phân giải 12bit cho phép mã hóa các tín hiệu tương tự từ 0->3.3 sang giá trị số từ 0->4095.  Giá trị lượng tử được tính bằng:
    Quantizer = 3.3 / 2^12 = 3.3/4096 = 0.8mV
1.2 Cảm biến nhiệt LM35DZ
Cảm biến nhiệt LM35DZ gồm 3 chân:
Nguồn cung cấp cho chân +Vs vào khoảng từ 4V đến 30V.  Ở chân xuất dữ liệu, khi nhiệt độ bằng 0 điện áp ra sẽ là 0V. Cảm biến này đo nhiệt độ theo thang Celcius. Cứ mỗi một đơn vị nhiệt độ sẽ tương ứng với 10mV. Và mức thay đổi là tuyến tính. Ví dụ nếu nhiệt độ hiện giờ là 25 độ Celcius, thì điện áp xuất sẽ là 10mVx25 = 250mV. Như vậy, với giá trị lượng tử là 0.8mV, chúng ta hoàn toàn có khả năng lấy mẫu chính xác giá trị từ cảm biến nhiệt.
Trong ứng dụng tích hợp với board GEM3v0.1, nguồn cấp cho cảm biến là 5V.
Sơ đồ mạch kết nối với STM32 được thiết kế như sau:
2 Cấu trúc chương trình
2.1 Sơ đồ khối
2.2 Cấu hình hoạt động ADC
Giải thích:
(1): Sử dụng hàm chuẩn thư viện CMSIS RCC_APB2PeriphClockCmd để kích hoạt các ngoại vi trên APB2, ở đây ta kích hoạt ADC1:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
(2): Để nhận được dữ liệu dạng tương tự, ta phải cấu hình chân dữ liệu hoạt động ở chế độ Analog Input. Ở demo này, ta sử dụng chân số 14 , tương ứng là chân 0(GPIO_Pin_0) của Port A(GPIOA) , ký hiệu là PA0
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
(3): Cấu hình chế độ hoạt động của ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
(4): Cấu hình ADC Channel, ở ví dụ này, ta cấu hình ADC Channel 0 (ADC_Channel_0)  hoạt đông như là Regular Channel với thời gian lấy mẫu là 55 chu kỳ
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
(5): Kích hoạt bộ ADC1
ADC_Cmd(ADC1, ENABLE);
(6): Kích hoạt Reset Calibration, khởi động lại bộ lấy mẫu chuẩn và chờ cho quá trình tái khởi động hoàn tất
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
(7): Kích hoạt chế độ lấy mẫu và cũng chờ cho nó hoàn tất
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
(8): Kích hoạt chế độ chuyển đổi
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
2.3 Đọc dữ liệu từ LM35DZ
Chân dữ liệu của LM35DZ được nối trực tiếp tới chân PA0. Để đọc dữ liệu đã được chuyển đổi bởi khối ADC1 ta sử dụng hàm
uint16_t adc = 0;
adc = ADC_GetConversionValue(ADC1);
Giá trị này đã được lượng tử hóa , do đó chúng ta phải tính toán lại giá trị thực theo công thức:
    Điện áp thực = Vref * (Giá trị lượng tử) / 2^n
              = 3.3 * (giá trị lượng tử)/ 4096.
Giả sử giá trị chuyển đổi đọc từ ADC1 là 251, khi đó điện áp thực nhận từ LM35DZ là:
    Điện áp thực = 3.3 * 251 / 4096  = 202mV
Khi đó nhiệt độ thực sẽ là:
    Nhiệt độ thực = Điện áp thực / 10 = 20.2 độ C
3. Tài nguyên chương trình
Download dự án ở đây.
Các bạn dùng cáp cổng COM nối board với máy tính để coi giá trị đọc từ cảm biến.

Cấu trúc ARM Cortex M3 trên chip LPC1768

(Linh Kiện Điện Tử) LPC1768 là 1 loại vi điều khiển sử dụng lõi ARM Cortex – M3 có tốc độ hoạt động cao 120MHz. Với đặc điểm của ARM Cortex – M3 sử dụng cấu trúc Harvard phân tầng 3-stage. Ngoại vi của LPC17xx gồm bộ nhớ flash 512kB, bộ nhớ dữ liệu 64kB, hỗ trợ Ethernet MAC, Host, Device, OTG USB, 8 kênh điều khiển GPDMA, 4 UART, 2 CAN, 2 SSP, SPI, 3 giao diện I2C, 2 I2S, 8 kênh ADC 12bit, bộ điều khiển NVIC 32bit, DAC 10bit, QEI, 4 timer, 6 PWM, RTC, 70 pin GPIO.
Ngoài ra LPC1768 còn hỗ trợ bộ điều khiển motor MCPWM, bộ điều khiển này cho phép người dùng điều khiển xung ra như mong muốn nhờ có thanh ghi Match, giúp hỗ trợ tốt trong việc điều khiển các loại động cơ 3 pha AC, DC và những ứng dụng cần chính xác về timing, counting, capture and comparation.
MCPWM có 3 kênh, mỗi kênh có thanh ghi Timer/Counter, Limit, Match 32bit, dead-time 10 bit, capture 32 bit, 2 ngõ ra modulated (MCOA và MCOB).


  

[Lập trình ARM-LPC2378] Tổ Chức Bộ Nhớ, Thiết Lập Pin, GPIO, Debug

Tổ Chức Bộ Nhớ, Thiết Lập Pin, GPIO, Debug

Nội Dung
Cách tổ chức bộ nhớ trong LPC2378
+ Cách thiết lập PIN
+ Debug chương trình


Cách tổ chức bộ nhớ trong LPC2378
+ Bộ xử lý ARM có thể quản lý một không gian địa chỉ bộ nhớ 4Gb
+ Bảng sau đây thể hiện sự phân bố địa chỉ của vùng bộ nhớ trong các thiết bị ARM:



Địa chỉ vùng nhớ LPC23xx

Cách thiết lập PIN
Cấu hình PIN - LPC2378
Chip LPC2378 có 144 chân. Với sơ đồ chân như sau:


+ Mỗi chân tương ứng có những chức năng, nhiệm vụ khác nhau.
Ví Dụ:


Thanh ghi PINSEL
Các thanh ghi PINSEL (PINSEL0 - PINSEL10) đảm nhiệm việc kết nối giữa các PIN và các thiết bị ngoại vi.
+ Các thanh ghi cấu hình này điều khiển thiết lập những chức năng khác nhau, với mỗi 2Bit tương ứng ta có 4 trường hợp như sau:


Ví Dụ:


Địa chỉ thanh ghi PINSEL
+ Mỗi thanh ghi PINSEL có 4Bytes




GPIO
+ Viết tắt của: General Purpose Input Output.
+ Là chân input/output.
+ LPC2378 có 104 chân có chức năng GPIO.
+ Được thiết lập qua 5 Port 32Bit:


+ Việc điều khiển trực tiếp trong thanh ghi GPIO chỉ có hiệu quả khi chức năng GPIO được chọn tại các PICSEL.
Ví Dụ:

+ Muốn chọn Port0.0 và 0.1 là GPIO thì PINSEL0=0x00; (giá trị mặc định của PINSEL).
Low GPIO được điều khiển bởi các thanh ghi: IOPIN, IOSET, IODIR, IOCLR. (Chỉ cho Port0 và Port1)
+ Fast GPIO được điều khiển bởi các thanh ghi: FIOPIN, FIOSET, FIODIR, FIOCLR, FIOMASK.



Ví Dụ:
Cấu hình Port0.6 là output:
        - IODIR0 = 0x00000040; //Bit thứ 6 được bật lên 1: [ 0000 0000 0100 0000 ]
+ Cấu hình Port0.6 ở mức tín hiệu cao:
        - IOSET0 = 0x00000040;
+ Cấu hình Port0.6 ở mức tín hiệu thấp:
        - IOCLR0 = 0x00000040;

Ví Dụ - Lập trình LED trên Board MCB2300
Các đèn LED trên Board được thể hiện qua Port2.0 đến port2.7:
Void LED_Init(void)
{
     PINSEL10 = 0;
     FIO2DIR = 0x000000FF; //P2.0 - P2.7 là Output.
     FIO2MASK = 0x00000000;
}
+ Tắt / mở LES:
Void LED_On(unsigned int num)
{
     FIO2SET = (1<<num); //VD: n=2 => FIO2SET = (1<<2) <=> FIO2SET = 0x04;
}
Void LED_Off(unsigned int num)
{
     FIO2CLR = (1<<num);
}


Debug chương trình
Debug

[Lập trình PIC] Các Ngắt Trong PIC




Các Ngắt Trong PIC


I /  CƠ CHẾ HOẠT ĐỘNG CỦA NGẮT : 
1 / Ngắt 1 cấp : 
+ Trên PIC 14 , 12 ,10 ,tất cả các ngắt chỉ có 1 cấp ưu tiên . Nghĩa là ngắt nào đang được phục vụ thì không thể bị ngắt bởi 1 ngắt khác xảy ra . Cơ chế sinh mã cho ngắt của CCS như sau : nhảy đến địa chỉ ngắt , thường là 004h , sao lưu thanh ghi W,  STATUS , PCLATCH , FSR,  và nhiều thứ vớ vẫn khác,   sau đó nó mới hỏi vòng xem cờ ngắt nào xảy ra  thì nhảy đến hàm phục vụ ngắt đó . thực hiện xong thì phục hồi tất cả thanh ghi trên , rồi mới “RETFIE” – thoát ngắt . Số chu kỳ thực thi từ chỗ ngắt đến khi nhảy vào hàm ngắt cỡ 20 chu kỳ lệnh !, nhảy ra cũng cỡ đó .
+ Điều gì xảy ra nếu chương trình dùng nhiều ngắt và khi có ngắt thì có 2 ngắt trở lên xảy ra đồng thời ? Nghĩa là : 2 ngắt xảy ra cùng lúc , hay khi ngắt A kích hoạt và CCS đang lưu các thanh ghi ( chưa tới hỏi vòng cờ ngắt ) thì ngắt B xảy ra , dĩ nhiên ngắt B không thể kích vector ngắt nhảy tới 004h vì bit cho phép ngắt toàn cục ( GIE ) bị khóa tự động khi có ngắt , chỉ có cờ ngắt B bật mà thôi. Sau khi lưu các thanh ghi , chương trình  kiểm tra cờ ngắt , rõ ràng là nếu bit nào được kiểm tra trước thì  phục vụ trước , dù nó xảy ra sau . Để tránh phục vụ không đúng chỗ , bạn dùng #priority để xác định ưu tiên ngắt ( xem phần chỉ thị tiền xử lý ) . Ngắt ưu  tiên nhất sẽ luôn được hỏi vòng trước .Sau khi xác định cờ ngắt cần phục vụ , nó sẽ thực thi hàm ngắt tương ứng .Xong thì xoá cờ ngắt đó và thoát ngắt . Phục vụ ngắt nào xong thì chỉ xoá cờ ngắt đó .Nếu A ưu tiên hơn B  thì sau khi làm A , chương trình  xoá cờ ngắt A , nhưng cờ B không xoá ( vì đâu có phục vụ ) , nên khi thoát ra ngắt A , nó sẽ lại ngắt tiếp ( vì cờ B đã bật ), lại hỏi vòng cờ ngắt từ đầu : nếu cờ A chưa bật thì xét B, lúc này B bật nên phục vụ B , xong thì xoá cờ B và thoát ngắt .
+ Môt chương trình dùng nhiều ngắt phải lưu ý điều này , tránh trường hợp : ngắt xảy ra liên tục (tràn
ngắt ) , 1 ngắt bị đáp ứng trễ  , ngắt không đúng , . . .



2 / Ngắt 2 cấp : 
+ Chỉ có trên PIC 18 ( và dsPIC ) . Có 2 khái niệm : ngắt ưu tiên thấp (low priority) và ngắt ưu tiên cao ( high priority ) . 2 vector thực thi ngắt tương ứng thường là 0008h (high) và 0018h ( low ) . Một  ngắt thấp đang được phục vụ sẽ bị ngưng và phục vụ ngắt cao ở 0008h nếu ngắt cao xảy ra . Ngược lại , ngắt cao đang xảy ra thì không bao giờ bị ngắt bởi ngắt thấp .
+ Nếu viết hàm ngắt bình thường , không đòi hỏi ưu tiên gì thì CCS sinh mã để tất cả hàm ngắt đều là ngắt ưu tiên cao . Quy trình thực hiện ngắt sẽ như ngắt 1 cấp trên . #priority vẫn được dùng . Số chu kỳ thực thi từ 0008h đến khi nhảy vào thực thi hàm ngắt khoảng 30 chu kỳ , xong hàm ngắt tới khi kết thúc ngắt cũng mất khoảng 30 chu kỳ lệnh .
+ Để sử dụng ngắt 2 cấp ,  khai báo #device phải có high_ints=true . Và hàm ngắt nào muốn ưu tiên cao thì thêm FAST hay HIGH theo sau chỉ thị tiền xử lý hàm đó .
Lưu ý : khi dùng FAST thì không nên dùng HIGH cho các ngắt khác thì mới có ý nghĩa và chỉ  có duy nhất 1 ngắt được ưu tiên FAST , nhưng  có thể có nhiều ngắt đặt ở mức HIGH .
VD :
#int_timer1  FAST 
 Void xu_ly ( ) 
  { . . . 
 } 

 #int_timer2  HIGH 
 Void dinh_thi () 
  { . . . 
 } 

 #int_timer5 HIGH  
 Void vong_lap() 
  { . . . 
 } 

+ Cơ chế sinh mã như sau : có ngắt thấp thì nhảy tới 0018h , sao lưu W, STATUS , FSR0/1/2 ,. . . rồi mới hỏi vòng cờ ngắt thấp . chạy xong hàm ngắt  thì phục hồi tất cả và “RETFIE 0 “ .
+ Riêng ngắt cao đánh dấu FAST không sinh mã sao lưu gì cả mà nhảy thẳng vào hàm ngắt chạy luôn . PIC 18 và dsPIC có cơ chế lưu siêu tốc là FAST STACK REGISTER ( xem datasheet ) . Khi xảy ra ngắt bất kỳ,  W, S , BSR tự động lưu vào thanh ghi trên , PC counter lưu vào stack . xong ngắt thì pop ra . Vấn đề ở chỗ : khi ngắt thấp xảy ra , FAST STACK REGISTER tự động lưu W ,S , BSR , PC -> stack . Trong khi thực hiện hàm phục vụ ngắt thì trường hợp W, S , BSR thay đổi là có thể ( vì vậy mới sao lưu chứ ) . nhưng nếu xảy ra ngắt cao vào thời điểm đó ? FAST STACK REGISTER sẽ bị ghi đè => mất data . Do đó , cơ chế sinh mã của CCS cần phải luôn đúng , nghĩa là : luôn tự sao lưu riêng W ,S , BSR, và các thanh ghi FSR nữa , khi thực  thi ngắt thấp . Còn ngắt cao FAST khi chạy xong sẽ “RETFIE 1 “ – tự động phục hồi W, S , BSR từ  FAST STACK REGISTER . Có 2 trường hợp : 1 là chỉ có ngắt cao , thì không có vấn đề gì  . 2 là ngắt cao ngắt 1 ngắt thấp đang chạy . Phân tích sẽ thấy rằng cho dù bị ngắt trong khi đang sao lưu ,hay chưa kịp sao lưu , hay đã sao lưu vào các biến riêng rồi , cuối cùng chương trình cũng quay ra đúng địa chỉ ban đầu với các thanh ghi W, S , BSR như cũ .
+ Tuân thủ nguyên tắc ngắt cao thực thi tức thời nên CCS chỉ cho 1 ngắt cao FAST duy nhất bất kỳ hoạt động ,  nên không sinh mã hỏi vòng , sao lưu thêm gì cả .
+ Nếu bạn muốn có nhiều ngắt ưu tiên cao , thì dùng HIGH , chương trình sao lưu bình thường như với ngắt thấp , nhưng khi đó ngắt đánh dấu FAST cũng mất tác dụng , CCS xem như là HIGH và xử lý bình thường .

_Như vậy dùng FAST hay HIGH đều có ý nghĩa riêng của nhà  lập trình .

II / KHAI BÁO NGẮT :
_Mỗi dòng VDK có số lượng nguồn ngắt ngắt khác nhau : PIC 14 có 14 ngắt , PIC 18 có 35 ngắt .
_Muốn biết CCS hỗ trợ những ngắt nào cho VDK của bạn , mở file *.h tương ứng , ở cuối file là
danh sách các ngắt mà CCS hỗ trợ nó . Cách khác là vào CCS -> View -> Valid interrupts , chọn
VDK muốn xem , nó sẽ hiển thị danh sách ngắt có thể có cho VDK đó .
_Sau đây là danh sách 1 số  ngắt với chức năng tương ứng :
#INT_GLOBAL : ngắt chung , nghĩa là khi có ngắt xảy ra , hàm theo sau chỉ thị này được thực
thi , bạn sẽ không được khai báo thêm chỉ thị ngắt nào khác khi sử dụng chỉ thị này . CCS không sinh
bất kỳ mã lưu nào , hàm ngắt bắt đầu ngay tại vector ngắt . Nếu bật nhiều cờ cho phép ngắt , có thể
bạn sẽ phải hỏi vòng để xác định ngắt nào . Dùng chỉ thị này tương đương viết hàm ngắt 1 cách thủ
công  mà thôi , như là viết hàm ngắt với ASM vậy .


#INT_AD  : chuyển đổi A /D đã hoàn tất , thường  thì không nên dùng
#INT_ADOF  : I don’t know
#INT_BUSCOL : xung đột bus
#INT_BUTTON : nút nhấn ( không biết hoạt động thế nào )
#INT_CCP1  : có Capture hay compare trên CCP1
#INT_CCP2  : có Capture hay compare trên CCP2
#INT_COMP  : kiểm tra bằng nhau trên Comparator
#INT_EEPROM : hoàn thành ghi EEPROM
#INT_EXT  : ngắt ngoài
#INT_EXT1  : ngắt ngoài 1
#INT_EXT2  : ngắt ngoài 2
#INT_I2C  : có hoạt động I 2C
#INT_LCD  : có hoạt động LCD
#INT_LOWVOLT : phát hiện áp thấp
#INT_PSP  : có data vào cổng Parallel slave
#INT_RB  : bất kỳ thay đổi  nào trên chân B4 đến B7
#INT_RC  : bất kỳ thay đổi  nào trên chân C4 đến C7
#INT_RDA  : data nhận từ RS 232 sẵn sàng
#INT_RTCC  : tràn Timer 0
#INT_SSP  : có hoạt động SPI hay I 2C
#INT_TBE  : bộ đệm chuyển RS 232 trống
#INT_TIMER0 : một tên khác của #INT_RTCC
#INT_TIMER1 : tràn Timer 1
#INT_TIMER2 : tràn Timer 2
#INT_TIMER3 : tràn Timer 3
#INT_TIMER5 : tràn Timer 5
#INT_OSCF               : lỗi OSC
#INT_PWMTB          : ngắt cuả PWM time base
#INT_IC3DR             : ngắt đổi hướng ( direct ) của IC 3
#INT_IC2QEI            : ngắt của QEI
#INT_IC1                   : ngắt IC 1


+ Hàm đi kèm phục vụ ngắt không cần tham số vì không có tác dụng .
+ Sử dụng NOCLEAR sau #int_xxx để CCS không xoá cờ ngắt của hàm đó .

+ Để cho phép ngắt đó hoạt động phải dùng lệnh enable_interrupts ( int_xxxx) vàenable_interrupts (global ) .
+ Khoá FAST theo sau #int_xxxx để cho ngắt đó là ưu tiên cao , chỉ được 1 ngắt thôi , chỉ có ở PIC 18 và dsPIC .
VD : #int_timer0  FAST  NOCLEAR 


III / CÁC HÀM THIẾT LẬP HOẠT ĐỘNG NGẮT : 
1 /  enable_interrupts ( level ) 
+ level là tên các ngắt đã cho ở trên hay là GLOBAL để cho phép ngắt ở cấp toàn cục .
+ Mọi ngắt của VDK đều có 1 bit cờ ngắt , 1 bit cho phép ngắt . Khi có ngắt thì bit cờ ngắt bị set =1, nhưng ngắt có họat động được hay không tuỳ thuộc  bit  cho phép ngắt . enable_interrupts (int_xxx ) sẽ bật bit cho phép ngắt . Nhưng tất cả các ngắt đều không thể thực thi nếu bit cho phép ngắt toàn cục = 0, enable_interrupts( global ) sẽ bật bit này .
VD : để cho phép ngắt timer0 và timer1  hoạt động:
enable_interrupts (int_timer0); 
enable_interrupts (int_timer1 ) ; 
enable_interrupts ( global );  // chỉ cần dùng 1 lần trừ phi muốn có thay đổi đặc biệt

2 / disable_interrupts ( level ) 
+ level giống như trên .
+ Hàm này vô hiệu 1 ngắt bằng cách set bit cho phép ngắt = 0 .
disable_interrupts ( global ) set bit cho phép ngắt toàn cục =0 , cấm tất cả các ngắt .
+ Không  dùng hàm này trong hàm phục vụ ngắt vì không có tác dụng , cờ ngắt luôn  bị xoá tự động .

3 / clear_interupt ( level ) 
+ level không có GLOBAL .
+ Hàm này xoá cờ ngắt của ngắt được chỉ định bởi level .

4 / ext_int_edge ( source , edge ) 
+ Hàm này thiết lập nguồn ngắt ngoài EXTx là cạnh lên hay cạnh xuống .
source : nguồn ngắt . Trên PIC 18 có 3 nguồn ngắt trên 3 chân EXT0, EXT1, EXT2 ứng với source =0,1, 2 . Các PIC khác chỉ có 1 nguồn EXT nên source = 0 .
edge : chọn cạnh kích ngắt , edge = L_TO_H nếu chọn  cạnh lên ( từ mức thấp  chuyển lên mức cao ) hay H_TO_L nếu chọn cạnh xuống .


IV / CÁC CHƯƠNG TRÌNH VD VỀ NGẮT :
  1 /  #INT_RB : 
+ Sau đây là 1 chương trình điển hình về sử dụng ngắt khi có sự thay đổi trên chân B4-B7 .
+ Mô tả : mỗi khi nhấn nút bất kỳ trên B4-B7 , sẽ kích ngắt RB , hàm phục vụ ngắt có tên  RB_LED được thực thi , hàm này đơn giản là xuất ra LED ở vị trí tương ứng nhưng trên portD từ D4 – D7 .
+ VDK là 16F877 .


#include < 16F877.h > 
#device  PIC16F877 *=16 
#use delay (clock = 20000000 )  //thêm khai báo này nếu ctrình có dùng hàm delay,OSC=20 Mhz 
#byte portb = 0x06      //tạo tên danh định portb thay thế địa chỉ portB là 06h 
#byte portd = 0x08      //tạo tên danh định portd thay thế địa chỉ portD là 08h 

#INT_RB 
Void RB_LED ( )      // hàm phục vụ ngắt 
   portd=portb; 

void main ( ) 
{  set_tris_b ( 0xF0 ) ;    // portB = 11110000 , B4-B7 là ngõ vào , B0-B3 là ngõ ra 
    set_tris_d ( 0x00 ) ;    // portD = 00000000 , D0-D7 đều là ngõ ra 
    enable_interrupts ( INT_RB ) ;  // cho phép ngắt RB 
    enable_interrupts ( GLOBAL ) ;  // cho phép ngắt toàn cục 
// do chương trình không làm gì khác ngoài việc chờ ngắt nên vòng while này trống không  
while( true )  
  { //có thể thêm mã xử lý ở đây . . . 
  } 
//main

0 comments:

Post a Comment

domain, domain name, premium domain name for sales

Popular Posts