Tải bản đầy đủ (.pdf) (80 trang)

GIÁO TRÌNH ARM STM32F103XX cơ bản (1)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (33.2 MB, 80 trang )

1

GIÁO TRÌNH ARM STM32F103 CƠ BẢN.
I. Giới thiệu:
a. Hình ảnh các dạng đóng gói .

H1: Kiểu đóng gói 64 pin

Biên soan: Cao Bá Vinh – email:


2

H2: kiểu đóng gói 100pin

Biên soan: Cao Bá Vinh – email:


3

H3: kiểu đóng gói 144pin

b. Cấu trúc của chip STM32F103xx:
i. Đây là cấu trúc 32bit .
ii. Được chế tạo bởi cơng ty STMicroelectronics.
iii. Tốc độ max 72Mhz.
iv. Tốc độ tính toán tất cả phép cộng trừ nhân chia số nguyên chỉ có 1 chu kỳ
máy.
v. Ngoại vi của STM32F103XX rất nhiều như:
ADC,DAC,TIMER,PWM,QEI,UART,SPI,I2C,USB,CAN,SDIO…
vi. Nguồn nuôi hoạt động từ 2v-3.6v.


Biên soan: Cao Bá Vinh – email:


4

vii. Bộ nhớ FLASH rất lớn từ 64k-1Mbyte.
viii. Nạp xóa bộ nhớ flash được 10.000 lần.
ix. Được hỗ trợ rất nhiều trình biên dịch như KEILC,IAR,MICROC…

II. Mơi trường làm việc trên trình biên dich KEILC cho arm.
a. Hướng dẫn tạo project trên KEILC.
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.
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:
Library
+ CMSIS
+ CM3
+ CoreSupport
//thư mục chứa hàm hỗ trợ nhân Cortex-M3
+ DeviceSupport
+ ST

+ STM32F10X
//System startup code
+ startup
//Start up code
+ Documentation
//tài liệu hỗ trợ
+ STM32F10x_StdPeriph_Driver //thư mục chứa hàm hỗ trợ thiết bị ngoại vi
+ inc
//thư mục chứa header file
+ src
//thư mục chứa mã nguồn
* 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.
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ự
Biên soan: Cao Bá Vinh – email:


5

án mới này là 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

Hình 1: 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.


Biên soan: Cao Bá Vinh – email:


6

Hình 2: 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

Biên soan: Cao Bá Vinh – email:


7

Chú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
“\Libraries\STM32F10x_StdPeriph_Driver\src”.
+ Nhóm “Start up”: thêm file startup_stm32f10x_hd.s ở thư mục
“Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm”.
+ Nhóm “User”: chứa file của người dùng, giả sử thêm file main.c của ta vào đây.

* Lưu ý: Đối với nhóm StdPeriph_Driver, nên căn cứ vào nhu cầu điều khiển ngoạ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

Biên soan: Cao Bá Vinh – email:


8

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
+ \Libraries\CMSIS\CM3\CoreSupport
+ \Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x
+ \Libraries\STM32F10x_StdPeriph_Driver\inc
* Lưu ý : Người dùng có thể thêm vào các đường dẫn thư mục khác của dự án.

3. Cấu hình project
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.
Biên soan: Cao Bá Vinh – email:


9

+ Để 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”

+ Để 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

Biên soan: Cao Bá Vinh – email:


10

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.

* Lưu ý: Nếu sử dụng bộ thư viện chuẩn cho thiết bị ngoại vi, nên khai báo
macro: USE_STDPERIPH_DRIVER.

4. Trình diễn
+ Nếu có sẵn board thí nghiệm, chúng ta có thể nạp trực tiếp file .hex sau khi biên dịch xuống
chíp thơng qua Flash Downloader của ST bằng cổng COM.
+ Nếu khơng có board, chúng ta có thể xem bằng cách dùng Debug Simulator của Keil

Biên soan: Cao Bá Vinh – email:


11

+ 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.

Biên soan: Cao Bá Vinh – email:


12

Hướng dẫn sử dụng Flash Loader Demonstrator
Bài viết này dựa trên kít thí nghiệm, Flash Loader Demonstrator (gọi tắt FLD) là chương trình
hỗ trợ nạp mã thực thi vào chip ARM Cortex-M3 thơng qua UART1. Có thể download FLD
trực tiếp từ trang web hỗ trợ của hãng ST ở đây.
Trước khi nạp chương trình vào chip thơng qua UART1, chúng ta phải thiết lập chip ở chế độ
boot từ System Memory của chip.

Thiết lập chế độ boot từ System Memory của chip.
Để nạp mã thực thi bằng FLD chúng ta cần trải qua 5 bước chính
+ Bước 1: Dùng cable serial nối từ máy tính tới board thơng qua cổng UART1.
Nhấn nút boot xuống(đèn trên kít tắt) sau đó nhấn nút reset.

Biên soan: Cao Bá Vinh – email:


13

