Giáo trình Lập trình nhúng

Sức đẩy của công nghệ đưa công nghệ vi điện tử, công nghệ vi cơ điện, công nghệ sinh học hội tụ tạo nên các chip của công nghệ nano, là nền tảng cho những thay đổi cơ bản trong lĩnh vực công nghệ cao “3C, sức kéo của thị trường đòi hỏi các thiết bị phải có nhiều chức năng thân thiện với người dùng, có mức độ thông minh ngày càng cải thiện đưa đến vai trò và tầm quan trọng của các hệ thống nhúng ngày càng cao trong nền kinh tế quốc dân.

Phát triển các hệ nhúng và phần mềm nhúng là quốc sách của nhiều quốc gia trên thế giới, nhất là giai đoạn hậu PC hiện nay. Ở nước ta đáng tiếc lĩnh vực này lâu nay đã bị lãng quên, do vậy cần có những điều chỉnh phù hợp trong chiến lược phát triển để có thể theo kịp, rút ngắn khoảng cách tụt hậu đối với các nước trong khu vực và trên thế giới trong quá trình hội nhập nền kinh tế toàn cầu không thể tránh khỏi hiện nay.

pdf 113 trang thom 08/01/2024 2940
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình nhúng", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Giáo trình Lập trình nhúng

Giáo trình Lập trình nhúng
TRƯỜNG ĐẠI HỌC VĂN HIẾN TPHCM 
KHOA KỸ THUẬT – CÔNG NGHỆ 
BỘ MÔN ĐIỆN TỬ - VIỄN THÔNG 
   
LẬP TRÌNH NHÚNG 
TÀI LIỆU LƯU HÀNH NỘI 
MỤC LỤC 
Chương 1 Tổng quan.1 
 1.1 Mở đầu...1 
 1.2 Khái niệm về hệ nhúng.......1 
 1.3 Vai trò của hệ thống nhúng trong sự phát triển của lĩnh vực công nghệ cao..3 
 1.4 Đặc tính, phương pháp thiết kế và xu thế phát triển của các hệ nhúng.....4 
 1.5 Môi trường thông minh.6 
 1.6 Các hệ điều hành nhúng và phần mềm nhúng..6 
 1.6.1 Hệ điều hành nhúng...6 
 1.6.2 Phần mềm nhúng...7 
Chương 2 Lý thuyết thiết kế hệ thống nhúng.8 
 2.1 Quy trình thiết kế Top-Down8 
 2.1.1 Pha phân tích......8 
 2.1.2 Pha thiết kế nguyên lý..10 
 2.1.3 Pha thiết kế kỹ thuật.....11 
 2.1.4 Pha xây dựng hệ thống.....11 
 2.1.5 Pha kiểm tra.....12 
 2.2 Quy trình thiết kế Bottom-Up.12 
 2.3 Đặc tả hệ thống....14 
 2.3.1 Khái niệm đặc tả (specification)......14 
 2.3.2 Tại sao cần đặc tả......14 
 2.3.3 Phân loại các kỹ thuật đặc tả..15 
 2.3.4 Ứng dụng và ưu việt khỉ sử dụng đặc tả...15 
 2.3.5 Phương pháp đặc tả sử dụng “Máy trạng thái hữu hạn FSM”...16 
 2.4 Các phương pháp biểu diễn thuật toán..17 
 2.4.1 Ngôn ngữ tự nhiên....18 
 2.4.2 Dùng lưu đồ.18 
 2.4.3 Mã giả...21 
Chương 3 Cấu trúc phần cứng.23 
 3.1 Cấu trúc tổng quát của hệ thống nhúng..23 
 3.1.1 Kiến trúc cơ bản.....23 
 3.1.2 Cấu trúc phần cứng......23 
 3.2 Một số nền tảng phần cứng thông dụng....24 
 3.2.1 Vi điều khiển Atmega8....24 
 3.2.2 Kit Arduino Uno R3....29 
 3.2.3 Vi điều khiển MSP430G2553...33 
 3.2.4 Kit MSP430 Launchpad....36 
 3.2.5 Vi điều khiển PIC18F2550...38 
 3.2.6 Kit PIC18F2550 Pinguino.....40 
Chương 4 Phần mềm nhúng.....43 
 4.1 Đặc điểm phần mềm nhúng.43 
 4.2 Lập trình nhúng với ngôn ngữ Arduino..43 
 4.2.1 Cấu trúc....43 
 4.2.1.1 setup()..43 
 4.2.1.2 loop()....44 
 4.2.1.3 Cú pháp mở rộng..45 
 4.2.1.4 Toán tử số học..48 
 4.2.1.5 Toán tử so sánh....50 
 4.2.1.6 Toán tử logic....50 
 4.2.1.7 Toán tử hợp nhất......50 
 4.2.1.8 Cấu trúc điều khiển......51 
 4.2.2 Giá trị...59 
 4.2.2.1 Hằng số....59 
 4.2.2.2 Kiểu dữ liệu......65 
 4.2.2.3 Chuyển đổi kiểu dữ liệu...73 
 4.2.2.4 Phạm vi của biến và phân loại biến..74 
 4.2.2.5 Hàm hỗ trợ sizeoff().....78 
 4.2.3 Hàm và thủ tục.....79 
 4.2.3.1 Nhập xuất Digital...79 
 4.2.3.2 Nhập xuất Analog......81 
 4.2.3.3 Hàm thời gian....85 
 4.2.3.4 Hàm toán học.....88 
 4.2.3.5 Hàm lượng giác......93 
 4.2.3.6 Sinh số ngẫu nhiên.....93 
 4.2.3.7 Nhập xuất nâng cao....96 
 4.2.3.8 Bits và Bytes..99 
 4.2.3.9 Ngắt.....102
