(NB) Tiếp nội dung phần 1 Giáo trình Hệ thống nhúng: Phần 2 cung cấp những kiến thức còn lại được trình bày như sau: Giới thiệu ARM STM32, giới thiệu KIT, tạo dự án với KEIL ARM, các bước nạp chương trình, lập trình nhúng trên ARM. Mời các bạn cùng tham khảo
Trang 1CHƯƠNG 4 LẬP TRÌNH NHÚNG TRÊN ARM 4.1 GIỚI THIỆU ARM STM32
Lập trình nhúng hiện nay không xa lại gì với chúng ta, STM32 là chip của
ST, dựa trên nền lõi ARM Cortex-M Dòng ARM Cortex™-M là thế hệ mới, thiết lập các tiêu chuẩn mới về hiệu suất, chi phí, ứng dụng cho các thiết bị cần tiêu thụ năng lượng thấp, và đáp ứng yêu cầu thời gian thực khắc khe
Hình 4.1 Hiệu năng ARM Cortex™-M
Một số tính năng có sử dụng STM32 như: từ điện tử dân dụng (tivi, đầu máy, máy giặt…), xe hơi đời mới, game, mobile, laptop … chỗ nào ARM cũng có mặt
TÍNH NĂNG NỔI BẬT:
Hiệu suất cao
Trang 2Hình 4.3 So sánh tiêu thụ năng lượng giữa ARM và VĐK 16 bit hoặc 8 bit
Code cũng tương đối dễ vì được support gần như hết: ngoại vi (GPIO, I2C, SPI, ADC, USB, Ethernet, CAN….), ST cung cấp cho chúng ta các thư viện trực
Microcontroller Software Interface Standard ), nhiệm vụ của chúng ta không thể
dễ dàng hơn: khai báo và sử dụng mà thôi …
Giá rẻ: STM32F1x khoảng 29000 đồng STM32F1x chạy với tốc đọ 24Mhz
Hình 4.4 Comparing 16-bit multiply operations across processor architectures
Trang 34.2 GIỚI THIỆU KIT
Vi xử lý ARM Cortex-M3 là thế hệ mới nhất của dòng vi xử lý ARM cho hệ thống nhúng Nó được phát triển để cung cấp cho các hệ thống giá thành thấp và
nó gần giống với MCU, với việc cắt giàm chân và năng lượng thấp, trong khi vẫn đảm bảo khả năng tính toán và đáp ứng ngắt được năng cao hơn ARM Cotext M3
dự trên kiến trúc vi xử lý RISC nhưng tối ưu hiệu quả mã lệnh, nhưng năng lực được đảm bảo từ nhân ARM trong kích thước bộ nhớ thường kết hợp với 8 hoặc
16 bit
Dòng STM32F103 có nhân ARM vì vậy tương thích với tất cả công cụ và phần mền dành cho ARM Nó là sự kết hợp hiệu năng cao từ ARM Cortex-M3 CPU với nhiều thiết bị ngoại vi cũng như nâng cao tính năng I/O STM32-103 Dev 1.0 cho phép bạn khám phá hoàn toàn nhưng tính năng mới của vi điều khiển ARM Cortex M3 STM32F103RDT6 được phát triển từ ST Microelectronics Inc Một vài ứng dụng như: USB Mass Storage device, Audio class device, HID mouse device, CDC Virtual com port device …
Hình 4.5 Kit STM32F103RDT6
4.2.1 Đặc tính của kit
1 MCU: STM32F103RDT6 ARM 32 bit CORTEX M3™ with 384K
2 Program Flash, 64K Bytes RAM, USB, CAN, x2 I2C, x16 ADC, x2
Trang 411 status LED
12 8 Mhz crystal oscillator
13 32768 Hz crystal and RTC backup battery
14 extension headers for all uC ports
15 Kích thước: 90.67 x 73.54mm (3.56 x 2.89")
Yêu cầu từ board phát triển :
Cáp USB 1.8m để nới với PC ( dành cho việc cấp nguồn hoặc giao tiếp
USB trong trường hợp dùng đến tính năng USB )
Phần cứng : ARM-JTAG, ARM-USB-OCD, ARM-USB-TINY or other
ARM JTAG compatible tool
Phần mềm :
+ free open source platform: GNU C compiler + OpenOCD and Eclipse
(support all low cost Olimex JTAG debuggers)
+ commercial solution EW-ARM from IAR Systems AB, require
expensive J-LINK debugger
+ CrossWorks from Rowley (supports all Olimex low cost JTAG debuggers)
- GPIO up to 51 (multiplexed with peripherials)
- 16 kênh ADC 12-bit, DAC x2
SPI:
STM32F103RDT6 have 2 SPIs which able to communicate up to 18 Mbits/s
Trang 53-bit prescaler gives 8 master mode frequencies and the frame is configurable from 8-bit to 16-bit The hardware CRC generation/verification supports basic SD Card/MMC modes Both SPIs can be served by the DMA controller
I2C:
STM32F103RDT6 have two I²C bus interfaces which can operate in master and slave modes They can supportstandard and fast modes They support dual slave addressing (7-bit only) and both 7/10-bit addressing in master mode A hardware CRC generation/verification is embedded They can be served by DMA and they support SM Bus 2.0/PM Bus
multi-CAN:
The STM32F103RDT6 CAN is compliant with specifications 2.0A and B (active) with a bit rate up to 1 Mbit/s It can receive and transmit standard frames with 11-bit identifiers as well as extended frames with 29-bit identifiers It has three transmit mailboxes, two receive FIFOs with 3 stages and 14 scalable filter banks.The CAN and USB share same pins PA11 and PA12, so you can’t use both CAN and USB on same time
USB:
The STM32F103RDT6 embeds a USB device peripheral compatible with the USB Fullspeed 12 Mbs The USB interface implements a full speed (12 Mbit/s) function interface It has software configurable endpoint setting and suspend/resume support The dedicated 48 MHz clock source is generated from the internal main PLL.The CAN and USB share same pins PA11 and PA12, so you can’t use both CAN and USB on same time
ADC:
STM32F103RDT6 have two 12-bit Analog to Digital Converters which share
up to 16 external channels, performing conversions in singleshot or scan modes
In scan mode, automatic conversion is performed on a selected group of analog inputs Additional logic functions embedded in the ADC interface allow:
- Simultaneous sample and hold
- Interleaved sample and hold
- Single shunt
The ADC can be served by the DMA controller.An analog watchdog feature allows very precise monitoring of the converted voltage of one, some or all selected channels An interrupt is generated when the converted voltage is outside the programmed thresholds The events generated by the standard timers (TIMx) and the Advanced Control timer (TIM1) can be internally connected to the ADC start trigger, injection trigger, and DMA trigger respectively, to allow the application to synchronize A/D conversion and timers
Trang 84.2.4 Hướng dẫn set jump cho board
Nguồn cung cấp cho mạch
Trang 9Cấp nguồn ngoài ( DC 5V )
Cấp nguồn từ USB
Trang 11Nút Reset
Nút WKUP Nút thoát khỏi trạng thái ngủ của STM32
Giao tiếp trực tiếp RS232 của ARM QUA USART1
Trang 12Thẻ nhớ SD giao tiếp trực tiếp SPI của ARM
Header nạp và gỡ lỗi chương trình qua JTAG
Hướng dẫn cấu hình DIP SW1 để nạp chương trình qua
cổng USART1 với FLASH LOADER DEMOSTRATOR
trên board OPENCMX-STM3210D
Nạp qua bootloader
Chạy chương trình trong ARM
Trang 134.3 TẠO DỰ ÁN VỚI KEIL ARM
Giới thiệu cách tạo mới dự án cho vi xử lý ARM Cortex-M3 STM32F103RC bằng Keil ARM Cùng với đó là cách tích hợp bộ thư viện chuẩn CMSIS của ST dành cho dòng ARM này
4.3.1 Bộ thư viện CMSIS
ST cung cấp cho người dùng bộ thư viện chuẩn lập trình giao tiếp với thiết
bị ngoại vi tương thích với chuẩn CMSIS Thông qua bộ thư viện này, lập trình viên dễ dàng giao tiếp với các thiết bị phần cứng chuẩn của các dòng Cortex-M3 của ST
Thư viện được chia làm 2 phần:
+ phần hỗ trợ nhân Cortex-M3: bao gồm mã giao tiếp với nhân CPU, và đoạn
mã start up code
+ phần hỗ trợ các thiết bị ngoại vi: chứa toàn bộ các hàm thư viện điều khiển thiết bị ngoại vi của ST
Cấu trúc thư viện CMSIS như sau:
* Lưu ý: Các hàm được viết và đặt tên theo chuẩn CMSIS, lập trình viên cần tuân theo các quy tắc của CMSIS khi sử dụng hàm, tránh viết lại các hàm truy cập thẳng vào phần cứng khi không cần thiết
4.3.2 Khởi tạo dự án mới
+ Mở Keil IDE, chọn menu “Project->New uVision Project” để tạo dự án mới Giả dụ đặt tên dự án mới này là 24h_Led
* Lưu ý: Thường khi tạo project mới hệ thống file quản lý dự án của Keil hay
bố trí ở thư mục dự án, điều này dễ bị lẫn lộn với các file nguồn, ta nên tạo một thư mục con để quản lý các file dự án này
Chọn chip STM32F103RC cho board
Trang 14Hình 4.6 Khởi tạo dự án + Sau khi dự án mới được tạo, ta nên tổ chức lại hệ thống mã nguồn để dễ dàng theo dõi
Hình 4.7 Tổ chức thư mục mã nguồn Như hình 2 ở trên ta tạo 4 nhóm file, các nhóm “CMSIS”,
“StdPeriph_Driver” và “Start up” sẽ là các files từ thư viện CMSIS của ST
* Lưu ý: Khi tạo mới dự án, Keil sẽ hỏi người dùng có sử dụng "start up
code" sẵn có không Chúng ta không sử dụng "start up code" này của Keil mà sẽ
dùng của ST có trong bộ thư viện chuẩn
+ Tích hợp thư viện CMSIS vào chương trình
Trang 15Chúng ta sẽ lần lượt tích hợp các thư mục trong thư viện vào dự án như sau:
+ Nhóm “CMSIS”: thêm file core_cm3.c ở thư mục
“\Libraries\CMSIS\CM3\CoreSupport” và system_stm32f10x.c ở thư mục
“\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x”
+ Nhóm “StdPeriph_Driver”: thêm các file liên quan đến điều khiển ngoạI
vi, ở dự án này chúng ta cần điều khiển cổng GPIO, UART nên cần thêm các
file: stm32f10x_gpio.c, stm32f10x_usart.c và stm32f10x_rcc.c ở thư mục
Trang 16ngoại vi để thêm vào các file tương ứng, tránh thêm các file dư thừa vì làm tăng thời gian biên dịch và tốn tài nguyên hệ thống
+ Khai báo thư mục thư viện cho dự án Sau khi thêm các file cần thiết cho
dự án, chúng ta chưa thể biên dịch thành công được vì còn thiếu đường dẫn tới các file khai báo thư viện CMSIS
Mở khung điều khiển cấu hình dự án
Chọn tab “C/C++”
Thêm các đường dẫn thư mục sau vào dự án:
+ \Libraries: thư mục chứa Libraries CMSIS
Sau khi đã thêm các file cần thiết cho dự án, chúng ta phải thiết lập các thông
số cơ bản để Keil có thể biên dịch ra file thực thi
+ Để nạp chương trình xuống board , chúng ta cần cấu hình Keil biên dịch ra file hex (hoặc bin)
Mở khung cấu hình dự án, chọn tab “Output”, check và ô “Create HEX File”
Trang 17+ Để tiện sắp xếp tài nguyên của dự án, ta nên xếp các file tạm được sinh ra bởI Keil vào các thư mục riêng
Tương ứng với các file object (tab Output) và linker (tab Listing) ta lưu trong thư mục “Obj” và “Lst” cho tiện theo dõi sau này
+ Cần lưu ý là với bộ thư viện CMSIS, chúng ta sử dụng khá nhiều kỹ thuật
“macro” trong lập trình Có một số “macro” cần khai báo “define” sẵn trong dự án
để có thể biên dịch thành công
Trang 18+ Chạy Debug chương trình, mở cửa sổ theo dõi các thiết bị ngoại vi ở menu
“Peripherals” chọn ngoại vi tương ứng, giả sử đó là Port C của GPIO
Bấm F10 (hoặc F11) để chạy debug từng dòng lệnh đồng thời theo dõi giá trị của Port C thay đổi
Trang 19Chú ý làm các bước như sau :
1 Rút nguồn cấp ra khỏi boad chờ sau 5s rùi cấp nguồn lại
2 Kiểm tra lại cáp COM
3 Kiếm tra lại DIP SW1 thiết lập STM32 ở bootloader đã đúng chưa?
Nếu như bạn đã làm như các bước trên mà vẫn hiện ra thông báo đó thì có thể STM32 của bạn không vào được bootloarder hoặc chíp ARM của bạn đã fuse
“WRITE PROTECT : ENABLE
B2 : Nếu chương trình nhận ra bootloader từ ARM, lúc đó chương hiện ra thông báo như sau:
Bạn bấm vào button “Next”
Hoặc gặp thông báo cảnh báo Remove protection, khi đó bạn bấm vào button
“Remove protection” Chờ cho chương trình xóa xong, bạn Nhấn “Close “ bạn
chạy lại chương trình và làm lại như Bước 1
B3 : Khi bạn gặp thông báo
Trang 20Bạn bấm “Next”
B4 : Bạn thiết lập thông số như trong hình dưới
Bạn chọn file nạp bằng cách bấm vào nút “…” Khi đó bạn trỏ tới file hex mà
bạn muốn nạp cho STM32 Xong bạn bấm button “Open” Khi đó chương trình
sẽ ra trở lại màn hình như sau Nếu bạn muốn chương trình kiểm tra lại nội
dung file nạp có đúng với nội dung của STM32 hay không bạn click chọn “Verify
after download”
B4: Bạn tiếp tục bấm “Next”
Khi nạp xong chương trình thông báo:
Trang 21Bạn chọn “Close” để đóng chương trình
B5: Thiết lập lại DIP SW1 để chạy chương trình trong ARM
4.5 LẬP TRÌNH NHÚNG TRÊN ARM
4.5.1 Điều khiển LED đơn
Trước khi bắt đầu chúng ta cần mở file stm32f10x.h lên và xem phần sau:
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices
/* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
Trang 22devices, you can define the device in your toolchain compiler preprocessor
- Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes
- Low-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes
- Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes
- Medium-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes
- High-density devices are STM32F101xx and STM32F103xx microcontrollers where the Flash memory density ranges between 256 and 512 Kbytes
- High-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 256 and 512 Kbytes
- XL-density devices are STM32F101xx and STM32F103xx microcontrollers where the Flash memory density ranges between 512 and 1024 Kbytes
- Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers */
Phần trước là hướng dẫn chọn define, file startup cho chương trình Tùy theo chip tương ứng mà chúng ta cần khai báo cho đúng
Muốn biết chip đang dùng thuộc loại nào thì khi khởi tạo project, lúc chọn chip có
Trang 23Chip STM32F103RC, có 256kB Flash là chip High-density nên chọn define là STM32F10X_HD
Bây giờ chúng ta tiếp tục với phần GPIO
MCU STM32F10x có nhiều loại với số lượng IO khác nhau Mỗi port IO được cấu hình bởi 2 thanh ghi 32bit (GPIOx_CRL&GPIOx_CRH)
- GPIOx_CRL : cấu hình các pin từ 0→7
- GPIO_CRH : cấu hình các pin từ 8→15
- Alternate function push-pull
- Alternate function open-drain
Các bit mode[1:0] cấu hình chế độ input hoặc output Mode info
00 input ( mặc định khi reset)
Trang 2401 output open drain
10 alternate output push/pull
11 alternate output open drain
Chú ý : chế độ input pullup/pulldown sẽ do giá trị bit tương ứng trên thanh ghi ODR quyết định Nếu sử dụng hàm chuẩn trong thư viện của ST thì có thể các bạn không cần biết cũng làm được Nhưng theo mình thì nên biết xem hàm mình dùng
nó tác động vào thanh ghi nào để lúc cần thì có thể gán trực tiếp cho nhanh Các pin IO đều có dạng 5V tolerant (ngoài 2 pin chung chức năng với thạch anh đồng
hồ thời gian thực) tức là có thể nối với các thiết bị dùng chuẩn 5V Mình thường nối thêm con trở nhỏ nối tiếp với chân IO nếu nó là chế độ input (để phần điện áp
Sơ đồ các pin các bạn có thể tham khảo trong datasheet.Các thanh ghi quan trọng
Input data register GPIOx_IDR
Output data register GPIOx_ODR
Bit Set/Reset register GPIOx_BSRR
Bit Reset register GPIOx_BRR
Lock mechanism register GPIOx_LCKR
Ngoài ra còn có thanh ghi remap các chân vào ra của ngoại vi Các bạn xem trong datasheet để hiểu rõ hơn
Trong thư viện “stm32f10x_gpio.h” các pin tương ứng đã được định nghĩa sẵn để người dùng dễ sử dụng : GPIO_Pin_x
Các port được định nghĩa bằng tên GPIOx trong đó x: A,B,C,…G Thực chất GPIOx có dạng con trỏ trỏ tới địa gốc của port tương ứng
Lệnh dùng khi Set Bit x của port y : GPIOx→BSRR = GPIO_Pin_y
Lệnh dùng khi Reset bit x của Port y : GPIOx→BRR =GPIO_Pin_y
Hoặc dùng lệnh :GPIOx→BSRR = GPIO_Pin_y <<16
Thư viện chuẩn của ST, để bật tắt các bit, ta sử dụng hàm GPIO_SetBit() và
Trang 25Bắt đầu chường trình cho GPIO :
#include "stm32f10x.h"
Khai báo thư viện stm32f10x.h
void delay_ms(uint32_t num);
void delay_ms(uint32_t num)
Việc nạp code cho STM32 có nhiều cách:
- JTAG: nạp và gỡ rối, việc dùng JTAG được thực hiện trên KeilC nên rất thuận tiện cho việc nạp code, debug , test sản phẩm, nhược điểm là phần cứng rườm rà
- SWD : chuẩn giao tiếp 2 dây, nhỏ gọn đơn giản và chi phí thấp hơn so với JTAG
- Bootloader : phần cứng đơn giản, dễ thực hiện,… nhưng chỉ dùng cho việc nạp code