Hình 1: Thiết lập kết nối
Bấm “Next” để FLD giao tiếp với chip.
* Lưu ý: Theo kinh nghiệm, ta nên chọn tốc độ UART ở 57600bps, và Parity là Even.
+ Bước 2: Nếu kết nối với chip thành công, FLD đọc cấu hình flash chip


Biên soan: Cao Bá Vinh – email:


14

Hình 2: Thơng tin Flash sau khi kết nối với chip thành công
+ Bước 3: Thông tin thiết bị

Biên soan: Cao Bá Vinh – email:


15

Hình 3: Thơng tin chip
Ở một số phiên bản FLD khác, thơng tin hiển thị có thể hơi khác như sau

Biên soan: Cao Bá Vinh – email:


16

Hình 4: Giao diện thơng tin của flash ở phiên bản Flash Loader Demonstrator v1.2
+ Bước 4: lựa chọn thao tác điều khiển chip
FLD hỗ trợ nhiều thao tác trên chip như
- Xóa dữ liệu từng phần hay hồn tồn trên flash.
- Nạp mã chương trình thực thi xuống flash.
- Lấy mã nguồn từ chip lên.
- Điều khiển các tính năng bảo vệ flash.
- Thay đổi giá trị từng byte trên flash.

Biên soan: Cao Bá Vinh – email:


17

Ở bài này tôi chỉ đề cập đến nạp chương trình thực thi xuống flash, các phần khác các bạn có thể
tham khảo cách dùng FLD tại đây.

Hình 5: Nạp chương trình xuống flash
* Lưu ý: chọn “Global Erase” để chắc rằng dữ liệu cũ sẽ bị xóa, flash sẵn sàng cho dữ liệu mới.
Chọn “Verify after download” để kiểm tra dữ liệu sau khi nạp có đúng hay khơng.
+ Bước 5: Sau khi đã chọn file xong, bấm Next FLD sẽ tự động thực thi nhiệm vụ.

Biên soan: Cao Bá Vinh – email:


18

Hình 6: Hồn tất nạp chương trình
Màn hình báo kết quả nạp đã hồn tất.
Để chạy đoạn chương trình vừa nạp vào flash của chip, chỉ cần nhấn nút boot lại(đèn led sáng
lên) và nhấn nút reset lại 1 lần nữa.

Biên soan: Cao Bá Vinh – email:


19

II:Lý thuyết ngôn ngữ C cho Vi điều Khiển.
1.


Tập lệnh và cấu trúc C:

1.1 KHAI BÁO BIẾN:

Chuẩn C

Chuẩn

Chuẩn stm32 Size
(Bits)

Range

bit

bit

1

0,1

int8_t

char

8

-128 to 127


uint8_t

u8

8

0 to 255

int8_t

s8

8

-128 to 127

int16_t

s16

16

-32768 to 32767

uint16_t

u16

16


0 to 65535

unsigned int

uint32_t

u32

32

0 to 4294967295

signed int

int32_t

s32

32

-2147483648 to 2147483647

uint64_t

u64

64

0 to 264


int64_t

s64

64

-232 to 232

float

float

float

32

±1.175e-38 to ±3.402e38

double

double

double

64

±1.175e-38 to ±3.402e38

keilC
bit

signed

char

unsigned
signed

char
char

signed short

int

unsigned short

unsigned
signed

int

__int64
__int64

Ta có rất nhiều kiểu khai báo biến , tùy ứng dụng mà ta sử dụng cho phù hợp để vừa tiết kiệm bộ
nhớ và tăng tốc độ sử lý.
Từ khóa unsigned là khơng dấu.
Biên soan: Cao Bá Vinh – email:



20

1.2 ĐỊNH NGHĨA :

Định nghĩa có chức năng thay thế cái gì đó để tiện cho ta thay đổi các ứng dụng 1 cách
nhanh chóng.
Từ khóa “#define” dùng để định nghĩa và cuối dịng khơng có dấu “;”.
Vd:

1.3 .

#define

led1_on

GPIOA->ODR|=1<<0

#define

data_led

#define

motor_left

TIM2->CCR1

#define

motor_right


TIM2->CCR2

#define

un

unsigned

#define

high(x)

(((x) & 0xFF00) >> 8)

#define

low(x)

((unsigned char)(x))

GPIOC->ODR

Thay Thế Kiểu :
Để thay thế kiểu ta có thể dung từ khóa “typedef”

Cấu trúc : typedef

kiểu dữ liệu đặt tên;


Vd:

typedef

int

so_nguyen;

typedef

char

byte;

typedef

double

so_thuc;

typedef signed
typedef signed short

char int8_t;
int int16_t;

typedef

signed


int int32_t;

typedef

int32_t

s32;

Biên soan: Cao Bá Vinh – email:


21

typedef

int16_t

s16;

typedef

int8_t

s8;

Sau khi chúng ta đặt tên thì chúng ta có thể sử dụng tên mới này mà đặt tên cho khai báo biến.

Vd:

so_nguyen


I,j,k,l;// lúc này thì các biến I,j,k,l là kiểu số nguyên 16bit.

1.4 .LỆNH IF .. ELSE IF…