Chương I: Tổng quan 
Bài giảng lập trình nhúng 1 
Chương 1: TỔNG QUAN 
1.1 Mở đầu 
Trong sự phát triển mạnh mẽ của khoa học kĩ thuật với nền kinh tế trí thức và xu 
hướng hội nhập toàn cầu như hiện nay, thế giới và Việt Nam đang thực hiện việc kết hợp 
giữa các ngành thuộc lĩnh vực công nghệ cao trong một Khoa hoặc cơ sở đào tạo. Đó là 
lĩnh vực khoa học dưới 3 ngọn cờ: Máy tính, Điện tử- Viễn thông và Điều khiển tự động 
mà ta thường gọi là “3 C” (Computer – Communication - Control). Có thể nói, các quá 
trình sản xuất và quản lí hiện nay như: các hệ thống đo lường điều khiển tự động trong 
sản xuất công nghiệp; các hệ thống di động và không dây tiên tiến, các hệ thống thông tin 
vệ tinh, các hệ thống thông tin dựa trên Web, chính phủ điện tử, thương mại điện tử, các cơ 
sở dữ liệu của nhiều ngành kinh tế và của Quốc gia, các hệ thống thiết bị Y tế hiện đại, các 
thiết bị điện tử dân dụng, ... đều là sản phẩm của sự kết hợp giữa các lĩnh vực khoa học trên. 
Hiện nay chúng ta đang ở thời đại hậu PC sau giai đoạn phát triển của máy tính lớn 
(Mainframe) 1960-1980, và sự phát triển của PC-Internet giai đoạn 1980-2000. Giai 
đoạn hậu PC-Internet này được dự đoán từ năm 2000 đến 2020 là giai đoạn của môi 
trường thông minh mà hệ thống nhúng là cốt lõi và đang làm nên làn sóng đổi mới trong 
công nghệ thông tin nói riêng và lĩnh vực công nghệ cao “3C”, nói chung. Một thực tế 
khách quan là thị trường của các hệ thống nhúng lớn gấp khoảng 100 lần thị trường PC, 
trong khi đó chúng ta mới nhìn thấy bề nổi của công nghệ thông tin là PC và Internet còn 
phần chìm của công nghệ thông tin chiếm 99% số processor trên toàn cầu này nằm trong 
các hệ nhúng thì còn ít được biết đến. 
Sức đẩy của công nghệ đưa công nghệ vi điện tử, công nghệ vi cơ điện, công 
nghệ sinh học hội tụ tạo nên các chip của công nghệ nano, là nền tảng cho những thay đổi 
cơ bản trong lĩnh vực công nghệ cao “3C, sức kéo của thị trường đòi hỏi các thiết bị phải 
có nhiều chức năng thân thiện với người dùng, có mức độ thông minh ngày càng cải 
thiện đưa đến vai trò và tầm quan trọng của các hệ thống nhúng ngày càng cao trong nền 
kinh tế quốc dân. 
Phát triển các hệ nhúng và phần mềm nhúng là quốc sách của nhiều quốc gia trên 
thế giới, nhất là giai đoạn hậu PC hiện nay. Ở nước ta đáng tiếc lĩnh vực này lâu nay đã 
bị lãng quên, do vậy cần có những điều chỉnh phù hợp trong chiến lược phát triển để có 
thể theo kịp, rút ngắn khoảng cách tụt hậu đối với các nước trong khu vực và trên thế giới 
trong quá trình hội nhập nền kinh tế toàn cầu không thể tránh khỏi hiện nay. 
1.2 Khái niệm về hệ nhúng 
Hệ thống nhúng (tiếng Anh: Embedded system) là một thuật ngữ để chỉ một thống 
có khả năng tự trị được nhúng vào trong một môi trường hay một hệ thống mẹ. Hệ thống 
nhúng có vai trò đảm nhận một phần công việc cụ thể của hệ thống mẹ. Hệ thống nhúng 
có thể là một hệ thống phần cứng và cũng có thể là một hệ thống phần mềm. 
(Wikipedia, 2010) 
Chương I: Tổng quan 
Bài giảng lập trình nhúng 2 
Ví dụ quanh ta có rất nhiều sản phẩm nhúng như lò vi sóng, nồi cơm điện, điều 
hòa, điện thoại di động, ô tô, máy bay, tàu thủy, các đầu đo, cơ cấu chấp hành thông 
minh v.v... ta có thể thấy hiện nay hệ thống nhúng có mặt ở mọi lúc mọi nơi trong 
cuộc sống của chúng ta. 
Hình 1.1 Một số ví dụ về các thống nhúng thông dụng 
Các nhà thống kê trên thế giới đã thống kê được rằng số chip vi xử lý ở trong các 
máy PC và các server, các mạng LAN, WAN, Internet chỉ chiếm khoảng 1% tổng số chip 
vi xử lý có trên thế giới, 99% số vi xử lý còn lại nằm trong các hệ thống nhúng. 
Như vậy công nghệ thông tin không chỉ đơn thuần là PC, mạng LAN, WAN, 
Internet phần mềm quản lý ... như nhiều người thường nghĩ. Đó chỉ là bề nổi của một tảng 
băng chìm. Phần chìm của công nghệ thông tin chính là các ứng dụng của các hệ nhúng có 
mặt trong mọi ngành nghề của đời sống xã hội hiện nay. Các hệ nhúng được tích hợp trong 
các thiết bị đo lường điều khiển tạo nên đầu não và linh hồn của sản phẩm. Trong các 
hệ nhúng, hệ thống điều khiển nhúng đóng một vai trò hết sức quan trọng. 
Hệ điều khiển nhúng là hệ thống mà máy tính được nhúng vào vòng điều khiển của 
sản phẩm nhằm điều khiển một đối tượng, điều khiển một quá trình công nghệ đáp ứng các 
yêu cầu đặt ra. Hệ thống điều khiển nhúng lấy thông tin từ các cảm biến, xử lý tính toán các 
thuật điều khiển và phát tín hiệu điều khiển cho các cơ cấu chấp hành. 
Khác với các hệ thống điều khiển cổ điển theo nguyên lý thủy lực, khí nén, rơle, 
mạch tương tự, hệ điều khiển nhúng là hệ thống điều khiển số được hình thành từ 
những năm 1960 đến nay. Trước đây các hệ điều khiển số thường do các máy tính lớn đảm 
nhiệm, ngày nay chức năng điều khiển số này do các chíp vi xử lý, các hệ nhúng đã thay 
thế. Phần mềm điều khiển ngày càng tinh sảo tạo nên độ thông minh của thiết bị và ngày 
càng chiếm tỉ trọng lớn trong giá thành của thiết bị. 
Chương I: Tổng quan 
Bài giảng lập trình nhúng 3 
Điểm qua về chức năng xử lý tin ở PC và ở các thiết bị nhúng có những nét 
khác biệt. Đối với PC và mạng internet chức năng xử lý đang được phát triển mạnh ở các 
lĩnh vực quản lý và dịch vụ như thương mại điện tử, ngân hàng điện tử, chính phủ điện tử, 
thư viện điện tử, đào tạo từ xa, báo điện tử ... các ứng dụng này thường sử dụng máy 
PC để bàn, mạng WAN, LAN hoạt động trong thế giới ảo. Còn đối với các hệ nhúng thì 
chức năng xử lý tính toán được ứng dụng cụ thể cho các thiết bị vật lý (thế giới thật) 
như mobile phone, quần áo thông minh, các thiết bị điện tử cầm tay, thiết bị y tế, xe ô 
tô, tầu tốc hành, phương tiện vận tải thông minh, máy đo, đầu đo, cơ cấu chấp hành thông 
minh, các hệ thống điều khiển, nhà thông minh, thiết bị gia dụng thông minh v.v... 
1.3 Vai trò của hệ thống nhúng trong sự phát triển của lĩnh vực công nghệ cao 
“3C“. 
Các hệ thống tự động đã được chế tạo trên nhiều công nghệ khác nhau như các thiết 
bị máy móc tự động bằng các cam chốt cơ khí, các hệ thống tự động hoạt động bằng 
nguyên lý khí nén, thủy lực, rơle cơ điện, mạch điện tử số ... các thiết bị, hệ thống này 
có chức năng xử lý và mức độ tự động thấp so với các hệ thống tự động hiện đại được 
xây dựng trên nền tảng của các hệ thống nhúng. 
Trong khi các hệ thống tin học sử dụng máy tính để hỗ trợ và tự động hóa quá 
trình quản lý, thì các hệ thống điều khiển tự động dùng máy tính để điều khiển và tự động 
hóa quá trình công nghệ. Chính vì vậy các thành tựu của công nghệ phần cứng và công nghệ 
phần mềm của máy tính điện tử được áp dụng và phát triển một cách có chọn lọc và hiệu 
quả cho các hệ thống điều khiển tự động. Và sự phát triển như vũ bão của công nghệ thông 
tin kéo theo sự phát triển không ngừng của lĩnh vực tự động hóa. 
Ta có thể thấy quá trình các hệ nhúng thâm nhập vào từng phần tử, thiết bị 
thuộc lĩnh vực tự động hóa như đầu đo, cơ cấu chấp hành, thiết bị giao diện với người vận 
hành thậm chí vào các rơle, contactor, nút bấm mà trước kia hoàn toàn làm bằng cơ khí. 
Trước khi đầu đo gồm phần tử biến đổi từ tham số đo sang tín hiệu điện, mạch 
khuyếch đại, mạch lọc và mạch biến đổi sang chuẩn 4-20mA để truyền tín hiệu đo về trung 
tâm xử lý. Hiện nay đầu đo đã tích hợp cả chip vi xử lý, biến đổi ADC, bộ truyền dữ liệu số 
với phần mềm đo đạc, lọc số, tính toán và truyền kết quả trên mạng số về thẳng máy tính 
trung tâm. Như vậy đầu đo đã được số hóa và ngày càng thông minh do các chức năng 
xử lý từ máy tính trung tâm trước kia nay đã được chuyển xuống xử lý tại chỗ bằng chương 
trình nhúng trong đầu đo. 
Tương tự như vậy cơ cấu chấp hành như môtơ đã được chế tạo gắn kết hữu cơ với 
cả bộ servo với các thuật toán điều chỉnh PID tại chỗ và khả năng nối mạng số tới máy tính 
chủ. 
Các tủ rơle điều khiển chiếm diện tích lớn trong các phòng điều khiển nay được co 
gọn trong các PLC(programble Logic Controller). 
Các bàn điều khiển với hàng loạt các đồng hồ chỉ báo, các phím, núm điều 
khiển, các bộ tự ghi trên giấy cồng kềnh nay được thay thế bằng một vài PC. 
Chương I: Tổng quan 
Bài giảng lập trình nhúng 4 
Hệ thống cáp truyền tín hiệu analog 4-20mA, ± 10V từ các đầu đo, cơ cấu chấp 
hành về trung tâm điều khiển nhằng nhịt trước đây đã được thay thế bằng vài cáp đồng trục 
hoặc cáp quang truyền dữ liệu số 
Ta có thể nói các hệ nhúng đã “thay thế và chiếm phần ngày càng nhiều” trong các 
phần tử, hệ thống thuộc lĩnh vực công nghệ cao “3C”. 
Vào những năm 30 các hệ thống tự động bằng cam chốt cơ khí thường hoạt 
động đơn lẻ với một chức năng xử lý. Các hệ thống tự động dùng rơle điện từ xuất hiện 
vào những năm 40 có mức xử lý khoảng 10 chức năng. Các hệ thống tự động dùng bán 
dẫn hoạt động theo nguyên lý tương tự (Analog) của thập kỷ 60 có mức xử lý khoảng 30 
chức năng. Vào những năm 70 các thiết bị điều khiển khả trình PLC ra đời với mức độ xử 
lý lên hàng trăm và vào những năm 80 với sự tham gia của các máy tính điện tử main frame 
mini đã hình thành các hệ thống điều khiển phân cấp với số chức năng xử lý lên tới hàng 
chục vạn (105). Sang thập kỷ 90 với sự phát triển của công nghệ phần cứng cũng như 
phần mềm, các hệ thống điều khiển phân tán ra đời(DCS) cho mức xử lý lên tới hàng 
trục triệu (107). Và sang thế kỷ 21, những hệ thống tự động có tính tự tổ chức, có tư 
duy hợp tác sẽ có mức xử lý lên tới hàng tỷ(109). Tuy nhiên để đạt được độ thông minh 
như những sinh vật sống còn cần nhiều thời gian hơn và các hệ thống tự động còn cần tích 
hợp trong nó nhiều công nghệ cao khác như công nghệ cảm biến, công nghệ vật liệu mới, 
công nghệ quang và laser v.v... Đây cũng là xu thế phát triển của các hệ thống tự động 
là ngày càng sử dụng nhiều công nghệ mới hơn trong cấu trúc và hoạt động của mình. 
Trong điều khiển quá trình công nghệ, việc áp dụng các hệ nhúng đã tạo ra khả 
năng tự động hóa toàn bộ dây chuyền sản xuất. Kiến trúc hệ thống điều khiển trước kia tập 
trung về xử lý tại một máy tính thì nay các đầu đo, cơ cấu chấp hành, giao diện với người 
vận hành đều được thông minh hóa có nhiều chức năng xử lý tại chỗ và khả năng nối 
mạng nhanh tạo thành hệ thống mạng máy điều khiển hoạt động theo chế độ thời gian 
thực. Ngoài các chức năng điều khiển và giám sát dây chuyền sản xuất hệ thống còn có 
nhiều cơ sở dữ liệu, khả năng tự xác định và khắc phục hỏng hóc, khả năng thống kê, 
báo cáo và kết hợp hệ thống mạng máy tính quản lý, lập kế hoạch, thiết kế và kinh doanh 
tạo thành hệ thống tự động hóa sản xuất toàn cục. 
Trong lĩnh vực rôbôt, với sự áp dụng các thành tựu của các hệ nhúng, rôbôt đã có 
thị giác và xúc giác. Việc áp dụng trí khôn nhân tạo vào rôbôt đã đưa rôbôt từ ứng dụng 
chủ yếu trong công nghiệp sang các lĩnh vực dịch vụ và y tế. Kết hợp với các thành tựu 
của cơ điện tử, rôbôt ngày càng uyển chuyển và thông minh hơn. Trong tương lai rôbôt 
không chỉ thay thế hoạt động cơ bắp của con người mà còn có thể thay thể các công việc 
đòi hỏi họat động trí não của con người. Lúc này hệ thống điều khiển của rôbôt không chỉ 
là các vi xử lý mạnh mà còn có sự hỗ trợ của các máy tính mạng nơron nhân tạo, xử lý 
song song nhúng trong rôbôt. Các nghiên cứu phát triển này hiện nay còn ở giai đoạn ban 
đầu. 
1.4 Đặc tính, phương pháp thiết kế và xu thế phát triển của các hệ nhúng 
Các hệ nhúng là những hệ kết hợp phần cứng và phần mềm một cách tối ưu. Các 
Chương I: Tổng quan 
Bài giảng lập trình nhúng 5 
hệ nhúng là những hệ chuyên dụng, thường hoạt động trong chế độ thời gian thực, bị hạn 
chế về bộ nhớ, giá thành phải rẻ nhưng lại phải hoạt động tin cậy và tiêu tốn ít năng lượng. 
Các hệ nhúng rất đa dạng và có nhiều kích cỡ, khả năng tính toán khác nhau. Ngoài ra 
các hệ nhúng thường phải hoạt động trong môi trường khắc nghiệt có độ nóng ẩm, rung 
xóc cao. Ví dụ như các điều khiển các máy diesel cho tàu biển, các thiết bị cảnh báo cháy 
nổ trong hầm lò. Các hệ thống nhúng lớn thường là các hệ nối mạng. Ở máy bay, tàu vũ 
trụ thường có nhiều mạng nhúng kết nối để kiểm soát hoạt động và điều khiển.Trong ô tô 
hiện đại có đến trên 80 nút mạng kết nối các đầu đo cơ cấu chấp hành để bảo đảm ô tô hoạt 
động an toàn và thoải mái cho người sử dụng. 
Thiết kế các hệ thống nhúng là thiết kế phần cứng và phần mềm phối hợp. Cách thiết 
kế cổ điển là cách xác định trước các chức năng phần mềm (SW) và phần cứng (HW) rồi 
sau đó các bước thiết kế chi tiết được tiến hành một cách độc lập ở hai khối. Hiện nay đa 
số các hệ thống tự động hóa thiết kế (CAD) thường dành cho thiết kế phần cứng. Các 
hệ thống nhúng hiện nay sử dụng đồng thời nhiều công nghệ như vi xử lý, DSP, mạng và 
các chuẩn phối ghép, protocol, do vậy xu thế thiết kế các hệ nhúng hiện nay đòi hỏi có 
khả năng thay đổi mề ... àm này sẽ tạo ra một sóng vuông ở tần số được định trước (chỉ nửa chu kỳ) tại một 
pin digital bất kỳ (analog vẫn được). Thời hạn của quá trình tạo ra sóng âm có thể được định 
trước hoặc nó sẽ phát ra âm thanh liên tục cho đến khi Arduino IDE chạy hàm noTone(). Chân 
digital đó cần được kết nối tới một buzzer hoặc một loa để có thể phát được âm thanh. 
Lưu ý rằng, chỉ có thể sử dụng duy nhất mộ hàm tone() trong cùng một thời điểm. Nếu 
hàm tone() đang chạy trên một pin nào đó, bây giờ lại tone() thêm một lần nữa thì hàm tone() sau 
sẽ không có hiệu lực. Nếu tone() lên pin đang được tone() thì hàm tone() sau sẽ thay đổi tần số 
sóng của pin đó. 
Trên mạch Arduino Mega, sử dụng hàm tone() thì sẽ can thiệp đến đầu ra PWM tại các 
chân digital 3 và digital 11. 
Hàm tone() sẽ không thể phát ra âm thanh có tần số < 31 Hz. Để biết têm về kĩ thuật 
này, hãy xem trang này. 
Chú ý: Nếu muốn chơi nhiều cao độ khác nhau trên nhiều pin. Thì trước khi chơi trên một pin 
khác thì phải noTone() trên pin đang được sử dụng. 
Cú pháp 
tone(pin, frequency) 
tone(pin, frequency, duration) 
Tham số 
pin: cổng digial / analog muốn chơi nhạc (nói cách khác là pin được kết nối tới loa) 
frequency: tần số của sóng vuông (sóng âm) - unsigned int 
duration: thời gian phát nhạc, đơn vị là mili giây (tùy chọn) - unsigned long 
Trả về 
không 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 97 
Ví dụ 
 Phát nhạc bằng Arduino với một cái loa hoặc buzzer 
4.2.3.7.2 noTone() 
Hàm này có nhiệm vụ kết thúc một sự kiện tone() trên một pin nào đó (đang chạy 
lệnh tone()). Nếu không có bất kỳ hàm tone() nào đang hoạt động thì hàm này sẽ không gây bất 
kỳ ảnh hưởng gì đến chương trình. 
Chú ý: Nếu muốn chơi nhiều cao độ khác nhau trên nhiều pin. Thì trước khi chơi trên một pin 
khác thì b phải noTone() trên pin đang được sử dụng. 
Cú pháp 
noTone(pin) 
Tham số 
pin: cổng digial / analog muốn chơi nhạc (nói cách khác là pin được kết nối tới loa) 
Trả về 
Không 
4.2.3.7.3 shiftOut() 
shiftOut() có nhiệm vụ chuyển 1 byte (gồm 8 bit) ra ngoài từng bit một. Bit được chuyển 
đi có thể được bắt đầu từ bit nằm bên trái nhất (leftmost) hoặc từ bit nằm bên phải nhất 
(rightmost). Các bit này được xuất ra tại chân dataPin sau khi chân clockPin được pulsed (có 
mức điện thế là HIGH, sau đó bị đẩy xuống LOW). 
Lưu ý: Nếu đang giao tiếp với một thiết bị mà chân clock của nó có giá trị được thay đổi từ 
mức điện thế LOW lên HIGH (rising edge) khi shiftOut, thì cần chắc chắn rằng 
chân clockPin cần được chạy lệnh này: digitalWrite(clockPin,LOW); 
Cú pháp 
shiftOut(dataPin, clockPin, bitOrder, value) 
Tham số 
dataPin: pin sẽ được xuất ra tín hiệu (int) 
clockPin: pin dùng để xác nhận việc gửi từng bit của dataPin (int) 
bitOrder: một trong hai giá trị MSBFIRST hoặc LSBFIRST. 
(Bắt đầu từ bit bên phải nhất hoặc Bắt đầu từ bit bên trái nhất) 
value: dữ liệu cần được shiftOut. (byte) 
Chú ý 
shiftOut() chỉ xuất được dữ liệu kiểu byte. Nếu muốn xuất một kiểu dữ liệu lớn hơn thì phải 
shiftOut 2 lần (hoặc nhiều hơn), mỗi lần là 8 bit. 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 98 
Trả về 
không 
Ví dụ 
Điều khiển 8 đèn LED sáng theo ý muốn. 
4.2.3.7.4 pulseIn() 
Đọc một xung tín hiệu digital (HIGH/LOW) và trả về chu kì của xung tín hiệu, tức là 
thời gian tín hiệu chuyển từ mức HIGH xuống LOW hoặc ngược lại (LOW -> HIGH). Một số 
cảm biến như cảm biến màu sắc như TCS3200D hay cảm biến siêu âm dòng HC-SRxx phải 
giao tiếp qua xung tín hiệu nên ta phải kết hợp giữa 2 hàm digitalWrite() để xuất tín hiệu 
và pulseIn() để đọc tín hiệu. 
Cú pháp 
pulseIn(pin, value); 
pulseIn(pin, value, timeout); 
Trong đó: 
pin là chân được chọn để đọc xung. pin có kiểu dữ liệu là int. 
Nếu đặt value là HIGH, hàm pulseIn() sẽ đợi đến khi tín hiệu đạt mức HIGH, khởi động 
bộ đếm thời gian. Khi tín hiệu nhảy xuống LOW, bộ đếm thời gian dừng lại. pulseIn() sẽ trả 
về thời gian tín hiệu nhảy từ mức HIGH xuống LOW này. Nếu đặt value là LOW, 
hàm pulseIn() sẽ làm ngược lại, đó là đo thời gian tín hiệu nhảy từ mức LOW lên 
HIGH. value có kiểu dữ liệu là int. 
Nếu tín hiệu luôn ở một mức HIGH/LOW cố định thì sau khoảng thời gian timeout, 
hàm pulseIn() sẽ dừng bộ đếm thời gian và trả về giá trị 0. timeout được tính bằng đơn vị micro 
giây. Giá trị mặc định của timeout là 60.106 tương ứng với 1 phút. Giá trị tối đa là 180.106 tương 
ứng với 3 phút. timeout có kiểu dữ liệu là unsigned long. 
Trả về 
Một số nguyên kiểu unsigned long, đơn vị là micro giây. pulseIn() trả về 0 nếu thời gian nhảy 
trạng thái HIGH/LOW vượt quá timeout 
Ví dụ 
int pin = 7; 
unsigned long duration; 
void setup() { 
 Serial.begin(9600); 
 pinMode(pin, INPUT); 
} 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 99 
void loop() { 
 duration = pulseIn(pin, HIGH); 
 //Hãy nối chân 7 của Arduino vào đường tín hiệu 
 //muốn đọc xung 
 Serial.println(duration); 
} 
4.2.3.8 Bits và Bytes 
4.2.3.8.1 lowByte() 
lowByte() là hàm trả về byte cuối cùng (8 bit cuối cùng) của một chuỗi các bit. Một số 
nguyên bất kì cũng được xem như là một chuỗi các bit, vì bất kì số nguyên nào cũng có thể biểu 
diễn ở hệ nhị phân dưới dạng các bit "0" và "1". 
Lưu ý: 
lowByte() không nhận giá trị thuộc kiểu dữ liệu số thực. 
Cú pháp 
lowByte([giá trị cần lấy ra 8 bit cuối]); 
Trả về 
byte 
Ví dụ 
int A = lowByte(0B11110011001100); //A = 0B11001100 = 204; 
int B = lowByte(511); //B = lowByte(0B111111111) = 255; 
int C = lowByte(5); //C = lowByte(0B00000101) = 0B101 = 5; 
4.2.3.8.2 highByte() 
highByte() là hàm trả về một chuỗi 8 bit kề với 8 bit cuối cùng của một chuỗi các bit. Như 
vậy, nếu dữ liệu đưa vào một chuỗi 16bit thìhighByte() sẽ trả về 8 bit đầu tiên, nếu dữ liệu đưa 
vào là một chuỗi 8bit hoặc nhỏ hơn, highByte() sẽ trả về giá trị 0. Một số nguyên bất kì cũng 
được xem như là một chuỗi các bit, vì bất kì số nguyên nào cũng có thể biểu diễn ở hệ nhị phân 
dưới dạng các bit "0" và "1". 
Lưu ý: 
highByte() không nhận giá trị thuộc kiểu dữ liệu số thực. 
Cú pháp 
highByte([giá trị đưa vào]); 
Trả về 
byte 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 100 
Ví dụ 
int A = highByte(0B1111111100000000); //A = 0B11111111 = 255; 
int B = highByte(0B10101010); //B = 0 
int C = highByte(0B110000000011111111) //C = 0B00000000 = 0 
int D = highByte(1023); //D = highByte(0B111111111) = 0B11 = 3 
4.2.3.8.3 bitRead() 
bitRead() sẽ trả về giá trị tại một bit nào đó được xác định bởi người lập trình của một 
số nguyên. 
Cú pháp 
bitRead(x, n) 
Tham số 
x: một số nguyên thuộc bất cứ kiểu số nguyên nào 
n: bit cần đọc. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0 
Trả về 
Giá trị của 1 bit (1 hoặc là 0) 
Ví dụ 
bitRead(B11110010,0); // trả về 0 
bitRead(B11110010,1); // trả về 1 
bitRead(B11110010,2); // trả về 0 
//Hàm bitRead có thể viết như sau 
B11110010 >> 0 & 1 // = 0 
B11110010 >> 1 & 1 // = 1 
B11110010 >> 2 & 1 // = 0 
4.2.3.8.4 bitWrite() 
bitWrite() sẽ ghi đè bit tại một vị trí xác định của số nguyên. 
Cú pháp 
bitWrite(x, n, b) 
Tham số 
x: một số nguyên thuộc bất cứ kiểu số nguyên nào 
n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. 
b: 1 hoặc 0 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 101 
Trả về 
không 
Ví dụ 
bitWrite(B11110010,0,1); // B11110011 
bitWrite(B11110010,1,0); // B11110000 
bitWrite(B11110010,2,1); // B11110110 
//Hàm bitWrite có thể viết như sau 
B11110010 | (1 << 0) // = B11110011 
B11110010 & ~(1 << 1) // = B11110000 
B11110010 | (1 << 2) // = B11110110 
4.2.3.8.5 bitSet() 
bitSet() sẽ thay giá trị tại một bit xác định của một số nguyên thành 1. 
Cú pháp 
bitSet(x, n) 
Tham số 
x: một số nguyên thuộc bất cứ kiểu số nguyên nào 
n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. 
Trả về 
không 
Ví dụ 
bitSet(B11110010,0); // B11110011 
bitSet(B11110010,2); // B11110110 
//Hàm bitSet có thể viết như sau 
B11110010 | (1 << 0) // = B11110011 
B11110010 | (1 << 2) // = B11110110 
4.2.3.8.6 bitClear() 
bitClear() sẽ thay giá trị tại một bit xác định của một số nguyên thành 0. 
Cú pháp 
bitClear(x, n) 
Tham số 
x: một số nguyên thuộc bất cứ kiểu số nguyên nào 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 102 
n: vị trí bit cần ghi. Các bit sẽ được tính từ phải qua trái, và số thứ tự đầu tiên là số 0. 
Trả về 
không 
Ví dụ 
bitClear(B11110010,1); // B11110000 
//Hàm bitClear có thể viết như sau 
B11110010 & ~(1 << 1) // = B11110000 
4.2.3.8.7 bit() 
Trả về một số nguyên dạng 2n (2 mũ n). 
Cú pháp 
bit(n) 
Tham số 
n: số nguyên 
Trả về 
một số nguyên 
Ví dụ 
bit(0); // 2^0 = 1 
bit(1); // 2^1 = 2 
bit(2); // 2^2 = 4 
bit(8); // 2^8 = 256 
// cũng có thể viết như sau 
1 << 0 // = 1 
1 << 1 // = 2 
1 << 2 // = 4 
1 << 8 // = 256 
4.2.3.9 Ngắt (interrupt) 
4.2.3.9.1 attachInterrupt() 
Ngắt (interrupt) là những lời gọi hàm tự động khi hệ thống sinh ra một sự kiện. Những 
sự kiện này được nhà sản xuất vi điều khiển thiết lập bằng phần cứng và được cấu hình trong 
phần mềm bằng những tên gọi cố định. 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 103 
Vì ngắt hoạt động độc lập và tự sinh ra khi được cấu hình nên chương trình chính sẽ 
đơn giản hơn. Một ví dụ điển hình về ngắt là hàm millis(). Hàm này tự động chạy cùng với 
chương trình và trả về 1 con số tăng dần theo thời gian mặc dù chúng ta không cài đặt nó. Việc 
cài đặt hàmmillis() sử dụng đến ngắt và được cấu hình tự động bên trong mã chương trình 
Arduino. 
Vì sao cần phải dùng đến ngắt? 
Ngắt giúp chương trình gọn nhẹ và xử lý nhanh hơn. Chẳng hạn, khi kiểm tra 1 nút nhấn 
có được nhấn hay không, thông thường cần kiểm tra trạng thái nút nhấn bằng 
hàm digitalRead() trong đoạn chương trình loop(). Với việc sử dụng ngắt, chỉ cần nối nút nhấn 
đến đúng chân có hỗ trợ ngắt, sau đó cài đặt ngắt sẽ sinh ra khi trạng thái nút chuyển từ HIGH-
>LOW. Thêm 1 tên hàm sẽ gọi khi ngắt sinh ra. Vậy là xong, biến trong đoạn chương trình ngắt 
sẽ cho ta biết trạng thái nút nhấn. 
Số lượng các ngắt phụ thuộc vào từng dòng vi điều khiển. Với Arduino Uno chỉ có 2 
ngắt, Mega 2560 có 6 ngắt và Leonardo có 5 ngắt. 
Board int.0 int.1 int.2 int.3 int.4 int.5 
Uno, Ethernet 2 3 
Mega2560 2 3 21 20 19 18 
Leonardo 3 2 0 1 7 
Cú pháp 
attachInterrupt(interrupt, ISR, mode); 
Thông số 
interrupt: Số thứ tự của ngắt. Trên Arduino Uno, có 2 ngắt với số thứ tự là 0 và 1. Ngắt số 0 
nối với chân digital số 2 và ngắt số 1 nối với chân digital số 3. Muốn dùng ngắt phải gắn nút 
nhấn hoặc cảm biến vào đúng các chân này thì mới sinh ra sự kiện ngắt. Nếu dùng ngắt số 0 mà 
gắn nút nhấn ở chân digital 4 thì không chạy được rồi. 
ISR: tên hàm sẽ gọi khi có sự kiện ngắt được sinh ra. 
mode: kiểu kích hoạt ngắt, bao gồm 
 LOW: kích hoạt liên tục khi trạng thái chân digital có mức thấp 
 HIGH: kích hoạt liên tục khi trạng thái chân digital có mức cao. 
 RISING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp thấp sang mức điện 