Lệnh if … else if là lệnh kiểm tra điều kiện .
if <điều kiện1>
{ Đúng điều kiện 1 thì làm.}
else
{Điều kiện 1 sai thì làm.}
……………………………….
Chú ý nếu thực hiện 1 dịng lệnh thì khơng cần dấu {}.
vd1:
int i=10;
if (i>10) i=i+1;
else i=i-1;

Vd2: int i=5,j;
if (i==7) j=0;
else if(i==10) j=j+2;
else if(i==5) j=i+1;
Biên soan: Cao Bá Vinh – email:


22

else j=j+100;

1.5 .LỆNH WHILE(điều kiện).
Lệnh while là lệnh kiểm tra điều kiện trước rồi mới thực thi khối lệnh .

Nếu điều kiện cịn đúng thì khối lệnh vẫn cịn thực hiện .
Vd: while(1); có nghĩa là đứng yên tại chỗ.

While (1) {led=!led; delay_ms(100);}// chớp tắt led sau mỗi 100ms.

Vd: char i=0;
while(i<250) {i++;delay_ms(100);led=i;}
Cách viết khác.
Vd: char i=0;
while(i++<250) {delay_ms(100);led=i;}// kt đk trước rồi tăng i sau.

Vd: char i=0;
while(++i<250) {delay_ms(100);led=i;}// tăng i sau đó kt đk sau.

1.6 .LỆNH do…while(điều kiện).
Lệnh do…while là lệnh thực hiện khối lệnh trước rồi mới kiểm tra điều kiện sau .
Nếu điều kiện cịn đúng thì khối lệnh vẫn còn thực hiện .

Vd: int char i=0;
Biên soan: Cao Bá Vinh – email:


23

do
{ ++i; delay_ms(100);
}
while(i<200);

Vd: int char i=0;

do
{ delay_ms(100); led=~led;
}
while(++i<200);

1.7. CÊu tróc rẽ nhánh - toán tử switch:
Là cấu trúc tạo nhiều nhánh đặc biệt. Nó căn cứ vào giá trị một biểu thức nguyên
để để chọn một trong nhiều cách nhảy.
Cấu trúc tổng quát của nó là :
switch ( biểu thức nguyªn )
{
case n1
khèi lƯnh 1
case n2
khèi lƯnh 2
.......
Biên soan: Cao Bá Vinh – email:


24

case nk
khối lệnh k
[ default
khối lệnh k+1

]

}
Với ni là các số nguyên, hằng ký tự hoặc biểu thức hằng. Các ni cần có giá trị

khác nhau. Đoạn chơng trình nằm giữa các dấu { } gọi là thân của toán tử switch.
default là một thành phần không bắt buộc phải có trong thân của switch.
Sự hoạt động của toán tử switch phụ thuộc vào giá trị của biểu thức viết trong
dấu ngoặc ( ) nh sau :
Khi giá trị của biểu thức này bằng ni, máy sẽ nhảy tới các câu lệnh có nhÃn là
case ni.
Khi giá trị biểu thức khác tất cả các ni thì cách làm việc của máy lại phụ thuộc
vào sự có mặt hay không của lệnh default nh sau :
Khi có default máy sẽ nhảy tới câu lệnh sau nhÃn default.
Khi không có default máy sẽ nhảy ra khỏi cấu trúc switch.

Chú ý :
Máy sẽ nhảy ra khỏi toán tử switch khi nó gặp câu lệnh break hoặc dấu ngoặc
nhọn đóng cuối cùng của thân switch. Ta cịng cã thĨ dïng c©u lƯnh goto trong thân
của toán tử switch để nhảy tới một câu lệnh bất kỳ bên ngoài switch.

Biờn soan: Cao Bỏ Vinh email:


25

Khi toán tử switch nằm trong thân một hàm nào đó thì ta có thể sử dụng câu lệnh
return trong thân của switch để ra khỏi hàm này ( lệnh return sẽ đề cập sau ).
Khi máy nhảy tới một câu lệnh nào đó thì sự hoạt động tiếp theo của nó sẽ phụ
thuộc vào các câu lệnh đứng sau câu lệnh này. Nh vậy nếu máy nhảy tới câu lƯnh cã
nh·n case ni th× nã cã thĨ thùc hiƯn tất cả các câu lệnh sau đó cho tới khi nào gặp câu
lệnh break, goto hoặc return. Nói cách khác, máy có thể đi từ nhóm lệnh thuộc case ni
sang nhóm lệnh thuộc case thứ ni+1. Nếu mỗi nhóm lệnh đợc kết thúc bằng break thì
toán tử switch sẽ thực hiện chỉ một trong các nhóm lệnh này.
Ví dụ :

Lập chơng trình phân loại học sinh theo điểm sử dụng cÊu tróc switch :
#include “stdio.h”
main()
{
int diem;
tt: printf(“\nVao du lieu :”);
printf(“\n Diem =“);
scanf(“%d”,&diem);
switch (diem)
{
case 0:
case 1:
case 2:
Biên soan: Cao Bá Vinh – email:


×