áp cao. 
 FALLING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp cao sang mức điện 
áp thấp. 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 104 
Lưu ý: với mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital còn 
giữ mức điện áp tương ứng. 
Trả về 
không 
Ví dụ 
Đoạn chương trình dưới đây sẽ làm sáng đèn led khi không nhấn nút và làm đèn led tắt 
đi khi người dùng nhấn nút, nếu vẫn giữ nút nhấn thì đèn led vẫn còn tắt. Sau khi thả nút nhấn, 
đèn led sẽ sáng trở lại. 
int ledPin = 13; 
void tatled() 
{ 
 digitalWrite(ledPin, LOW); // tắt đèn led 
} 
void setup() 
{ 
 pinMode(ledPin, OUTPUT); 
 pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 
 attachInterrupt(0, tatled, LOW); // gọi hàm tatled liên tục khi còn nhấn nút 
} 
void loop() 
{ 
 digitalWrite(ledPin, HIGH); // bật đèn led 
} 
Một ví dụ khác khi sử dụng ngắt, có thể thoát khỏi các hàm delay để xử lý 1 đoạn chương 
trình khác 
int ledPin = 13; 
void tatled() 
{ 
 // tắt đèn led khi nhấn nút, nhả ra led nhấp nháy trở lại 
 digitalWrite(ledPin, LOW); 
} 
void setup() 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 105 
{ 
 pinMode(ledPin, OUTPUT); 
 pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 
 attachInterrupt(0, tatled, LOW); 
} 
void loop() 
{ 
 // đoạn chương trình này nhấp nháy led sau 500ms 
 digitalWrite(ledPin, HIGH); 
 delay(500); 
 digitalWrite(ledPin, LOW); 
 delay(500); 
} 
4.2.3.9.2 detachInterrupt() 
Hàm detachInterrupt() sẽ tắt các ngắt đã được kích hoạt tương ứng với thông số truyển 
vào. Giả sử sau khi nhấn nút bấm lần đầu tiên đèn led sẽ tắt nhưng nhấn lần thứ 2 đèn sẽ không 
tắt nữa. Lúc này cần dùng đến detachInterrupt() để tắt ngắt chúng ta đã tạo ra. 
Cú pháp 
detachInterrupt(interrupt); 
Thông số 
interrupt: số thứ tự ngắt (xem thêm ở bài attachInterrupt() ) 
Trả về 
không 
Ví dụ 
Đoạn chương trình dưới đây sẽ bật sáng đèn led và chỉ tắt nó khi nhấn lần đầu tiên, thả 
ra đèn sẽ sáng lại. Nếu tiếp tục nhấn nữa thì đèn vẫn sáng mà không bị tắt đi. 
int ledPin = 13; // đèn LED được kết nối với chân digital 13 
boolean daNhan = false; // lưu giữ giá trị cho biết đã nhấn nút hay chưa 
void tatled() 
{ 
 digitalWrite(ledPin, LOW); // tắt đèn led khi còn nhấn nút 
 daNhan = true; // lúc này đã nhấn nút 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 106 
} 
void setup() 
{ 
 pinMode(ledPin, OUTPUT); // thiết đặt chân ledPin là OUTPUT 
 pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0 
 attachInterrupt(0, tatled, LOW); // cài đặt ngắt gọi hàm tatled 
} 
void loop() 
{ 
 digitalWrite(ledPin, HIGH); // bật đèn led 
 if (daNhan == true) 
 { 
 // Nếu đã nhấn nút thì tắt ngắt đi 
 detachInterrupt(0); 
 } 
} 
4.2.3.9.3 interrupts() 
Mặc định, Arduino luôn bật các ngắt nên trong phần setup(), không cần gọi hàm này để 
bật các ngắt. Hàm interrupts() sẽ bật toàn bộ các ngắt đã được cài đặt. Nếu vì lý do nào đó ta 
tắt các ngắt bằng hàm noInterrupts(), sử dụng hàm này để bật lại các ngắt. 
Cú pháp 
interrupts(); 
Thông số 
không 
Trả về 
không 
Ví dụ 
void setup() {} 
void loop() 
{ 
 noInterrupts(); 
 // tắt các ngắt để chạy 
Chương IV: Phần mềm nhúng 
Bài giảng lập trình nhúng 107 
 // đoạn chương trình yêu cầu cao về thời gian 
 interrupts(); 
 // bật lại các ngắt, các ngắt hoạt động 
 // bình thường trở lại 
} 
4.2.3.9.4 noInterrupts() 
Khi cần chạy các đoạn chương trình yêu cầu chính xác về thời gian, cần tắt các ngắt để 
Arduino chỉ tập trung vào xử lý các tác vụ cần thiết và chỉ duy nhất các tác vụ này. Các ngắt 
chạy nền sẽ không được thực thi sau khi gọi hàm noInterrupts(). 
Cú pháp 
noInterrupts(); 
Thông số 
không 
Trả về 
không 
Ví dụ 
void setup() {} 
void loop() 
{ 
 noInterrupts(); 
 // tắt các ngắt để chạy 
 // đoạn chương trình yêu cầu cao về thời gian 
 interrupts(); 
 // bật lại các ngắt, các ngắt hoạt động 
 // bình thường trở lại 
} 

File đính kèm:

  • pdfgiao_trinh_lap_trinh_nhung.pdf