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

pdf 113 trang hapham 80
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 bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfgiao_trinh_lap_trinh_nhung.pdf

Nội dung text: Giáo trình Lập trình nhúng

  1. 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
  2. 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-Down 8 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. 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. 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
  5. Chương I: Tổng quan 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) Bài giảng lập trình nhúng 1
  6. Chương I: Tổng quan 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ị. Bài giảng lập trình nhúng 2
  7. Chương I: Tổng quan Đ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. Bài giảng lập trình nhúng 3
  8. Chương I: Tổng quan 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 Bài giảng lập trình nhúng 4
  9. Chương I: Tổng quan 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 dẻo hơn trong quá trình thiết kế 2 phần HW và SW. Để có được thiết kế cuối cùng tối ưu, quá trình thiết kế SW và HW phải phối hợp với nhau chặt chẽ và có thể thay đổi sau mỗi lần thử chức năng hoạt động tổng hợp. Thiết kế các hệ nhúng đòi hỏi kiến thức đa ngành về điện tử, xử lý tín hiệu, vi xử lý, thuật điều khiển và lập trình thời gian thực. Phần mềm trong các hệ nhúng ngày càng chiếm tỉ trọng cao và đã trở thành một thành phần cấu tạo nên thiết bị bình đẳng như các phần cơ khí, linh kiện điện tử, linh kiện quang học các hệ nhúng ngày càng phức tạp hơn đáp ứng các yêu cầu khắt khe về thời gian thực, tiêu ít năng lượng, hoạt động tin cậy ổn định hơn, có khả năng hội thoại cao, có khả năng kết nối mạng, có thích nghi, tự tổ chức cao có khả năng tái cấu hình như một thực thể, một tác nhân. Và có khả năng tiếp nhận năng lượng từ nhiều nguồn khác nhau (ánh sáng, rung động, điện từ trường, sinh học ) để tạo nên các hệ thống tự tiếp nhận năng lượng trong quá trình họat động. Tuy nhiên hệ thống nhúng hiện nay còn phải đối mặt với nhiều thách. Độ phức tạp của hệ thống tăng cao do nó kết hợp nhiều lĩnh vực đa ngành, kết hợp phần cứng - mềm, trong khi các phương pháp thiết kế và kiểm tra chưa chín muồi. Khoảng cách giữa lý thuyết và thực hành lớn và còn thiếu các phương pháp và lý thuyết hoàn chỉnh cho khảo sát phân tích toàn cục của hệ nhúng bao gồm lý thuyết điều khiển tự động, thiết kế máy, công nghệ phần mềm, điện tử, vi xử lý, các công nghệ hỗ trợ khác. Mặt khác các hệ nhúng còn nhiều vấn đề cần giải quyết với độ tin cậy và tính mở của hệ thống. Do hệ thống nhúng thường phải hội thoại với môi trường xung quanh nên nhiều khi gặp những tình huống không lường trước dễ dẫn đến hệ thống bị loạn. Trong quá trình hoạt động một số phần mềm thường phải chỉnh lại và thay đổi nên hệ thống phần mềm có thể không kiểm soát được. Đối với hệ thống mở, các hãng thứ 3 đưa các module mới, thành phần mới vào cũng có thể gây nên sự hoạt động thiếu tin cậy. Bài giảng lập trình nhúng 5
  10. Chương I: Tổng quan 1.5 Môi trường thông minh Công nghệ bán dẫn phát triển mạnh theo xu thế ngày càng rẻ, tích hợp cao, có khả năng tính toán lớn, khả năng kết nối toàn cầu, khả năng phối hợp với các cảm biến và cơ cấu chấp hành vi cơ điện và sinh học, khả năng giao diện không qua bàn phím đang tạo tiền đề và cơ sở cho sự bùng nổ của các thiết bị vật dụng thông minh xung quanh ta. Đây là sự khởi đầu của thời đại hậu PC - Môi trường thông minh. Các phần mềm nhúng trong các chip vi hệ htống rất phong phú và có độ mềm dẻo, tái sử dụng cao. Sức đẩy của công nghệ sẽ đưa công nghệ vi điện tử tiếp cận và cộng năng với công nghệ sinh học tạo nên công nghệ nano với độ phức tạp giga vào thập niên 2010-2020. Các chip vi hệ thống xử lý hỗn hợp tương tự và số MS-SoC (Mixed Signal System on chip) vào giai đoạn này sẽ có trên 2 tỷ transistor, 1000 lõi CPU, 100MB bộ nhớ và hoạt động ở tần số 200GHz. Với những vi hệ thống có khả năng tính toán siêu hạng này việc thiết kế các hệ nhúng sẽ gặp không ít thách thức như xử lý song song, độ phức tạp của phần mềm nhúng và khả năng cung cấp năng lượng cho các thiết bị cầm tay. Trong tương lai năng lượng cho truyền dữ liệu sẽ lớn gấp từ 5 đến 30 lần năng lượng hoạt động của các CPU. Trước đây các hệ thống thường được thiết kế trên nền phần cứng là PC và phần mềm là Windown hoặc Linux, thì ngày nay số lượng các hệ nền (platform) cho thiết kế các hệ nhúng có khoảng 25. Trong tương lai các hệ nhúng sẽ được thiết kế trên nền các chip MS-SoC tạo nên các platform thiết kế chuyên dụng với số lượng sẽ lên đến hơn 500 loại. Ta có thể liệt kê một số ví dụ điển hình như platform raptor II cho thiết kế camera số, PXA240 cho thiết kế các thiết bị PDA, TL850 cho TV số, BLUECORE cho công nghệ không dây Bluetooth, CDMA cho mobile phone 3G các hệ MS-SoC sẽ có khả năng tái cấu hình và sẽ là công cụ chủ chốt cho các sản phẩm của công nghệ cao “3C”. 1.6 Các hệ điều hành nhúng và phần mềm nhúng 1.6.1 Hệ điều hành nhúng Khác với PC thường chạy trên nền hệ điều hành windows hoặc unix, các hệ thống nhúng có các hệ điều hành nhúng riêng của mình. Các hệ điều hành dùng trong các hệ nhúng nổi trội hiện nay bao gồm Embedded linux, VxWorks, WinCE, Lynyos, BSD, Green Hills, QNX và DOS, Embeddde linux hiện đang phát triển mạnh. Năm 2001 hệ điều hành này chiếm 12% thị phần các hệ điều hành nhúng thì năm 2002 chiếm 27% và chiếm vị trí số 1. Hiện nay 40% các nhà thiết kế các hệ nhúng cân nhắc đầu tiên sử dụng Embedded linux cho các ứng dụng mới của mình và sau đó mới đến các hệ điều hành nhúng truyền thống như VxWorks, WinCE. Các đối thủ cạnh tranh của Embedded linux hiện nay là các hệ điều hành nhúng tự tạo và windows CE. Sở dĩ Embedded linux có sự phát triển vượt bậc là do có sức hấp dẫn đối với các ứng dụng giá thành thấp và đòi hỏi thời gian đưa sản phẩm ra thị trường nhanh. Mặt khác Linux là phần mềm mã nguồn mở nên bất kỳ ai cũng có thể hiểu và thay đổi theo ý mình. Linux cũng là một hệ điều hành có cấu trúc module và chiếm ít bộ nhớ trong khi windows không có các đặc tính ưu Bài giảng lập trình nhúng 6
  11. Chương I: Tổng quan việt này. Do thị trường của các sản phẩm nhúng tăng mạnh lên các nhà sản xuất ngày càng sử dụng các hệ điều hành nhúng để đảm bảo sản phẩm có sức cạnh tranh và Embedded linux đang là sản phẩm hệ điều hành nhúng có uy tín chiếm vị trí số 1 trong những năm tới. 1.6.2 Phần mềm nhúng Phần mềm nhúng là phần mềm tạo nên phần hồn, phần trí tuệ của các sản phẩm nhúng. Phần mềm nhúng ngày càng có tỉ lệ cao trong giá trị của các sản phẩm nhúng. Hiện nay phần lớn các phần mềm nhúng nằm trong các sản phẩm truyền thông và các sản phẩm điện tử gia dụng (consumer electronics) tiếp đến là trong các sản phẩm ô tô, phương tiện vận chuyển, máy móc thiết bị y tế, các thiết bị năng lượng các thiết bị cảnh báo bảo vệ và các sản phẩm đo và điều khiển. Để có thể tồn tại và phát triển, các sản phẩm công nghiệp và tiêu dùng cần phải thường xuyên đổi mới và ngày càng có nhiều chức năng tiện dụng và thông minh hơn. Các chức năng này phần lớn do các chương trình nhúng tạo nên. Phần mềm nhúng là một lĩnh vực công nghệ then chốt cho sự phát triển kinh tế của nhiều quốc gia trên thế giới như Nhật Bản, Hàn Quốc, Phần Lan và Trung Quốc. Tại Mỹ có nhiều chương trình hỗ trợ của nhà nước để phát triển các hệ thống và phần mềm nhúng. Hàn Quốc có những dự án lớn nhằm phát triển công nghệ phần mềm nhúng như các thiết bị gia dụng nối mạng Internet, hệ thống phần mềm nhúng cho phát triển thành phố thông minh, dự án phát triển ngành công nghiệp phần mềm nhúng, trung tâm hỗ trợ các ngành công nghiệp hậu PC v.v Hàn Quốc cũng chấp nhận Embedded linux như một hệ điều hành chủ chốt trong việc phát triển các sản phẩm nhúng của mình. Thụy Điển coi phát triển các hệ nhúng có tầm quan trọng chiến lược cho sự phát triển của đất nước. Phần Lan có những chính sách quốc gia tích cực cho nghiên cứu phát triển các hệ nhúng đặc biệt là các phần mềm nhúng. Những quốc gia này còn thành lập nhiều viện nghiên cứu và trung tâm phát triển các hệ nhúng. Bài giảng lập trình nhúng 7
  12. Chương II: Lý thuyết thiết kế hệ thống nhúng Chương 2: LÝ THUYẾT THIẾT KẾ HỆ THỐNG NHÚNG 2.1 Quy trình thiết kế Top-Down Quy trình Top-Down thường được áp dụng cho các bài toán đã có giải pháp công nghệ cả về phần mềm cũng như phần cứng. Các giải pháp này đã được phát triển trước đó ở các ứng dụng khác, và đã được kiểm định. Trong thực tế chúng ta sẽ thấy, bản chất hay mấu chốt của quy trình là vấn đề tìm hiểu và xác định bài toán, làm sao để xác định được chính xác và đầy đủ nhất các yêu cầu cũng các rằng buộc mà hệ thống phải đạt được. Sơ đồ khối quy trình kế top-down ở hình 2.1 Hình 2.1 Sơ đồ khối quy trình Top - Down 2.1.1 Pha phân tích Pha này là pha quan trọng nhất quyết định hệ thống có đạt yêu cầu hay không. Một hệ thống nhúng cụ thể phải được đặt vào (nhúng vào) một hệ thống lớn cụ thể. Vì thế ta Bài giảng lập trình nhúng 8
  13. Chương II: Lý thuyết thiết kế hệ thống nhúng cần phải biết có những yêu cầu nào cho nó, môi trường hay điều kiện làm việc của nó. Thông tin này gọi là các yêu cầu và các điều kiện rằng buộc cho hệ thống, nó giúp cụ thể hoá được việc chọn giải pháp công nghệ và thiết bị cho các kỹ sư thiết kế ở pha sau. - Các yêu cầu: Các thông tin chi tiết về nhiệm vụ mà hệ thống phải giải quyết được, các tham số đầu vào đầu ra, các giới hạn trong hệ thống cụ thể, - Các rằng buộc: Điều kiện làm việc và các hạn chế như thời tiết, độ ẩm, độ nhiễu, độ chính xác, tính thời gian thực, loại tín hiệu giao tiếp với hệ thống mẹ, Ví dụ: Xét bài toán thiết kế hệ thống điều khiển cho 1 cửa tự động Giả sử qua quá trình khảo sát thực tế và yêu cầu của bên khác hàng ta phải xác định được các thông số tối thiểu sau: a) Yêu cầu: 1) Hệ thống áp dụng cho 1 cửa hai chiều (vào/ra) 2) Cửa cao 2,5m rộng 3m 3) Có người trong phạm vi 2m trước và sau cửa là cửa phải mở 4) Thời gian mở và đóng cửa 3s 5) Cửa đang đóng gặp vật cản phải mở ra ngay 6) Làm việc điện áp 220v/50Hz 7) Chi phí cho bộ điều khiển không quá 10 triệu VNĐ 8) Hệ thống thống có 2 chế độ làm việc tự động và bằng tay 9) Sensor và công nghệ tuỳ chọn b) Điều kiện rằng buộc 1) Sử dụng động cơ động lực có sẵn loại AC một pha 220V/50Hz 3kW. 2) Nơi đặt cửa có nhiều người qua lại, nên hệ thống sẽ phải làm việc với tần suất cao. 3) Điều kiện môi trường: Trong nhà, nhiệt độ từ 180C đến 360C 4) Bộ điều khiển bằng tay đặt cạnh cửa phía bên trong nhà 5) Hệ thống điện cấp mới từ đầu 6) Chịu được quá tải khi gặp chướng ngại vật trong khoảng thời gian dài. Trong các bài toán cụ thể, với các hệ thống mẹ cụ thể, mỗi hệ thống nhúng sẽ có các yêu cầu khác nhau. Tuy nhiên vẫn có những tiêu chuẩn và yêu cầu chung mà hầu hết các hệ thống phải tính đến như: - Tính đến chi phí bảo trì định kỳ - Kích thước và trọng lượng - Khả năng thực thi: Thời gian đáp ứng, độ chính xác, độ phân giải, Bài giảng lập trình nhúng 9
  14. Chương II: Lý thuyết thiết kế hệ thống nhúng - Nguồn nuôi - Tính mềm dẻo, khả năng nâng cấp, khả năng tương thích, khả năng phục hồi sau khi mất nguồn, - Thời gian thử - Thời gian để thương mại sản phẩm - Độ an toàn - Khả năng chống lại sự phá hoại hay xâm nhập. 2.1.2 Pha thiết kế nguyên lý Mục tiêu của pha này là xác định các giải pháp công nghệ từ các yêu cầu đặt ra ở pha Phân tích, từ đó đi thiết kế mô hình, sơ đồ nguyên lý cho toàn bộ hệ thống bao gồm cả phần cứng và phần mềm. Để thực hiện bước này thông thường trải qua các bước sau: - Trước tiên ta phải xây dựng một sơ đồ mô hình tổng quát của toàn hệ thống. - Sau đó phân tách thành các module hay các hệ thống con. - Định giá cho hệ thống, lập kế hoạch phát triển và ước lượng thời gian phát triển hệ thống. - Xây dựng các sơ đồ luồng dữu liệu giữa các module hay các hệ thống con trong hệ thống Ví dụ 2: Xây dựng và phân tách các module trong mô hình tổng quát của bài toán điều khiển động cơ. Hình 2.2 Sơ đồ tổng quát của một hệ thống điều khiển động cơ Bài giảng lập trình nhúng 10
  15. Chương II: Lý thuyết thiết kế hệ thống nhúng 2.1.3 Pha thiết kế kỹ thuật • Xây dựng các thiết kế chi tiết cho cả phần cứng phần mềm, các bản thiết kế này sẽ được chuyển sang pha thực thi để xây dựng hệ thống. Vì thế ở pha này người thiết kế phải đưa ra các bản thiết kế như: 1. Sơ đồ khối, sơ đồ thuật toán. 2. Cấu trúc dữu liệu, dữ liệu chia sẻ. 3. Sơ đồ nguyên lý mạch, chi tiết về các đầu vào/ra, loại tín hiệu hay giao thức giao tiếp. 4. Thông số linh kiện được chọn hoặc có thể thay thế. 5. Các tham số vào/ra cho hệ thống. 6. Lựa chọn thiết bị, công cụ phát triển hệ thống, các tài nguyên sẽ sử dụng. 7. • Xây dựng sơ đồ quan hệ giữa các module và các hàm trong hệ thống (call graph), sơ đồ này mô tả cách thức tương tác giữa phần cứng và phần mềm trong hệ thống. Ví dụ: Sơ đồ Call graph của hệ thống điều khiển động cơ Hình 2.3 Sơ đồ quan hệ (call graph) giữa các module phần cứng và phân mềm trong hệ thống điều khiển động cơ Để phát hiện và hạn chế tối đa các lỗi mà hệ thống sẽ gặp phải sau khi được xây dựng, ta có thể mô hình hóa các thành phần hoặc toàn bộ hệ thống nếu có thể, nhằm thử nghiệm hoạt động của hệ thống với các đầu vào và tình huống giả lập, đồng thời thử nghiệm tính thân thiện của giao diện người dùng. 2.1.4 Pha xây dựng hệ thống Từ các bản thiết kế, bước này tiến hành xây dựng hoàn thiện hệ thống trên cả phân mềm và phần cứng. Trong suốt quá trình xây dựng phải tuân thủ theo các bước và sơ đồ công nghệ từ các bản thiết kế kỹ thuật. Đặc biệt là các tham số vào ra giữa các Bài giảng lập trình nhúng 11
  16. Chương II: Lý thuyết thiết kế hệ thống nhúng hàm, điều này ảnh hưởng đến việc tích hợp các module giữa các nhóm làm việc khác nhau hay sự kế thừa từ các module khác. Các linh kiện và thiết bị sử dụng phải tuân thủ theo bản thiết kế, nhằm giúp hệ thống thỏa mãn đầy đủ các thông số rằng buộc đã được đặt ra ở pha phân tích. Việc phát triển hệ thống có thể được phân tách thành nhiều nhóm, nhiều phần không cần tuân theo tuần tự, hoặc có thể trên nhiều môi trường khác nhau miễn sao đảm bảo việc trao đổi tham số giữa các module là tương thích và đầy đủ. Nếu chúng ta phân tách và thiết kế tốt, việc phát triển hệ thống có thể được tiến hành song song, hoặc kế thừa cái có sẵn, sẽ làm giảm thời gian phát triển hệ thống đáng kể mà vẫn đảm bảo các yêu cầu đã đặt ra. Một số các kỹ thuật nhằm phát hiện và hạn chế lỗi mà người phát triển có thể áp dụng trong pha này là Debug hay mô phỏng Simulation. Tuy nhiên trong một bài toán cụ thể việc Debug là rất khó, thông thường người phát triển luôn sử dụng một trình mô phỏng (Simulation) với các phép thử trên các tín hiệu giả lập. 2.1.5 Pha kiểm tra Mục tiêu của pha này là đánh giá khả năng thực thi của hệ thống sau khi đã hoàn thiện, thông thường ta thực hiện các bước sau: Đầu tiên ta tiến hành gỡ lỗi (debug) và kiểm định cho từng chức năng cơ của hệ thống. Tiếp theo đánh giá khả năng thực thi của hệ thống dựa trên nhiều tiêu chí khác nhau như: Tốc độ, độ chính xác, tính ổn định, Ngày nay rất nhiều công ty trên nhiều lĩnh vực tuyển dụng nhân sự riêng cho pha này gọi là testing hay các tester. Nhiệm của của các Tester không chỉ là kiểm các tính năng của sản phẩm có phù hợp với các yêu cầu đã đề ra hay không, mà còn phải nghĩ ra các tình huống, các mẫu, để tìm ra các lỗi mà người thiết kế hay người phát triển chưa phát hiện ra được. Các thông tin kết quả của bước này quyết định một sản phẩm có thể được thương mại hóa hay không, hay phải bắt đầu một chu kỳ mới với pha đầu tiên là pha phân tích bao gồm các thông tin mới thu thập được từ bước này. 2.2. Quy trình Bottom-Up Quy trình Bottom-Up trong thực tế thường áp dụng trong các bài toán chưa lựa chọn hay chưa tìm ra được giải pháp công nghệ. Mấu chốt của quy trình tập trung chủ yêu và quá trình thử nghiệm với hệ thống và tín hiệu thực, từ đó chọn ra giải pháp công nghệ và linh kiện phù hợp nhất cho bài toán. Sơ đồ tổng quát của quy trình như hình 2.4 Bài giảng lập trình nhúng 12
  17. Chương II: Lý thuyết thiết kế hệ thống nhúng Hình 2.4 Sơ đồ khối quy trình Bottom - Up Quy trình Bottom-Up bắt đầu từ các ý tưởng đơn lẻ, sau đó xây dựng luôn thiết kế kỹ thuật. Như ta thấy quy trình hoàn toàn ngược so với Top-Down. Quy trình này thường áp dụng có các bài toán chưa lắm chắc về lời giải, người thiết kế mới chỉ có ý tưởng về một vấn đề nào đó và muốn tìm một giải pháp hoặc giải pháp tốt nhất để giải quyết vấn đề. Việc giải quyết các ý tưởng có thể 1 hoặc nhiều để có một sản phẩm hoàn chỉnh. Ở quy trình này ta cần chú ý có 2 khâu test nhằm kiểm định chính xác lại các thiết kế kỹ thuật và thiết kế nguyên lý trước khi lựa chọn 1 giải pháp tối ứu nhất. Chính từ việc thí nghiệm và thiết kế thử hệ thống trước, sau đó mới có thể phân tích nguyên lý để chọn các đặc tính mới, rằng buộc mới cho một hệ thống mới. Với quy trình này khâu thiết kế kỹ thuật và Test sau khi xây dựng hệ thống là quan trọng nhất. Vì với Top-Down việc xây dựng một sản phẩm là theo nhu cầu của người dùng và môi trường đặt hệ thống. Còn với Bottom-Up có thể người ta còn chưa tìm ra cách để thiết kế ra sản phẩm đó, hoặc sản phẩm đó chưa hề có trên thị trường, khi đó cả người dùng và người thiết kế chưa thể có thông tin gì về các yêu cầu cho sản phẩm hay các đặt tính kỹ thuật của sản phẩm, vì vậy khâu thiết kế kỹ thuật và Test sau thực thi các kỹ sư phải tìm ra các đặt tính đó, nhằm xác định được các ưu việt cũng như các hạn chế của sản phẩm mới. Bài giảng lập trình nhúng 13
  18. Chương II: Lý thuyết thiết kế hệ thống nhúng 2.3 Đặc tả hệ thống 2.3.1 Khái niệm đặc tả (specification) Kỹ thuật đặc tả nhằm định nghĩa một hệ thống, module hay sản phẩm cần phải làm gì, nhưng không mô tả nó phải làm thế nào. Nghĩa là đặc tả chỉ tập trung vào việc mô tả các chức năng, đầu vào và đầu ra, còn giải pháp để từ đầu vào có được đầu ra như thế nào thì không mô tả. Đồng thời nêu nên các tính chất của vấn đề đặt ra. Như vậy bản chất ta sử dụng một công cụ để mô hình hoá một hệ thống thành các module, các luồng dữ liệu vào ra, các yêu cầu của tín hiệu hay dữ liệu, các thông tin trao đổi giữa các module, Sao cho toàn bộ quy trình làm việc của hệ thống có thể đọc được thông qua đặc tả. Ở đây ta không quan tâm đến công nghệ của hệ thống, mà chỉ quan tâm đến chức năng, nhiệm vụ và các tính chất mà hệ thống phải có được. Đặc tả có thể được tiến hành ở nhiều giai đoạn, nhiều lần trong tiến trình phát triển hệ thống như: • Đặc tả yêu cầu (requirement specification): Nhằm mô tả đầy đủ và chi tiết những thống nhất giữa người sử dụng tương lai và người thiết kế về hệ thống. Đây là các thông tin cơ sở để người thiết kế thiết hệ thống của mình, nhiệm vụ người thiết kế pahỉ thiết kế đầy đủ và hoàn thiện theo yêu cầu đã thống nhất, người sử dụng tương lại được phép đỏi hỏi, giám sát việc thực thi các yêu cầu trong phạm vi đã thoả thuận. • Đặc tả kiến trúc hệ thống (system architect specification): Nhằm mô tả sự thống nhất giữa người thiết kế và người cài đặt. Các đặt tả nhằm chỉ ra được các chức năng, tính chất và nhiệm vụ cho các thành phần hệ thống chuẩn bị được cài đặt. Việc xác định các yêu cầu từ đó chuyển thành bản thiết kế đã được đặc tả ởkhâu đặc tả yêu cầu, vì thế khâu này người cài đặt chỉ quan tầm đến bản thiết kế và những rằng buộc đã thống nhất với người thiết kế. • Đặc tả Module (module specification): Mô tả sự thống nhất giữa người lập trình cài đặt module và người lập trình sử dụng module. Quá trình cài đặt hệ thống có thể được phân ra thành nhiều module được cài đặt một cách song song, hay kế thừa từ module có sẵn hay module đặt hàng, vì thế người cài đặt và người sử dụng module cần đặc tả chi tiết các chức năng, nhiệm vụ và đặc biệt các giao tiếp của hàm, để sao cho có thể ghép nối tương thích và hiệu quả module đó vào hệ thống. 2.3.2 Tại sao cần đặc tả Việc đặc tả là rất cần thiết trước khi xây dựng một hệ thống bất kỳ trong lĩnh vực nào bời vì: • Đặc tả mang tính hợp đồng: Mô tả đầy đủ và chi tiết sự thống nhất giữa ngườisử dụng và người phát triển, chính vì thế đây là cơ pháp lý và khoa học để người phát triển thiết kế, còn người sử dụng thì giám sát và kiểm định. • Giúp sản phẩm hợp thức hoá: Sản phẩm được phát triển theo các yêu cầu đã thoả thuận, vì thế sản phẩm đương nhiên sẽ đặt yêu cầu với người sử dụng. Bài giảng lập trình nhúng 14
  19. Chương II: Lý thuyết thiết kế hệ thống nhúng • Đặc tả là công cụ để trao đổi: Ngôn ngữ đặc tả là một ngôn ngử được quy định chung và thống nhất vì thế các đặc tả có thể được trao đổi giữa các người thiết kế với nhau. Đồng thời thông qua đó người sử dụng cũng có thể có cái nhìn tổng quát về sản phẩm. • Tái sử dụng: Một đặc tả có thể được lưu giữ để phát triển tiếp hoặc được bổ sung nâng cấp về sau. 2.3.3 Phân loại các kỹ thuật đặc tả a) Đặc tả phi hình thức: Sử dụng 1 trong các công cụ sau để mô tả hệ thống o Ngôn ngữ tự nhiên tự do o Ngôn ngữ tự nhiên có cấu trúc o Các ký hiệu đồ họa b) Đặc tả nửa hình thức: Sử dụng hỗn hợp cả ngôn ngữ tự nhiên, các ký hiệu toán học và các ký hiệu đồ họa c) Đặc tả hình thức: Sử dụng các ký hiệu toán học để mô hình hóa hệ thống, các ký hiệu toán học là các ký hiệu thống nhất chung có thể là: o Ngôn ngữ đặc tả o Ngôn ngữ lập trình So sánh đặc tả hình thức và đặc tả phi hình thức: Đặc tả hình thức Đặc tả phi hình thức • Chính xác (vì sử dụng các ký hiệu toán • Phương pháp sử dụng ngôn ngữ tự học đã được thống nhất trên thế giới). nhiên, tự do và bản địa nên dễ hiểu, dễ sử • Hợp thức hóa hình thức. dụng. • Sử dụng là công cụ trao đổi giữa các • Khả năng mềm dẻo cao, vì công cụ mô người thiết kế, tuy nhiên vì sử dụng các tả là ngôn ngữ dễ thay thế. ký hiệu toán học chuyên ngành nên khó • Thiếu sự chính xác và đầy đủ do hạn đọc và khó hiểu. chế của ngôn ngữ và mang tính chủ quan. • Chỉ dành cho những người có kiến thức • Nhập nhằng. chuyên môn nên khó sử dụng. 2.3.4 Ứng dụng và ưu việt khỉ sử dụng đặc tả a) Ứng dụng • Đặc tả thường sử dụng trong giai đoàn đầu của tiến trình phát triển sản phẩm Bài giảng lập trình nhúng 15
  20. Chương II: Lý thuyết thiết kế hệ thống nhúng • Nhằm hạn chế lỗi trong quá trình phát triển phần mềm, thông qua việc đặc tả chi tiết và đầy đủ các chức năng, nhiệm vụ và tính chất cho tất cả các thành phần của sản phẩm • Kỹ thuật đặc tả thường dùng khi phát triển các hệ thống o Hệ thống điều khiển o Hệ thống nhúng o Hệ thống thời gian thực b) Ưu việt khi sử dụng đặc tả Ưu điểm khi sử dụng đặc tả được thể hiện rõ nhất qua qua chi phí phát triển hệ thống, ta có thể thấy rõ qua biểu đồ sau: Hình 2.5 Biểu đồ so sánh chi phí phát triẻn hệ thống sử dụng đặc tả và không sử dụng Qua biểu đồ ta dễ dành nhận ra tổng chi phí khi sử dụng đặc tả giảm đi rất nhiều, điều nay sẽ là cho giá thành sản phẩm đạt được tính cạnh tranh. 2.3.5 Phương pháp đặc tả sử dụng “Máy trạng thái hữu hạn FSM(Finite state machine)” Trong thực tế có một số phương pháp đặc tả như: • Máy trạng thái hữu hạn • Mạng Petri (thường dùng để mô tả các hệ thống phức tạp không đồng bộ, có nhiều khâu làm việc song song) • Điều kiện trước sau (thường dùng đặc tả cho các hàm hoặc module) Bài giảng lập trình nhúng 16
  21. Chương II: Lý thuyết thiết kế hệ thống nhúng • Kiểu trừu tượng (mô tả dữ liệu và các thao tác trên dữ liệu đó ở một mức trừu tượng độc lập với cách cài đặt dữ liệu bởi ngôn ngữ lập trình) Trong phạp vi này bài giảng chỉ tập trung trình bày về kỹ thuật đặc tả sử dụng máy trạng thái hữu hạn, do tính đơn giản và phù hời với các hệ thống nhỏ có tính moudle và tuần tự cao. Phương pháp máy trạng thái hữu hạn: • Phương pháp mô tả các luông điều khiển trong hệ thống • Biểu diễn hệ thống dưới dạng đồ thị • Đồ thị bao gồm: o Nút: mỗi nút là một trạng thái S của hệ thống o Nhãn: Mô tả dữ liệu đầu vào, là nhãn của một cung o Cung: Một chuyển tiếp T : S x I -> S (chuyển tiếp mô tả một sự biến đổi trạng thái khi một trạng có dữ liệu vào) Ví dụ 1: Hình 2.6 Đặc tả cách thức làm việc của một máy điện thoại sử dụng máy trạng thái hữu hạn 2.4 Các phương pháp biểu diễn thuật toán Khi chứng minh hoặc giải một bài toán trong toán học, ta thường dùng những ngôn từ toán học như : "ta có", "điều phải chứng minh", "giả thuyết", và sử dụng những phép suy luận toán học như phép suy ra, tương đương, Thuật toán là một phương pháp thể hiện lời giải bài toán nên cũng phải tuân theo một số quy tắc nhất định. Bài giảng lập trình nhúng 17
  22. Chương II: Lý thuyết thiết kế hệ thống nhúng Ðể có thể truyền đạt thuật toán cho người khác hay chuyển thuật toán thành chương trình máy tính, ta phải có phương pháp biểu diễn thuật toán. Có 3 phương pháp biểu diễn thuật toán : 1. Dùng ngôn ngữ tự nhiên. 2. Dùng lưu đồ-sơ đồ khối (flowchart). 3. Dùng mã giả (pseudocode) 2.4.1 Ngôn ngữ tự nhiên Trong cách biểu diễn thuật toán theo ngôn ngữ tự nhiên, người ta sử dụng ngôn ngữ thường ngày để liệt kê các bước của thuật toán . Phương pháp biểu diễn này không yêu cầu người viết thuật toán cũng như người đọc thuật toán phải nắm các quy tắc. Tuy vậy, cách biểu diễn này thường dài dòng, không thể hiện rõ cấu trúc của thuật toán, đôi lúc gây hiểu lầm hoặc khó hiểu cho người đọc. Gần như không có một quy tắc cố định nào trong việc thể hiện thuật toán bằng ngôn ngữ tự nhiên. Tuy vậy, để dễ đọc, ta nên viết các bước con lùi vào bên phải và đánh số bước theo quy tắc phân cấp như 1, 1.1, 1.1.1 Ví dụ: Biểu diễn thuật toán giải phương trình bậc hai dùng ngôn ngữ tự nhiên (không xét đến nghiệm phức) Đầu vào: Phương trình ax2 + bx + c =0 Đầu ra: Nghiệm Bước 1: Xác định hệ số a,b,c 1.1. Nếu a≠0 chuyển đến bước 2 1.2. Nếu a=0 không thực hiện vì la phương trình bậc nhất Bước 2: Tính ∆ = b2 - 4ac Bước 3: Kiểm tra ∆ 3.1. Nếu ∆>0 đến bước 4 3.2. Nếu ∆=0 đến bước 5 3.3. Nếu ∆<0 báo phương trình vô nghiệm, kết thúc thuật toán Bước 4: Báo phương trình có 2 nghiệm kết thúc thuật toán Bước 5: Phương trình có nghiệm kép x1=x2=-b/2a, kết thúc thuật toán 2.4.2 Dùng lưu đồ Lưu đồ hay sơ đồ khối là một công cụ trực quan để diễn đạt các thuật toán. Biểu diễn thuật toán bằng lưu đồ sẽ giúp người đọc theo dõi được sự phân cấp các trường hợp và quá trình xử lý của thuật toán. Phương pháp lưu đồ thường được dùng trong những thuật toán có tính rắc rối, khó theo dõi được quá trình xử lý. Ðể biểu diễn thuật toán theo sơ đồ khối, ta phải phân biệt hai loại thao tác. Một thao Bài giảng lập trình nhúng 18
  23. Chương II: Lý thuyết thiết kế hệ thống nhúng tác là thao tác chọn lựa dựa theo một điều kiện nào đó. Chẳng hạn : thao tác "nếu a = b thì thực hiện thao tác B2, ngược lại thực hiện B4" là thao tác chọn lựa. Các thao tác còn lại không thuộc loại chọn lựa được xếp vào loại hành động. Chẳng hạn, "Chọn một hộp bất kỳ và để lên đĩa cân còn trống." là một thao tác thuộc loại hành động. a) Thao tác chọn lựa (hay còn gọi khối điều kiện) Thao tác chọn lựa được biểu diễn bằng một hình thoi, bên trong chứa biểu thức điều kiện. b) Thao tác xử lý (process) Thao tác xử lý được biểu diễn bằng một hình chữ nhật, bên trong chứa nội dung xử lý. c) Ðường đi (route) Khi dùng ngôn ngữ tự nhiên, ta mặc định hiểu rằng quá trình thực hiện sẽ lần lượt đi từ bước trước đến bước sau (trừ khi có yêu cầu nhảy sang bước khác). Trong ngôn ngữ lưu đồ, do thể hiện các bước bằng hình vẽ và có thể đặt các hình vẽ này ở vị trí bất kỳ nên ta phải có phương pháp để thể hiện trình tự thực hiện các thao tác. Hai bước kế tiếp nhau được nối bằng một cung, trên cung có mũi tên để chỉ hướng thực hiện. Chẳng hạn trong hình dưới, trình tự thực hiện sẽ là B1, B2, B3. Từ thao tác chọn lựa có thể có đến hai hướng đi, một hướng ứng với điều kiện thỏa và một hướng ứng với điều kiện không thỏa. Do vậy, ta dùng hai cung xuất phát từ các đỉnh hình thoi, trên mỗi cung có ký hiệu Ð/Ðúng/Y/Yes để chỉ hướng đi ứng với điều kiện thỏa và ký hiệu S/Sai/N/No để chỉ hướng đi ứng với điều kiện không thỏa. Bài giảng lập trình nhúng 19
  24. Chương II: Lý thuyết thiết kế hệ thống nhúng Hình 2.7 Lưu đồ thuật toán giải phương trình bậc 2 d) Ðiểm cuối (terminator) Ðiểm cuối là điểm khởi đầu và kết thúc của thuật toán, được biểu diễn bằng hình ovan, bên trong có ghi chữ bắt đầu/start/begin hoặc kết thúc/end. Ðiểm cuối chỉ có cung đi ra (điểm khởi đầu) hoặc cung đi vào (điểm kết thúc). Xem lưu đồ thuật toán giải phương trình bậc hai ở trên để thấy cách sử dụng của điểm cuối. e) Ðiểm nối (connector) Bài giảng lập trình nhúng 20
  25. Chương II: Lý thuyết thiết kế hệ thống nhúng Ðiểm nối được dùng để nối các phần khác nhau của một lưu đồ lại với nhau. Bên trong điểm nối, ta đặt một ký hiệu để biết sự liên hệ giữa các điểm nối. f) Ðiểm nối sang trang (off-page connector) Tương tự như điểm nối, nhưng điểm nối sang trang được dùng khi lưu đồ quá lớn, phải vẽ trên nhiều trang. Bên trong điểm nối sang trang ta cũng đặt một ký hiệu để biết được sự liên hệ giữa điểm nối của các trang. Ở trên chỉ là các ký hiệu cơ bản và thường được dùng nhất. Trong thực tế, lưu đồ còn có nhiều ký hiệu khác nhưng thường chỉ dùng trong những lưu đồ lớn và phức tạp. Ðối với các thuật toán trong cuốn sách này, ta chỉ cần sử dụng các ký hiệu trên là đủ. 2.4.3 Mã giả Tuy sơ đồ khối thể hiện rõ quá trình xử lý và sự phân cấp các trường hợp của thuật toán nhưng lại cồng kềnh. Ðể mô tả một thuật toán nhỏ ta phải dùng một không gian rất lớn. Hơn nữa, lưu đồ chỉ phân biệt hai thao tác là rẽ nhánh (chọn lựa có điều kiện) và xử lý mà trong thực tế, các thuật toán còn có thêm các thao tác lặp. Khi thể hiện thuật toán bằng mã giả, ta sẽ vay mượn các cú pháp của một ngôn ngữ lập trình nào đó để thể hiện thuật toán. Tất nhiên, mọi ngôn ngữ lập trình đều có những thao tác cơ bản là xử lý, rẽ nhánh và lặp. Dùng mã giả vừa tận dụng được các khái niệm trong ngôn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt nội dung thuật toán. Tất nhiên là trong mã giả ta vẫn dùng một phần ngôn ngữ tự nhiên. Một khi đã vay mượn cú pháp và khái niệm của ngôn ngữ lập trình thì chắc chắn mã giả sẽ bị phụ thuộc vào ngôn ngữ lập trình đó. Ví dụ: Một đoạn mã giả của thuật toán giải phương trình bậc hai if Delta > 0 then begin x1=(-b-sqrt(delta))/(2*a) x2=(-b+sqrt(delta))/(2*a) xuất kết quả : phương trình có hai nghiệm là x1 và x2 end Bài giảng lập trình nhúng 21
  26. Chương II: Lý thuyết thiết kế hệ thống nhúng else if delta = 0 then xuất kết quả : phương trình có nghiệm kép là -b/(2*a) else {trường hợp delta < 0 }xuất kết quả : phương trình vô nghiệm Bài giảng lập trình nhúng 22
  27. Chương III: Cấu trúc phần cứng Chương 3: CẤU TRÚC PHẦN CỨNG 3.1 Cấu trúc tổng quát của hệ thống nhúng 3.1.1 Kiến trúc cơ bản Kiến trúc cơ bản của hệ thống nhúng được miêu tả ở hình 3.1, như vậy một hệ thống đầy đủ về cơ bản có 3 thành phần: Hình 3.1 Kiến trúc cơ bản của một hệ thống nhúng 1. Chương trình ứng dụng: là các chương trình chạy trên nền hệ thống nhúng. Người sử dụng tác động trực tiếp trên các phần mềm này. 2. Hệ điều hành: Hệ điều hành giúp cho việc phát triển phần mềm và phần cứng có thể tách biệt trên 2 công nghệ không cần liên quan đến nhau nhưng vẫn có thể kết hợp để có một sản phẩm tốt nhất. Cũng như máy tính hệ điều hành giúp người khác thác hệ thống được hiệu quả và dễ dàng hơn, hệ thống nhúng có hệ điều hành thường linh hoạt và mềm dẻo hơn. 3. Phần cứng: Đây là thành phần cốt lõi không thể thiếu, thành phần phần cứng quan trọng nhất là CPU, các thành phần khác có thể tùy biến theo từng ứng dụng cụ thể. 3.1.2 Cấu trúc phần cứng Cấu trúc tổng quát thông dụng nhất của một vi xử lý/vi điều khiển nhúng được đưa ra ở hình 3.2. Hình 3.2 Cấu trúc thông dụng của một VXL/VĐK nhúng Bài giảng lập trình nhúng 23
  28. Chương III: Cấu trúc phần cứng VXL/VĐK nhúng là một chủng loại rất điển hình và đang được sử dụng rất phổ biến hiện này. Chúng được ra đời và sử dụng theo sự phát triển của các Chip xử lý ứng dụng cho máy tính. Vì đối tượng ứng dụng là các thiết bị nhúng nên cấu trúc cũng được thay đổi theo để đáp ứng các ứng dụng. Hiện nay chúng ta có thể thấy các họ vixử lý điều khiển của rất nhiều các nhà chế tạo cung cấp như, Intel, Atmel, Motorola, Infineon. Về cấu trúc, chúng cũng tương tự như các Chíp xử lý phát triển cho PC nhưng ở mức độ đơn giản hơn nhiều về công năng và tài nguyên. Phổ biến vẫn là các Chip có độ rộng bus dữ liệu là 8bit, 16bit, 32bit. Về bản chất cấu trúc, Chip vi điều khiển là chip vi xử lý được tích hợp thêm các ngoại vi. Các ngoại vi thường là các khối chức năng ngoại vi thông dụng như bộ định thời gian, bộ đếm, bộ chuyển đổi A/D, giao diện song song, nối tiếp Mức độ tích hợp ngoại vi cũng khác nhau tuỳ thuộc vào mục đích ứng dụng sẽ có thể tìm được Chip phù hợp. Thực tế với các ứng dụng yêu cầu độ tích hợp cao thì sẽ sử dụng giải pháp tích hợp trên chip, nếu không thì hầu hết các Chip đều cung cấp giải pháp để mở rộng ngoại vi đáp ứng cho một số lượng ứng dụng rộng và mềm dẻo. 3.2 Một số nền tảng phần cứng thông dụng Hiện trên thị trường có rất nhiều nhà sản xuất phát triển nhiều loại chip VXL/VĐK nhúng khác nhau, mỗi loại đều có những tính năng và ưu việt riêng. Trong thực tế mỗi dòng chip ra đời được thiết kế chuyên biệt cho một phân khúc ứng dụng nào đấy, vì thế không có một nguyên tắc chung hay một loại VXL/VĐK chung cho mọi bài toán. Tuỳ vào khả năng và nhiệm vụ cụ thể của hệ thống mà ta chọn lựa loại chip phù hợp. Trong một số bài toán và một số dòng chip thì sự phân biệt giữa các chip là không rõ dàng, nghĩa là có thể việc sử dụng các chip khác nhau nhưng mạng lại hiệu qua như nhau. Ngoài vi xử lý của máy tính, ta có thể phân loại ra hai dòng chip nhúng là vi xử lý nhúng và vi điều khiển nhúng. Vi xử lý nhúng được sử dụng rộng rãi với thị phần lớn nhất hiện nay là ARM, còn vi điều khiển thì có nhiều loại như AVR, PIC, 8051, Tuy nhiên trong phạm vi bài giảng này chi trình bày tóm lược một số loại chip là PIC, 8051, ARM, 3.2.1 Vi điều khiển Atmega8 3.2.1.1 Đặc điểm Vi điều khiển Atmega8 của hãng ATMEL là một loại vi điều khiển AVR mới với kiến trúc rất phức tạp. Atmega 8 là bộ vi điều khiển RISC 8 bit tiêu thụ năng lượng nhưng đạt hiệu suất rất cao, dựa trên kiến trúc RISC AVR. Bằng việc thực hiện các lệnh trong một chu kỳ xung nhịp, Atmega8 đạt được tốc độ xử lý dữ liệu lên đến 1 triệu lệnh/giâyở tần số 1MHz. Atmega8 còn cho phép người thiết kế hệ thống tối ưu hoá mức độ tiêu thụ năng lượng mà vẫn đảm bảo tốc độ xử lý. Atmega 8 đã tích hợp đầy đủ các tính năng như bộ chuyển đổi ADC 10bit, bộ so sánh, bộ truyền nhận nối tiếp, bộ định thời, bộ đếm thời gian thực, bộ điều chế độ rộng xung Do đó ta phải nghiên cứu và khai thác triệt để các tính năng này để ứng dụng hiệu quả vào những mạch trong thực tế. Atmega8 sử dụng kiến trúc RISC (Reduced Instruction Set Computer) AVR. Bài giảng lập trình nhúng 24
  29. Chương III: Cấu trúc phần cứng Atmega8 với kiến trúc RISC có chỉ tiêu chất lượng cao và tiêu thụ năng lượng ít: - 130 lệnh hầu hết được thực hiện trong một chu kỳ xung nhịp. - 32 thanh ghi làm việc đa năng. - Tốc độ xử lý lệnh lên đến 16 triệu lệnh/giây ở tần số 16MHz. Bộ nhớ dữ liệu và bộ nhớ chương trình không tự mất dữ liệu: - 8K byte bộ nhớ Flash lập trình được ngay trên hệ thống, có thể nạp xoá 10000 lần. - 512 byte bộ nhớ EEFROM lập trình được ngay trên hệ thống, có thể ghi xóa 100000 lần. - 1K byte bộ nhớ SRAM. - Có thể giao tiếp với 8K byte bộ nhớ ngoài. - Khóa bảo mật phần mềm lập trình được. - Giao diện nối tiếp SPI để lập trình ngay trên hệ thống. Các tính năng ngoại vi: - Hai bộ đếm/ bộ định thời 8 bit với chế độ so sánh và chia tần số tách biệt. - Một bộ định thời 16 bit với chế độ so sánh, chia tần số tách biệt và chế độ bắt mẫu (Capture Mode). - Bộ đếm thời gian thực (RTC) với bộ dao động tách biệt. - Bộ điều chế độ rộng xung PWM 8 bit. - Bộ biến đổi ADC bên trong 8 kênh 10 bit. - 2 bộ USART nối tiếp lập trình được. - Bộ định thời Watchdog lập trình được với bộ dao động trên chip. - Một bộ so sánh Analog. Các tính năng vi điều khiển đặc biệt: - Có mạch power - on reset và có thể reset bằng phần mềm. - Các nguồn ngắt ngoài và trong. - Có 5chế độ ngủ: nghỉ (Idle). Tiết kiệm năng lượng (power save) và power down, ADC Noise Reduction, Standby. - Tần số làm việc có thể thay đổi được bằng phần mềm. Vào ra và các cách đóng vỏ - 23 đường vào ra lập trình được. - 32 chân dán kiểu vỏ vuông (TQFP) Điện thế làm việc: - VCC = 2,7V đến 5,5V đối với Atmega8L. Bài giảng lập trình nhúng 25
  30. Chương III: Cấu trúc phần cứng - VCC = 4,5V đến 5,5V đối với Atmega8. Vùng tốc độ làm việc: - 0 đến 8 MHz đối với Atmega8L. - 0 đến 16 MHz đối với Atmega8. 3.2.1.2 Sơ đồ chân Atmega8 Hình 3.3 Sơ đồ chân Atmega8 3.2.1.3 Sơ đồ khối của Atmega8 Bài giảng lập trình nhúng 26
  31. Chương III: Cấu trúc phần cứng Hình 3.4 Sơ đồ khối vi điều khiển AVR Atmega8 Bài giảng lập trình nhúng 27
  32. Chương III: Cấu trúc phần cứng 3.2.1.4 Mô tả chức năng các chân Atmega8 VCC: Điện áp nguồn nuôi. GND: Đất. Port B (PB0 PB7)- 6 Port B là port I/O 8 bit với điện trở kéo lên ở bên trong, cung cấp dòng điện 40mA có thể điều khiển trực tiếp led đơn. - Khi các chân Port B là các lối vào được đặt xuống mức thấp từ bên ngoài, chúng sẽ là nguồn dòng nếu như các điện trở nối lên nguồn dương được kích hoạt. Các chân này sẽ ở trạng thái tổng trở cao khi tín hiệu Reset ở mức tích cực hoặc ngay cả khi không có dao động. Port C (PC0 PC6) - Port C là port I/O 8 bit với điện trở kéo lên ở bên trong, cung cấp dòng điện 40mA có thể điều khiển trực tiếp led đơn. - Khi các chân Port C là các lối vào được đặt xuống mức thấp từ bên ngoài, chúng sẽ là nguồn dòng nếu như các điện trở nối lên nguồn dương được kích hoạt. Các chân này sẽ ở trạng thái tổng trở cao khi tín hiệu Reset ở mức tích cực hoặc ngay cả khi không có dao động. - Port C cũng đóng vai trò như 8 đường địa chỉ cao từ A8 đến A15 khi kết nối bộ nhớ SRAM bên ngoài. Port D (PD0 PD7) - Port D là port I/O 8 bit với điện trở kéo lên ở bên trong, cung cấp dòng điện 40mA có thể điều khiển trực tiếp LED đơn. - Khi các chân Port D là các lối vào được đặt xuống mức thấp từ bên ngoài, chúng sẽ là nguồn dòng nếu như các điện trở nối lên nguồn dương được kích hoạt. Các chân này sẽ ở trạng thái tổng trở cao khi tín hiệu Reset ở mức tích cực hoặc ngay cả khi không có dao động. Reset: Ngõ vào được đặt lại. ATmega8 sẽ được đặt lại khi chân này ở mức thấp trong hơn 50ns hoặc ngay cả khi không có tín hiệu xung clock. Các xung ngắn hơn không tạo ra tín hiệu đặt lại. AVCC: Cung cấp nguồn cho Port C và bộ chuyển đổi ADC hoạt động. Ngay khi không sử dụng bộ chuyển đổi ADC thì chân AVCC vẫn phải đươc kết nối tới nguồn VCC. AREF: Đây là chân điều chỉnh điện áp tham chiếu cho chuyển đổi A/D. XTAL1: Ngõ vào bộ khuếch đại đảo và ngõ vào mạch tạo xung nhịp bên ngoài. XTAL2: Ngõ ra bộ khuếch đại đảo. Bộ tạo dao động thạch anh : - XTAL1 và XTAL2 lần lượt là lối vào và lối ra của một bộ khuếch đại đảo, bộ khuếch đại này được bố trí để làm bộ tạo dao động trên chip Bài giảng lập trình nhúng 28
  33. Chương III: Cấu trúc phần cứng - Để điều khiển được bộ Vi Điều Khiển từ một nguồn xung nhịp bên ngoài, chân XTAL2 để không, chân XTAL1 được nối với tín hiệu dao động bên ngoài. 3.2.2 Kit Arduino Uno R3 Hiện dòng mạch Arduino UNO đã phát triển tới thế hệ thứ 3 (R3). Hình 3.5 Kit Arduino Uno R3 Một vài thông số của Arduino UNO R3 Vi điều khiển ATmega328 (họ 8bit) Điện áp hoạt động 5V – DC (chỉ được cấp qua cổng USB) Tần số hoạt động 16 MHz Dòng tiêu thụ 30mA Điện áp vào khuyên dùng 7-12V – DC Điện áp vào giới hạn 6-20V – DC Số chân Digital I/O 14 (6 chân PWM) Số chân Analog 6 (độ phân giải 10bit) Dòng tối đa trên mỗi chân I/O 30 mA Dòng ra tối đa (5V) 500 mA Dòng ra tối đa (3.3V) 50 mA Bài giảng lập trình nhúng 29
  34. Chương III: Cấu trúc phần cứng Bộ nhớ flash 32 KB (ATmega328) với 0.5KB dùng bởi bootloader SRAM 2 KB (ATmega328) EEPROM 1 KB (ATmega328) Vi điều khiển Arduino UNO có thể sử dụng 3 vi điều khiển họ 8bit AVR là ATmega8, ATmega168, ATmega328. Bộ não này có thể xử lí những tác vụ đơn giản như điều khiển đèn LED nhấp nháy, xử lí tín hiệu cho xe điều khiển từ xa, làm một trạm đo nhiệt độ - độ ẩm và hiển thị lên màn hình LCD, hay những ứng dụng nhúng khác. Thiết kế tiêu chuẩn của Arduino UNO sử dụng vi điều khiển ATmega328. Tuy nhiên nếu yêu cầu phần cứng không cao có thể sử dụng các loại vi điều khiển khác có chức năng tương đương nhưng rẻ hơn như ATmega8 (bộ nhớ flash 8KB) hoặc ATmega168 (bộ nhớ flash 16KB). Năng lượng Arduino UNO có thể được cấp nguồn 5V thông qua cổng USB hoặc cấp nguồn ngoài với điện áp khuyên dùng là 7-12V DC và giới hạn là 6-20V. Thường thì cấp nguồn bằng pin vuông 9V là hợp lí nhất nếu không có sẵn nguồn từ cổng USB. Nếu cấp nguồn vượt quá ngưỡng giới hạn trên, sẽ làm hỏng Arduino UNO. Các chân năng lượng GND (Ground): cực âm của nguồn điện cấp cho Arduino UNO. Khi dùng các thiết bị sử dụng những nguồn điện riêng biệt thì những chân này phải được nối với nhau. 5V: cấp điện áp 5V đầu ra. Dòng tối đa cho phép ở chân này là 500mA. 3.3V: cấp điện áp 3.3V đầu ra. Dòng tối đa cho phép ở chân này là 50mA. Vin (Voltage Input): để cấp nguồn ngoài cho Arduino UNO, nối cực dương của nguồn với chân này và cực âm của nguồn với chân GND. IOREF: điện áp hoạt động của vi điều khiển trên Arduino UNO có thể được đo ở chân này. Và dĩ nhiên nó luôn là 5V. Mặc dù vậy ta không được lấy nguồn 5V từ chân này để sử dụng bởi chức năng của nó không phải là cấp nguồn. RESET: việc nhấn nút Reset trên board để reset vi điều khiển tương đương với việc chân RESET được nối với GND qua 1 điện trở 10KΩ. Lưu ý: Arduino UNO không có bảo vệ cắm ngược nguồn vào. Do đó phải hết sức cẩn thận, kiểm tra các cực âm – dương của nguồn trước khi cấp cho Arduino UNO. Các chân 3.3V và 5V trên Arduino là các chân dùng để cấp nguồn ra cho các thiết bị khác, không phải là các chân cấp nguồn vào. Việc cấp nguồn sai vị trí có thể làm hỏng board. Bài giảng lập trình nhúng 30
  35. Chương III: Cấu trúc phần cứng Cấp nguồn ngoài không qua cổng USB cho Arduino UNO với điện áp dưới 6V có thể làm hỏng board. Cấp điện áp trên 13V vào chân RESET trên board có thể làm hỏng vi điều khiển ATmega328. Cường độ dòng điện vào/ra ở tất cả các chân Digital và Analog của Arduino UNO nếu vượt quá 200mA sẽ làm hỏng vi điều khiển. Cấp điệp áp trên 5.5V vào các chân Digital hoặc Analog của Arduino UNO sẽ làm hỏng vi điều khiển. Cường độ dòng điện qua một chân Digital hoặc Analog bất kì của Arduino UNO vượt quá 40mA sẽ làm hỏng vi điều khiển. Do đó nếu không dùng để truyền nhận dữ liệu, phải mắc một điện trở hạn dòng. Bộ nhớ Vi điều khiển Atmega328 tiêu chuẩn cung cấp cho người dùng: 32KB bộ nhớ Flash: những đoạn lệnh lập trình sẽ được lưu trữ trong bộ nhớ Flash của vi điều khiển. Thường thì sẽ có khoảng vài KB trong số này sẽ được dùng cho bootloader nhưng với các ứng dụng nhỏ hiếm khi nào cần quá 20KB bộ nhớ này. 2KB cho SRAM (Static Random Access Memory): giá trị các biến khai báo khi lập trình sẽ lưu ở đây. Khai báo càng nhiều biến thì càng cần nhiều bộ nhớ RAM. Khi mất điện, dữ liệu trên SRAM sẽ bị mất. 1KB cho EEPROM (Electrically Eraseble Programmable Read Only Memory): đây giống như một chiếc ổ cứng mini – nơi có thể đọc và ghi dữ liệu của mình vào đây mà không bị mất dữ liệu khi cúp điện giống như dữ liệu trên SRAM. Các cổng vào/ra Arduino UNO có 14 chân digital dùng để đọc hoặc xuất tín hiệu. Chúng chỉ có 2 mức điện áp là 0V và 5V với dòng vào/ra tối đa trên mỗi chân là 40mA. Ở mỗi chân đều có các điện trở pull-up từ được cài đặt ngay trong vi điều khiển ATmega328 (mặc định thì các điện trở này không được kết nối). Một số chân digital có các chức năng đặc biệt như sau: 2 chân Serial: 0 (RX) và 1 (TX): dùng để gửi (transmit – TX) và nhận (receive – RX) dữ liệu TTL Serial. Arduino Uno có thể giao tiếp với thiết bị khác thông qua 2 chân này. Nếu không cần giao tiếp Serial, không nên sử dụng 2 chân này nếu không cần thiết Chân PWM (~): 3, 5, 6, 9, 10, và 11: cho phép xuất ra xung PWM với độ phân giải 8bit (giá trị từ 0 → 28-1 tương ứng với 0V → 5V) bằng hàm analogWrite(). Nói một cách đơn giản, có thể điều chỉnh được điện áp ra ở chân này từ mức 0V đến 5V thay vì chỉ cố định ở mức 0V và 5V như những chân khác. Chân giao tiếp SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Ngoài các chức năng thông thường, 4 chân này còn dùng để truyền phát dữ liệu bằng giao thức SPI với các thiết bị khác. Bài giảng lập trình nhúng 31
  36. Chương III: Cấu trúc phần cứng LED 13: trên Arduino UNO có 1 đèn led màu cam (kí hiệu chữ L). Khi bấm nút Reset, sẽ thấy đèn này nhấp nháy để báo hiệu. Nó được nối với chân số 13. Khi chân này được người dùng sử dụng, LED sẽ sáng. Arduino UNO có 6 chân analog (A0 → A5) cung cấp độ phân giải tín hiệu 10bit (0 → 210-1) để đọc giá trị điện áp trong khoảng 0V → 5V. Với chân AREF trên board, có thể để đưa vào điện áp tham chiếu khi sử dụng các chân analog. Tức là nếu cấp điện áp 2.5V vào chân này thì có thể dùng các chân analog để đo điện áp trong khoảng từ 0V → 2.5V với độ phân giải vẫn là 10bit. Đặc biệt, Arduino UNO có 2 chân A4 (SDA) và A5 (SCL) hỗ trợ giao tiếp I2C/TWI với các thiết bị khác. Sơ đồ khối các chân vào ra trên Arduino Uno Hình 3.6 Sơ đồ khối các chân vào ra trên Kit Arduino Uno Lập trình cho Arduino Các thiết bị dựa trên nền tảng Arduino được lập trình bằng ngôn riêng. Ngôn ngữ này dựa trên ngôn ngữ Wiring được viết cho phần cứng nói chung. Và Wiring lại là một biến thể của C/C++. Một số người gọi nó là Wiring, một số khác thì gọi là C hay C/C++. Riêng đội ngũ phát triển Arduino gọi là “ngôn ngữ Arduino”. Ngôn ngữ Arduino bắt nguồn từ C/C++ phổ biến hiện nay do đó rất dễ học, dễ hiểu. Để lập trình cũng như gửi lệnh và nhận tín hiệu từ mạch Arduino, nhóm phát triển dự án này đã cũng cấp đến cho người dùng một môi trường lập trình Arduino được gọi là Arduino IDE (Intergrated Development Environment) như hình dưới đây. Bài giảng lập trình nhúng 32
  37. Chương III: Cấu trúc phần cứng Hình 3.7 Arduino IDE 3.2.3 Vi điều khiển MSP430G2553 Các dòng vi điều khiển msp430 này do hãng TI ( Texas Instruments) sản xuất, ngoài ra thì TI còn sản xuất và cung cấp nhiều linh kiện điện tử và các module khác. Vi điều khiển( Micro controller unit – MCU ) là đơn vị xử lý nhỏ, nó được tích hợp toàn bộ các bộ nhớ như ROM , RAM , các port truy xuất , giao tiếp ngoại vi trực tiếp trên 1 con chip hết sức nhỏ gọn. Được thiết kế dựa trên cấu trúc VON-NEUMAN , đặc điểm của cấu trúc này là chỉ có duy nhất 1 bus giữa CPU và bộ nhớ (data và chương trình) , do đó mà chúng phải có độ rộng bit tương tự nhau. MSP430 có một số phiênbản như: MSP430x1xx, MSP430x2xx, MSP430x3xx, MSP430x4xx, MSP430x5xx. Dưới đây là những đặc điểm tổng quát của họ vi điều khiển MSP430: + Cấu trúc sử dụng nguồn thấp giúp kéo dài tuổi thọ của Pin -Duy trì 0.1µA dòng nuôi RAM. -Chỉ 0.8µA real-time clock. -250 µA/ MIPS. + Bộ tương tự hiệu suất cao cho các phép đo chính xác -12 bit hoặc 10 bit ADC-200 kskp, cảm biến nhiệt độ, Vref , -12 bit DAC. -Bộ giám sát điện áp nguồn. Bài giảng lập trình nhúng 33
  38. Chương III: Cấu trúc phần cứng + 16 bit RISC CPU cho phép được nhiều ứng dụng, thể hiện một phần ở kích thước Code lập trình. -Thanh ghi lớn nên loại trừ được trường hợp tắt nghẽn tập tin khi đang làm việc. -Thiết kế nhỏ gọn làm giảm lượng tiêu thụ điện và giảm giá thành. -Tối ưu hóa cho những chương trình ngôn ngữ bậc cao như C, C++ -Có 7 chế độ định địa chỉ. -Khả năng ngắt theo véc tơ lớn. + Trong lập trình cho bộ nhớ Flash cho phép thay đổi Code một cách linh hoạt, phạm vi rộng, bộ nhớ Flash còn có thể lưu lại như nhật ký của dữ liệu. Sơ đồ chân : Chip MSP430 có kích thước nhỏ gọn , chỉ với 20 chân đối với kiểu chân DIP. Bao gồm 2 port I/O (hay GPIO general purprose input/ output : cổng nhập xuất chung). Hình 3.8 Sơ đồ chân vi điều khiển MSP430G2553 Ta thấy rằng mỗi port đều có 8 chân. Port 1 : có 8 chân từ P1.0 đến P1.7 tương ứng với các chân từ 2-7 và 14 , 15. Port 2 : cũng gồm có 8 chân P2.0 – P2.7 ứng với các chân 8 – 13 , 18,19. Ngoài chức năng I/O thì trên mỗi pin của các port đều là những chân đa chức năng. Sơ đồ khối của vi điều khiển MSP430G2553 Bài giảng lập trình nhúng 34
  39. Chương III: Cấu trúc phần cứng Hình 3.9 Sơ đồ khối vi điều khiển MSP430G2553 - Chân số 1 là chân cấp nguồn Vcc( ký hiệu trên chip là DVcc ) , ở đây nguồn cho chip chỉ được cấp ở mức 3,3V, nếu cấp nguốn cao quá mức này thì chip có thể hoạt động sai hay cháy chip. -Chân 20 là chân nối cực âm (0V). -Chân reset : Chính là chân số 16 RST , chân này có dấu gạch ngang trên có nghĩa là chân này tích cực ở mức thấp . Mục đích của việc reset là nhằm cho chương trình chạy lại từ đầu . -Mạch dao động : Cũng giống như những dòng vi điều khiển khác thì Msp430 cũng hỗ trợ người dùng thạch anh ngoài ( external crystal ), nhưng thạch anh ngoại vi cho phép chỉ có thể lên tới 32,768 kHz mà thôi, và tín hiệu này được mắc trên 2 chân 18 và 19. Nhưng msp430 lại hỗ trợ thạch anh nội có thể lên đến 16Mhz, tùy vào cách khai báo trong lập trình. Và mặc định của chip là thạch anh nội. Như vậy thì chúng ta không cần thiết phải sử dụng mạch dao động ngoại cho chip giống như những dòng khác. - Port I/O : Port 1 : có 8 chân từ P1.0 đến P1.7 tương ứng với các chân từ 2-7 và 14 , 15. Port 2 : cũng gồm có 8 chân P2.0 – P2.7 ứng với các chân 8 – 13 , 18,19. Trong chế độ nhập (input) thì cả 2 port đều có 1 mạch điều khiển điện trở kéo dương – gọi là PULL UP nhưng giá trị của điện trở này rất lớn khoảng 47K nên gọi là WEAK PULL UP RESISTAN. Bài giảng lập trình nhúng 35
  40. Chương III: Cấu trúc phần cứng 3.2.4 Kit MSP430 Launchpad Msp430 là dòng value line , power low, và low – cost . Chính vì vậy mà TI đã cung cấp cho người dùng 1 mạch nạp code + debug chỉ trên 1 mạch nhỏ gọn. Đó là kit MSP430 Launchpad, trong kit còn có hỗ trợ: -1 mạch nạp code có cả debug -1 dây cáp USB tốt để kết nối kit với máy tính. -1 chip thạch anh 32,768kHz -1 chip Msp430G2553 -1 chip Msp430G2453 -1 header female. Hình 3.10 Kit MSP430 Launchpad Một kit LaunchPad gồm hai thành phần, với GND được phủ chung: - Nửa trên: Là phần mạch nạp theo chuẩn spy-bi-wire Jtag (2 dây), kết hợp với chuyển đổi giao tiếp UART với máy tính. Trên cùng là đầu USBmini để nối với máy tính, phía dưới là hàng Header để nối ra đối tượng cần giao tiếp, bao gồm các chân: · TXD, RXD: phục vụ giao tiếp UART với máy tính. · RST, TEST: phục vụ nạp và debug (sửa lỗi) theo chuẩn spy-bi-wire Jtag. · VCC: cấp nguồn 3V3 cho đối tượng (thường là nửa dưới LaunchPad). - Nửa dưới: là một mạch phát triển MSP430 đơn giản, bao gồm: · Socket cắm MSP430 (thường gắn sẵn chip MSP430G2553), Pad hàn thạch anh, Nút nhấn Reset chip. · Nút nhấn gắn vào P1.3, hai Led hiển thị có jumper để gắn vào P1.0 và P1.6. Hai hàng header để kết nối hai hàng chân của chip ra ngoài, một hàng header nguồnGND-GND-VCC để lấy nguồn 3V3 trên LaunchPad. Bài giảng lập trình nhúng 36
  41. Chương III: Cấu trúc phần cứng Sơ đồ khối các chân vào ra trên Kit MSP430 Launchpad Hình 3.11 Sơ đồ các chân vào ra trên Kit MSP430 Launchpad Lập trình cho MSP430 Launchpad Kit MSP430 Launchpad được lập trình trên nền tảng ngôn ngữ Arduino. Để lập trình cũng như gửi lệnh và nhận tín hiệu từ kit, nhóm phát triển dự án này đã cũng cấp đến cho người dùng một môi trường lập trình ngôn ngữ Arduino trên kit MSP430 Launchpad được gọi là Energia IDE (Intergrated Development Environment) như hình dưới đây. Hình 3.12 Energia IDE Bài giảng lập trình nhúng 37
  42. Chương III: Cấu trúc phần cứng 3.2.4 Vi điều khiển PIC18F2550 Họ vi điều khiển PIC18F2455/2550/4455/4550 là họ vi điều khiển tiên tiến của MICROCHIP, đặc biệt họ này có tích hợp cổng USB 2.0, ADC 10 bit và tích hợp nhiều công cụ khác. Mạnh, mềm dẻo là từ đánh giá ngắn gọn về họ vi điều khiển này. Các khối tích hợp của họ vi điều khiển PIC18F và các đặc điểm của các khối tích hợp như sau: Các đặc điểm cổng USB: USB V2.0 Tốc độ thấp (1.5 Mb/s) và tốc độ toàn phần (12Mb/s) Hỗ trợ tới 32 điểm cuối RAM 1 kByte cho khối USB Mạch thu phát USB trên chip cùng với mạch ổn áp 3.3V Cổng song song streaming (SPP) cho truyền streaming USB Hỗ trợ cả 4 chế độ truyền: - Truyền điều khiển (Control transfer) - Truyền ngắt (Interrupt transfer) - Truyền đồng bộ (Isochronous transfer) - Truyền khối (Bulk transfer) Các chế độ quản lý năng lượng : có nhiều chế độ quản lý năng lượng để giảm năng lượng tiêu thụ tối đa, đặc biệt có ý nghĩa cho các ứng dụng sử dụng pin. Hoạt động bình thường (Run): CPU bật, ngoại vi bật Nghỉ (Idle): CPU tắt, ngoại vi bật, tiêu thụ dòng tiêu biểu 5.8A Ngủ (Sleep): CPU tắt, ngoại vi tắt, tiêu thụ dòng tiêu biểu 0.1A Dao động timer1: tiêu thụ dòng tiêu biểu 1.1A , 32kHz, 2V. Watchdog timer: tiêu thụ dòng tiêu biểu 2.1A Khởi động dao động 2 tốc độ Cấu trúc dao động mềm dẻo: Bốn chế độ tinh thể bao gồm PLL độ chính xác cao cho USB Hai chế độ xung clock ngoài lên đến 48 MHz Khối dao động nội - 8 tần số chọn được bởi người sử dụng, từ 31kHz đến 8 Mhz - Tinh chỉnh bởi người dùng để bổ chính độ trôi tần số Bài giảng lập trình nhúng 38
  43. Chương III: Cấu trúc phần cứng Dao động thứ cấp dùng timer1 32kHz Tùy chọn dao động đôi cho phép CPU và USB hoạt động 2 tần số xung nhịp khác nhau Khối theo dõi an toàn xung nhịp - Cho phép shutdown an toàn khi tắt xung nhịp - hay vi điều khiển sẽ tiếp tục hoạt động với tần số xung nhịp thấp hơn Các đặc điểm ngoại vi: Dòng vào/ra (sink/source) cao 25mA/25mA Ba ngắt ngoài Bốn khối timer (timer0 đến timer3) Có tới 2 khối CCP (Capture/Compare/PWM) - Capture 16 bit cực đại, độ phân giải 6.25 ns (T /16 CY ) - So sánh 16 bit cực đại, độ phân giải 100 ns (TCY ) - PWM có lối ra với độ giải từ 1 đến 10 bit Khối CCP nâng cao ECCP (Enhanced Capture/Compare/PWM) - Nhiều chế độ lối ra - Có thể chọn cực tính - Thời gian chết lập trình được - Tự động tắt và tự động khởi động Khối USART nâng cao - Hỗ trợ bus LIN Cổng truyền nối tiếp đồng bộ chủ MSSP (Master Synchronous Serial Port) ADC 10 bit, 13 lối vào, thời gian thu thập dữ liệu lập trình được 2 bộ so sánh tương tự với đa hợp lối vào Các đặc điểm của vi điều khiển Cấu trúc tối ưu biên dịch C với tập lệnh mở rộng tùy chọn Bộ nhớ chương trình flash nâng cao cho phép 100.000 lần xóa/ghi Bộ nhớ dữ liệu EEPROM cho phép 1.000.000 lần xóa/ghi Lưu trữ dữ liệu trong bộ nhớ flash/EEPROM hơn 40 năm Ngắt nhiều mức ưu tiên Watchdog timer mở rộng, chu kỳ khả trình từ 41 ms đến 131 s Bài giảng lập trình nhúng 39
  44. Chương III: Cấu trúc phần cứng Bảo vệ mã lập trình Nguồn nuôi đơn 5V cho lập trình nối tiếp trên mạch qua 2 chân Mạch gỡ lỗi qua 2 chân Dải điện áp hoạt động rộng (2.0V đến 5.5V) Sơ đồ chân vi điều khiển PIC18F2550 Hình 3.13 Sơ đồ chân vi điều khiển PIC18F2550 Sơ đồ khối vi điều khiển PIC18F2550 Hình 3.14 Sơ đồ khối vi điều khiển PIC18F2550 3.2.4 Kit PIC18F2550 Pinguino Kit PIC18F2550 Pinguino được phát triển trên nền tảng vi điều khiển PIC18F2550. Trên Kit có 18 chân Digital I/O chia sẽ với 5 chân ngõ vào Analog. Ngoài ra một số chân còn có những chức năng đặc biệt như: 2 kênh ngõ ra fast PWM (3000Hz), giao tiếp I2C, giao Bài giảng lập trình nhúng 40
  45. Chương III: Cấu trúc phần cứng tiếp nối tiếp tốc độ lên đến 57600 bauds, USB native, đọc ghi EEPROM, truy xuất ngắt Kit PIC18F2550 Pinguino hỗ trợ 2 nút nhấn ( 1 dùng cho Reset, 1 dùng cho Run), trong một số phiên bản bootloader không dùng đến nút Run, 2 led ( 1 led báo nguồn, 1 led báo trạng thái Run). Ngoài ra Kit còn hỗ trợ khối nguồn ổn áp nên có thể sử dụng nguồn qua USB hoặc dùng nguồn ngoài (7-12VDC). Hình 3.15 Kit PIC18F2550 Pinguino Sơ đồ khối các chân vào ra trên Kit PIC18F2550 Pinguino Hình 3.16 Sơ đồ khối các chân vào ra trên Kit PIC18F2550 Pinguino Bài giảng lập trình nhúng 41
  46. Chương III: Cấu trúc phần cứng Lập trình cho PIC18F2550 Pinguino Kit PIC18F2550 Pinguino được lập trình trên nền tảng ngôn ngữ Arduino. Để lập trình cũng như gửi lệnh và nhận tín hiệu từ kit, nhóm phát triển dự án này đã cũng cấp đến cho người dùng một môi trường lập trình ngôn ngữ Arduino trên kit PIC18F2550 Pinguino được gọi là Pinguino IDE (Intergrated Development Environment) như hình dưới đây. Hình 3.17 Pinguino IDE Bài giảng lập trình nhúng 42
  47. Chương IV: Phần mềm nhúng Chương 4: PHẦN MỀM NHÚNG 4.1. Đặc điểm phần mềm nhúng Nói một cách đơn giản, phần mềm nhúng là phần mềm dành cho tất cả những thiết bị không liên quan gì đến máy tính, chẳng hạn như thiết bị điều khiển, định hướng cho ô tô, điện thoại di động, ví tiền điện tử, đồ gia dụng (ti vi, tủ lạnh, máy giặt, điều hòa ). Như ta đã biết, số chip vi xử lý dùng trong các máy tính, mạng nội bộ và Internet chỉ chiếm hơn 1% tổng số chip vi xử lý trên thế giới. Số còn lại thuộc về các hệ thống nhúng. Theo số liệu của Business Communications Company, tổng thị trường phần mềm nhúng thế giới năm 2004 đạt khoảng 46 tỷ USD. Đến năm 2009, con số này là 88 tỷ USD. Nhật Bản hiện nay được đánh giá là một trong những thị trường phần mềm nhúng hàng đầu thế giới. Theo thống kê của JISA (Hiệp hội Dịch vụ CNTT Nhật Bản), phần mềm nhúng hiện nay chiếm tới 40% thị phần phần mềm Nhật Bản, với các sản phẩm rất đa dạng: lò vi ba, máy photocopy, máy in laser, máy FAX, các bảng quảng cáo sử dụng hệ thống đèn LED, màn hình tinh thể lỏng Năm 2004, thị trường phần mềm nhúng của Nhật Bản đạt khoảng 20 tỷ USD với 150.000 nhân viên. Đây được coi là thị trường đầy hứa hẹn với các đối tác chuyên sản xuất phần mềm nhúng như Trung Quốc, Indonesia, Nga, Ireland, Israel và cả Việt Nam. Đặc điểm phần mềm nhúng: • Hướng chức năng hoá đặc thù • Hạn chế về tài nguyên bộ nhớ • Yêu cầu thời gian thực 4.2 Lập trình nhúng với ngôn ngữ Arduino Chương trình Arduino có thể được chia làm 3 phần: cấu trúc (structure), giá trị (variables), hàm và thủ tục (function). 4.2.1 Cấu trúc 4.2.1.1 setup() Những lệnh trong setup() sẽ được chạy khi chương trình khởi động, có thể sử dụng nó để khai báo giá trị của biến, khai báo thư viện, thiết lập các thông số, Những lệnh trong setup() chỉ chạy một lần để khai báo. Ví dụ int led = 13; void setup() { Bài giảng lập trình nhúng 43
  48. Chương IV: Phần mềm nhúng pinMode(led, OUTPUT); } Khi cấp nguồn cho Arduino, lệnh “pinMode(led, OUTPUT);” sẽ được chạy 1 lần để khai báo. 4.2.1.2 loop() Sau khi setup() chạy xong, những lệnh trong loop() được chạy. Chúng sẽ lặp đi lặp lại liên tục cho tới khi nào nguồn của board Arduino được ngắt mới thôi. Bất cứ khi nào nhất nút Reset, chương trình sẽ trở về lại trạng thái như khi Arduino mới được cấp nguồn. Quá trình này có thể được miêu tả như sơ đồ dưới đây Ví dụ void loop() { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); } Lệnh ở loop() sẽ được chạy và được lặp đi lặp lại liên tục, tạo thành một chuỗi: digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); Bài giảng lập trình nhúng 44
  49. Chương IV: Phần mềm nhúng digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); 4.2.1.3 Cú pháp mở rộng 4.2.1.3.1 Dấu chấm phẩy “;” Dùng để kết thúc một dòng lệnh. Ví dụ int ledPin = 13; Khi lập trình nếu quên dấu ";" chương trình dịch của Arduino sẽ tự động dò tìm lỗi này và thông báo chính xác dòng bị lỗi. 4.2.1.3.2 Dấu ngoặc nhọn “{}” Nhiệm vụ của “{}” là cung cấp một cú pháp để gọi những lệnh cho những cấu trúc đặc biệt như (if, while, for, ) Ví dụ: Trong hàm và thủ tục void myfunction( ){ ; } Vòng lặp while ( ) { } do { } while ( ); for ( ; ; ) Bài giảng lập trình nhúng 45
  50. Chương IV: Phần mềm nhúng { } Lệnh rẻ nhánh if ( ) { } else if ( ) { } else { } 4.2.1.3.3 Dòng chú thích “//” Dòng chú thích sẽ giúp ghi chú cho từng dòng code hoặc trình bày nhiệm vụ của nó để người đọc có thể hiểu được chương trình này làm được những gì. Dòng chú thích sẽ không được Arduino biên dịch nên cho dù dòng chú thích có dài đến đâu thì cũng không ảnh hưởng đến bộ nhớ flash của vi điều khiển. Ví dụ x = 5; // Đây là dòng chú thích // nó sẽ ghi chú tất cả những chữ (text, câu lệnh, everything) nằm sau dấu // cho đến khi hết dòng 4.2.1.3.4 Đoạn chú thích “/* */” Cũng giống như dòng chú thích nhưng được ghi trên dòng khác nhau. Ví dụ /* Đây là đoạn chú thích Nó sẽ "ghi chú" tất cả những gì nằm trong cặp dấu "/ *" và "* /" Bài giảng lập trình nhúng 46
  51. Chương IV: Phần mềm nhúng if (gwb == 0){ // Có thể dùng dòng chú thích trong này x = 3; /* nhưng không được dùng một đoạn chú thích khác, chương trình sẽ bị lỗi cú pháp */ } // kết thúc với ký tự đóng "* /" */ Dòng chú thích thường dùng khi cần ghi chú một đoạn code. Đoạn chú thích thường dùng để debug một đoạn code mới thêm vào. Khi thêm một đoạn code mới vô tình làm cho chương trình hoạt động lỗi thì hãy thử dùng đoạn chú thích để đánh dấu là ghi chú những dòng đó (chương trình dịch sẽ bỏ qua). Sau đó, xem thử chương trình có chạy đúng hay không, nếu có lỗi thì mở rộng dòng chú thích lên những dòng code trước đó nữa, còn nếu không thì thu hẹp đoạn chú thích lại và tiếp tục thực hiện cho đến khi hết lỗi. 4.2.1.3.5 #define #define là một đối tượng của ngôn ngữ C/C++ cho phép đặt tên cho một hằng số nguyên hay hằng số thực. Trước khi biên dịch, trình biên dịch sẽ thay thế những tên hằng đang sử dụng bằng chính giá trị của chúng. Quá trình thay thế này được gọi là quá trình tiền biên dịch (pre- compile). Cú pháp #define [tên hằng] [giá trị của hằng] Ví dụ #define pi 3.14 Nếu viết code như sau: #define pi 3.14 float a = pi * 2.0; // pi = 6.28 thì sau khi pre-compile trước khi biên dịch, kết quả là: #define pi 3.14 float a = 3.14 * 2.0; // a = 6.28 Lưu ý Nếu một biến có tên trùng với tên hằng số được khai báo bằng #define thì khi pre- comile, biến ấy sẽ bị thay thế bằng giá trị của hằng số kia. Hệ quả tất yếu là khi biên dịch, chương trình sẽ bị lỗi cú pháp (không dễ dàng nhận ra điều này). Đôi khi nó cũng dẫn đến lỗi logic - một lỗi rất khó sửa. Nếu viết code như sau: #define pi 3.14 Bài giảng lập trình nhúng 47
  52. Chương IV: Phần mềm nhúng float pi = 3.141592654; thì sau khi pre-compile trước khi biên dịch, kết quả là: #define pi 3.14 float 3.14 = 3.141592654; // lỗi cú pháp Vì vậy, nên hạn chế tối đa việc sử dụng #define để khai báo hằng số khi không cần thiết. Có thể sử dụng cách khai báo sau để thay thế: const float pi = 3.14; 4.2.1.3.6 #include #include cho phép chương trình tải một thư viện đã được viết sẵn. Tức là có thể truy xuất được những tài nguyên trong thư viện này từ chương trình. Nếu có một đoạn code và cần sử dụng nó trong nhiều chương trình, có thể dùng #include để nạp đoạn code ấy vào chương trình, thay vì phải chép đi chép lại đoạn code ấy. Cú pháp #include Ví dụ Giả sử có thư mục cài đặt Arduino IDE tên là ArduinoIDE, thư viện có tên là EEPROM (được lưu ở \ArduinoIDE\libraries\EEPROM\) Một đoạn code lưu ở file code.h nằm trong thư mục function của thư viện EEPROM thì được khai báo như sau: #include //đường dẫn đầy đủ: \ArduinoIDE\libraries\EEPROM\function\code.h 4.2.1.4 Toán tử số học 4.2.1.4.1 Phép gán “=” Dùng để gán một giá trị cho một biến. Giá trị nằm trên phải, tên biến nằm bên trái ngăn cách nhau bởi 1 dấu bằng. Ví dụ int sensVal; // Khai báo kiểu dữ liệu cho biến sensVal là int sensVal = analogRead(0); // đặt giá trị cho sensVal là giá trị analog tại chân A0 4.2.1.4.2 Phép cộng, phép trừ, phép nhân, phép chia Những phép toán trên có nhiệm vụ thực hiện việc tính toán trong Arduino. Tùy thuộc vào kiểu dữ liệu của các biến hoặc hằng số mà kết quả trả về của nó có kiểu dữ liệu như thế nào. Nếu là kiểu số nguyên thì nó cũng sẽ overflow. Và nếu các giá trị đưa vào là số thực thì được phép sử dụng các dấu chấm "." để ngăn cách phần nguyên và phần thực. Bài giảng lập trình nhúng 48
  53. Chương IV: Phần mềm nhúng Ví dụ y = y + 3; x = x - 7; i = j * 6; r = r / 5; Cú pháp result = value1 + value2; result = value1 - value2; result = value1 * value2; result = value1 / value2; Tham số value1: là một số ở bất kỳ kiểu dữ liệu nào value2: là một số ở bất kỳ kiểu dữ liệu nào 4.2.1.4.3 Phép chia lấy dư Phép chia lấy dư là phép lấy về phần dư của một phép chia các số nguyên. Cú pháp = / ; Ví dụ x = 7 % 5; // x bây giờ là 2 x = 9 % 5; // x bây giờ là 4 x = 5 % 5; // x bây giờ là 0 x = 4 % 5; // x bây giờ là 4 Mã lập trình tham khảo /* cập nhập lại giá trị trong hàm loop */ int values[10]; int i = 0; void setup() {} void loop() { values[i] = analogRead(0); Bài giảng lập trình nhúng 49
  54. Chương IV: Phần mềm nhúng i = (i + 1) % 10; // giá trị của biến i sẽ không bao giờ vượt quá 9. } Lưu ý Phép chia lấy dư không khả dụng với kiểu dữ liệu float 4.2.1.5 Toán tử so sánh Các toán tử so sánh thường dùng để so sánh 2 số có cùng một kiểu dữ liệu. Toán tử Ý nghĩa Ví dụ == So sánh bằng (a == b) trả về TRUE nếu a bằng b và ngược lại So sánh không != bằng (a != b) trả về TRUE nếu a khác b và ngược lại (a > b) trả về TRUE nếu a lớn hơn b và FALSE nếu a bé hơn > So sánh lớn hoặc bằng b = bằng (a >= b) tương đương với ((a > b) or (a = b)) 4.2.1.6 TOÁN TỬ LOGIC Toán tử Ý nghĩa Ví dụ and (a && b) trả về TRUE nếu a và b đều mang giá trị TRUE. Nếu một trong a (&&) Và hoặc b là FALSE thì (a && b) trả về FALSE (a || b) trả về TRUE nếu có ít nhất 1 trong 2 giá trị a và b là TRUE, trả về or ( || ) Hoặc FALSE nếu a và b đều FALSE Phủ not ( ! ) định nếu a mang giá trị TRUE thì (!a) là FALSE và ngược lại (a ^ b) trả về TRUE nếu a và b mang hai giá trị TRUE/FALSE khác nhau, xor (^) Loại trừ các trường hợp còn lại trả về FALSE 4.2.1.7 Toán tử hợp nhất 4.2.1.7.1 Cộng một, trừ một Tăng hoặc trừ một biến đi 1 đơn vị. Bài giảng lập trình nhúng 50
  55. Chương IV: Phần mềm nhúng Cú pháp x++; // tăng x lên 1 giá trị và trả về giá trị cũ của x ++x; // tăng x lên 1 giá trị và trả về giá trị mới của x x ; // trừ x lên 1 giá trị và trả về giá trị cũ của x x ; // trừ x lên 1 giá trị và trả về giá trị mới của x Tham số x: bất kỳ kiểu số nguyên nào (int, byte, unsigned int, ) Trả về Giá trị cũ của biến hoặc giá trị mới đã được cộng / hoặc bị trừ của biến ấy. Ví dụ x = 2; y = ++x; // x bây giờ có giá trị là 3, và y cũng có giá trị là 3 y = x ; // x bây giờ đã trở lại với giá trị 2, nhưng y không đổi vẫn là 3 4.2.1.7.2 Các phép toán rút gọn Cung cấp một số phép toán rút gọn để viết code trong đẹp hơn và dễ nhớ hơn. Cú pháp x += y; // giống như phép toán x = x + y; x -= y; // giống như phép toán x = x - y; x *= y; // giống như phép toán x = x * y; x /= y; // giống như phép toán x = x / y; Tham số x: mọi kiểu dữ liệu y: mọi kiểu dữ liệu hoặc hằng số Ví dụ x = 2; x += 4; // x bây giờ có giá trị là 6 x -= 3; // x bây giờ có giá trị là 3 x *= 10; // x bây giờ có giá trị là 30 x /= 2; // x bây giờ có giá trị là 15 4.2.1.8 Cấu trúc điều khiển 4.2.1.8.1 Câu lệnh if, if else Bài giảng lập trình nhúng 51
  56. Chương IV: Phần mềm nhúng Cú pháp: if ([biểu thức 1] [toán tử so sánh] [biểu thức 2]) { //biểu thức điều kiện [câu lệnh 1] } else { [câu lệnh 2] } Nếu biểu thức điều kiện trả về giá trị TRUE, [câu lệnh 1] sẽ được thực hiện, ngược lại, [câu lệnh 2] sẽ được thực hiện. Ví dụ: int a = 0; if (a == 0) { a = 10; } else { a = 1; } // a = 10 Lệnh if không bắt buộc phải có nhóm lệnh nằm sau từ khóa else int a = 0; if (a == 0) { a = 10; } // a = 10 Có thể kết hợp nhiều biểu thức điều kiện khi sử dụng lệnh if. Chú ý rằng mỗi biểu thức con phải được bao bằng một ngoặc tròn và phải luôn có một cặp ngoặc tròn bao toàn bộ biểu thức con. Cách viết đúng Cách viết sai Bài giảng lập trình nhúng 52
  57. Chương IV: Phần mềm nhúng int a = 0; int a = 0; if ((a == 0) && (a < 1)) { if (a == 0) && (a < 1) { a = 10; a = 10; } } int a = 0; if (a == 0 && a < 1) { a = 10; } Chú ý: a = 10; là một câu lệnh gán, giá trị logic của nó luôn là TRUE (vì lệnh gán này luôn thực hiện được) (a == 10) là một biểu thức logic có giá trị TRUE hay FALSE tùy thuộc vào giá trị của biến a. Nếu: int a = 0; if (a = 1) { a = 10; } thì giá trị của a sẽ bằng 10, vì (a = 1) là một câu lệnh gán, trong trường hợp này nó được xem như một biểu thức logic và luôn trả về giá trị TRUE. 4.2.1.8.2 Câu lệnh switch case Giống như if, switch / case cũng là một dạng lệnh nếu thì, nhưng nó được thiết kế chuyên biệt để xử lý giá trị trên một biến chuyên biệt. Ví dụ, có một biến là action sẽ nhận trị từ những module khác qua serial. Nhưng action sẽ nằm trong một các giá trị nào đó thì lúc này hãy sử dụng switch / case. Ví dụ switch (action) { case "callMyMom": //gọi điện cho mẹ của tôi break; case "callMyDad": Bài giảng lập trình nhúng 53
  58. Chương IV: Phần mềm nhúng //gọi điện cho ba của tôi break; default: // mặc định là không làm gì cả // có thể có default: hoặc không } Cú pháp switch (var) { case label: //đoạn lệnh break; case label: // Đoạn lệnh break; /* case more and more */ default: // statements } Tham số var: biến muốn so sánh label: sẽ đem giá trị của biến SO SÁNH BẰNG với nhãn này 4.2.1.8.3 Vòng lặp for Hàm for có chức năng làm một vòng lặp. Hàm for làm đi làm lại một công việc có một tính chất chung nào đó. Chẳng hạn, bật tắt một con LED thì dùng digitalWrite xuất HIGH delay rồi lại LOW rồi lại delay. Nhưng nếu muốn làm nhiều hơn 1 con LED thì đoạn code sẽ dài ra. Ví dụ: Hãy xuất 10 chữ số (từ 1 - 10) ra Serial. Không dùng hàm for void setup() { Serial.begin(9600); Bài giảng lập trình nhúng 54
  59. Chương IV: Phần mềm nhúng Serial.println(1); Serial.println(2); Serial.println(3); Serial.println(4); Serial.println(5); Serial.println(6); Serial.println(7); Serial.println(8); Serial.println(9); Serial.println(10); } void loop() { // không làm gì cả; } Khi sử dụng hàm for: void setup(){ Serial.begin(9600); int i; for (i = 1;i<=10;i=i+1) { Serial.println(i); } } void loop(){ } Cấu trúc Theo ví dụ trên, đoạn code sử dụng hàm for như sau: for (i = 1;i<=10;i = i + 1) { Serial.println(i); } Hàm for trong ví dụ này sẽ : 1. Chắc chắn nó sẽ xử lý đoạn code Serial.println(i); 10 lần Bài giảng lập trình nhúng 55
  60. Chương IV: Phần mềm nhúng 2. Chạy từ vị trí xuất phát là 1, đến vị trí kết thúc là 10 // i = 1 ; i bé hơn for ( = ; ; += ) { ; } For lùi (xuất phát từ một vị trí lớn chạy về vị trí nhỏ hơn) lớn hơn for ( = ; ; -= ) { ; } Cú pháp chính của hàm For: for ( = ; ; ) { //lệnh } 4.2.1.8.4 Vòng lặp while Vòng lặp while là một dạng vòng lặp theo điều kiện, không thể biết trước số lần lặp của nó, nhưng có thể quản lý lúc nào thì nó ngừng lặp! 1. While là một vòng lặp không biết trước số lần lặp, nó dựa vào điều kiện, điều kiện còn đúng thì còn chạy. 2. Chạy một đoạn lệnh (trong đó có những hàm ảnh hưởng đến điều kiện). Cú pháp while ( ) { //các đoạn lệnh; } Bài giảng lập trình nhúng 56
  61. Chương IV: Phần mềm nhúng Ví dụ int day = 1; int nam = 2014; // Năm 2014 while (day 5) break; } a++; if (a > 100) break; } //a = 101 4.2.1.8.6 Câu lệnh continue Bài giảng lập trình nhúng 57
  62. Chương IV: Phần mềm nhúng continue là một lệnh có chức năng bỏ qua một chu kì lặp trong một vòng lặp (for, do, while) chứa nó trong đó. Khi gọi lệnh continue, những lệnh sau nó và ở trong cùng vòng lặp với nó sẽ bị bỏ qua để thực hiện những chu kì lặp kế tiếp. Ví dụ int a = 0; int i = 0; while (i 400) { return 1; else{ return 0; } 4.2.1.8.8 Câu lệnh goto Goto có nhiệm vụ tạm dừng chương trình rồi chuyển đến một nhãn đã được định trước, sau đó lại chạy tiếp chương trình! Cú pháp label: //Khai báo một nhãn có tên là label Bài giảng lập trình nhúng 58
  63. Chương IV: Phần mềm nhúng goto label; //Chạy đến nhãn label rồi sau đó thực hiện tiếp những đoạn chương trình sau nhãn đó Lệnh goto chỉ hữu ích khi đang dùng nhiều vòng lặp quá và muốn thoát khỏi nó một cách nhanh chóng. Ví dụ for(byte r = 0; r -1; g ){ for(byte b = 0; b 250){ goto bailout;} //thêm nhiều câu lệnh nữa } } } bailout: 4.2.2 Giá trị 4.2.2.1 Hằng số 4.2.2.1.1 HIGH Trong lập trình trên Arduino, HIGH là một hằng số có giá trị nguyên là 1. Trong điện tử, HIGH là một mức điện áp lớn hơn 0V. Giá trị của HIGH được định nghĩa khác nhau trong các mạch điện khác nhau, nhưng thường được quy ước ở các mức như 1.8V, 2.7V, 3.3V 5V, 12V, HIGH là một hằng số có giá trị nguyên là 1 Xét 2 đoạn code ví dụ sau: int led = 13; void setup() { pinMode(led, OUTPUT); digitalWrite(led, HIGH); } void loop() { } Đoạn code này có chức năng bật sáng đèn led nối với chân số 13 trên mạch Arduino (Arduino Nano, Arduino Uno R3, Arduino Mega 2560, ). Bài giảng lập trình nhúng 59
  64. Chương IV: Phần mềm nhúng int led = 13; void setup() { pinMode(led, OUTPUT); digitalWrite(led, 1); } void loop() { } Sẽ xuất hiện 2 vấn đề: Trong đoạn code thứ 2, "HIGH" đã được sửa thành "1". Đèn led trên mạch Arduino vẫn sáng bình thường với 2 chương trình khác nhau. Điều này khẳng định "HIGH là một hằng số có giá trị nguyên là 1" đã nêu ở trên. HIGH là một điện áp lớn hơn 0V Điện áp (điện thế) tại một điểm là trị số hiệu điện thế giữa điểm đó và cực âm của nguồn điện (0V). Giả sử ta có một viên pin vuông 9V thì ta có thể nói điện áp ở cực dương của cục pin là 9V, hoặc hiệu điện thế giữa 2 cực của cục pin là 9V. Điện áp ở mức HIGH không có giá trị cụ thể như 3.3V, 5V, 9V, mà trong mỗi loại mạch điện, nó có trị số khác nhau và đã được quy ước trước. Trong các mạch Arduino, HIGH được quy ước là mức 5V mặc dù 4V vẫn có thể được xem là HIGH. Ví dụ như trong mạch Arduino Uno R3, theo nhà sản xuất, điện áp được xem là ở mức HIGH nằm trong khoảng từ 3V đến 5V. Dù HIGH không có một trị số nào rõ ràng nhưng nhất quyết rằng giá trị của nó luôn lớn hơn 0V. 4.2.2.1.2 LOW Trong lập trình trên Arduino, LOW là một hằng số có giá trị nguyên là 0. Trong điện tử, LOW là mức điện áp 0V hoặc gần bằng 0V, giá trị này được định nghĩa khác nhau trong các mạch điện khác nhau, nhưng thường là 0V hoặc hơn một chút xíu. LOW là một hằng số có giá trị nguyên là 0 Xét 2 đoạn code ví dụ sau: int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { digitalWrite(led, HIGH); Bài giảng lập trình nhúng 60
  65. Chương IV: Phần mềm nhúng delay(1000); digitalWrite(led, LOW); delay(1000); } Đoạn code này có chức năng bật làm led chớp tắt nối với chân số 13 trên mạch Arduino với thời gian delay là 1s (Arduino Nano, Arduino Uno R3, Arduino Mega 2560, ). int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, 0); delay(1000); } Sẽ xuất hiện 2 vấn đề: Trong đoạn code thứ 2, "LOW" đã được sửa thành "0". Đèn led trên mạch Arduino vẫn chớp tắt bình thường với 2 chương trình khác nhau. Điều này khẳng định "LOW là một hằng số có giá trị nguyên là 0" đã nêu ở trên. LOW là một điện áp lớn hơn 0V Điện áp (điện thế) tại một điểm là trị số hiệu điện thế giữa điểm đó và cực âm của nguồn điện (0V). Giả sử ta có một viên pin vuông 9V thì ta có thể nói điện áp ở cực dương của cục pin là 9V, ở cực âm là 0V, hoặc hiệu điện thế giữa 2 cực của cục pin là 9V. Điện áp ở mức LOW không có giá trị cụ thể như 3.3V, 5V, 9V, mà trong mỗi loại mạch điện, nó có một trị số khác nhau nhưng thường là 0V hoặc gần bằng 0V. Trong các mạch Arduino, LOW được quy ước là mức 0V mặc dù 0.5V vẫn có thể được xem là LOW. Ví dụ như trong mạch Arduino Uno R3, theo nhà sản xuất, điện áp được xem là ở mức LOW nằm trong khoảng từ 0V đến 1.5V ở các chân I/O. 4.2.2.1.3 Thiết đặt Digital Pins như là INPUT, INPUT_PULLUP, và OUTPUT Bài giảng lập trình nhúng 61
  66. Chương IV: Phần mềm nhúng Chân vi điều khiển có thể được sử dụng như là INPUT, INPUT_PULLUP , hoặc OUTPUT. Để thay đổi cách sử dụng một pin, chúng ta sử dụng hàm pinMode(). Cấu hình một pin là INPUT Các pin của Arduino ( Atmega ) được cấu hình là một INPUT với pinMode ( ) có nghĩa là làm cho pin ấy có trở kháng cao (không cho dòng điện đi ra) . Pin được cấu hình là INPUT làm việc tiêu thụ năng lượng điện của mạch rất nhỏ, nó tương đương với một loạt các điện trở 100 Mega-ôm ở phía trước của pin . Điều này làm cho chúng cực kì hữu ích cho việc đọc một cảm biến, nhưng không cung cấp năng lượng một đèn LED. Khi một pin được cấu hình là INPUT thì sẽ dễ dàng đọc được các tín hiệu điện (Có điện <= 5V). Nếu đã cấu hình pin là INPUT và muốn pin có một tham chiếu đến GND (cực âm), thường được thực hiện với một điện trở kéo xuống. Cấu hình một pin là INPUT_PULLUP Chip Atmega trên Arduino có nội kéo lên điện trở (điện trở kết nối với hệ thống điện nội bộ) có thể truy cập. Nếu không thích mắc thêm một điện trở ở mạch ngoài, có thể dùng tham số INPUT_PULLUP trong pinMode(). Mặc định khi không được kết nối với một mạch ngoài hoặc được kết nối với cực dương thì pin sẽ nhận giá trị là HIGH, khi pin được thông tới cực âm xuống GND thì nhận giá trị là LOW. Cấu hình một pin là đầu ra (OUTPUT) Để thiết đặt pin là một OUTPUT, chúng ta dùng pinMode ( ), điều này có nghĩa là làm cho pin ấy có một trở kháng thấp (cho dòng điện đi ra). Pin sẽ cung cấp một lượng điện đáng kể cho các mạch khác . Pin của vi điều khiển Atmega có thể cung cấp một nguồn điện liên tục 5V hoặc thả chìm ( cho điện thế bên ngoài chạy vào ) lên đến 40 mA ( milliamps ). Lúc bấy giờ, nếu làm ngắn mạch (digitalWrite 1 pin là HIGH rồi nối trực tiếp đến cực âm hoặc digitalWrite 1 pin là LOW rồi mắc trực tiếp đến cực dương) thì mạch sẽ bị hỏng. Ngoài ra, với dòng điện chỉ 40mA thì trong một số trường hợp chúng ta không thể làm cho mô tơ hoặc relay hoạt động được. Để làm chúng hoạt động thì chúng ta cần chuẩn bị cho mình một số mạch sử dụng các IC khuếch đại chuyên dụng (gọi là mạch giao tiếp) 4.2.2.1.4 LED_BUILTIN Hầu hết các mạch Arduino đều có một pin kết nối với một on-board LED (led nằm trên mạch) nối tiếp với một điện trở, chúng có giá trị là 13. LED_BUILTIN là một hằng số thay thế cho việc tuyên bố một biến có giá trị điều khiển on-board LED. 4.2.2.1.5 true true là một hằng logic, cũng có thể HIỂU true là một hằng số nguyên mang giá trị là 1. Trong các biểu thức logic, một hằng số hay giá trị của một biểu thức khác 0 được xem như là mang giá trị true. Lưu ý Không được viết "true" thành TRUE hay bất kì một dạng nào khác. Bài giảng lập trình nhúng 62
  67. Chương IV: Phần mềm nhúng Các giá trị sau là tương đương nhau: true, HIGH, 1 4.2.2.1.6 false Trái lại với true, false là một hằng logic có giá trị là phủ định của true (và ngược lại), tức là (!true) = false, cũng có thể HIỂU false là một hằng số nguyên mang giá trị là 0. Trong các biểu thức logic, một hằng số hay giá trị của một biểu thức bằng 0 được xem như là bằng false. Lưu ý Không được viết "false" thành FALSEhay bất kì một dạng nào khác. Các giá trị sau là tương đương nhau: false, LOW, 0 4.2.2.1.7 Hằng số nguyên Hằng số nguyên là những con số được sử dụng trực tiếp trong chương trình. Theo mặc định, những con số này có kiểu là int (trong pascal thì kiểu int giống như kiểu integer). Ví dụ if (a >= 10) { a = 0; } Ở đây 0 và 10 được gọi là những hằng nguyên. Thông thường, các hằng số nguyên được biểu thị dưới dạng thập phân, nhưng có thể biểu thị chúng trong các hệ cơ số khác như sau: Hệ cơ số Ví dụ Định dạng Ghi chú 10 (thập phân) 159 biểu thị bằng các chữ số từ 0 đến 9 bắt đầu bằng 'B' (hoặc 2 (nhị phân) B1111011 '0B') biểu thị bằng 2 chữ số 0 và 1 8 (bát phân) 0173 bắt đầu bằng '0' biểu thị bằng các chữ số từ 0-7 biểu thị bằng các chữ số từ 0-9 và kí tự 16 (thập lục phân) 0x7B bắt đầu bằng '0x' từ A-F (hoặc a-f) Hệ thập phân (decimal) là hệ cơ số 10, cũng là hệ cơ số được dùng phổ biến nhất. Ví dụ: int a = 101; // có giá trị là 101 ở hệ thập phân ((1 * 10^2) + (0 * 10^1) + 1) Hệ nhị phân (binary) là hệ cơ số 2, chỉ được biểu thị bởi 2 chữ số "0" và "1", có tiền tố "B" (đôi khi là "0B") đứng đầu Ví dụ: Bài giảng lập trình nhúng 63
  68. Chương IV: Phần mềm nhúng int a = B101; // có giá trị là 5 ở hệ thập phân ((1 * 2^2) + (0 * 2^1) + 1) Các định dạng nhị phân chỉ hoạt động trên byte (8 bit) giữa 0 (B0) và 255 (B11111111). Nếu muốn sử dụng hệ nhị phân trên một số nguyên int (16 bít) thì phải thực hiện quy trình 2 bước như sau: long myInt = (B11100000 * 256) + B11111111; // myInt = B1110000011111111 Hệ bát phân (octal) là hệ cơ số 8, chỉ dùng các chữ số từ 0-7 để biểu thị, có tiền tố "0" đứng đầu int a = 0101; // có giá trị là 65 ở hệ thập phân ((1 * 8^2) + (0 * 8^1) + 1) Chú ý: Rất khó để tìm lỗi một cách dễ dàng nếu không cẩn thận hoặc không thành thạo trong việc sử dụng hệ bát phân. Giả sử muốn khai báo một hằng số nguyên ở hệ thập phân ví dụ 161, nhưng do đặt thêm số 0 phía trước. => chương trình dịch hiểu sai hệ số đang sử dụng => sinh ra lỗi logic khiến chương trình chạy sai. Hệ thập lục phân (hexadecimal) là hệ cơ số 16, chỉ dùng các chữ số từ 0-9 và A-F (hoặc a-f) để biểu thị; A đại diện cho 10, B là 11, lên đến F là 15. Các chữ số dùng ở hệ này có tiền tố "0x" đứng trước Ví dụ: int a = 0x101; // có giá trị là 257 trong hệ thập phân ((1 * 16^2) + (0 * 16^1) + 1) Hậu tố U và L Theo mặc định, một hằng số nguyên được coi là một số nguyên kiểu int với những hạn chế trong giao tiếp giữa các giá trị. Để xác định một hằng số nguyên với một kiểu dữ liệu khác phải tuân theo quy tắc sau: Dùng 'u' hoặc 'U' để biểu thị kiểu dữ liệu unsigned (không âm). Ví dụ: 33u Dùng 'l' hoặc 'L' để biểu thị kiểu dữ liệu long. Ví dụ: 100000L Dùng 'ul' hoặc 'UL' để biểu thị kiểu dữ liệu unsigned long. Ví dụ: 32767ul 4.2.2.1.8 Hằng số thực Tương tự như hằng số nguyên, hằng số thực (floating point constants) cũng có cách làm việc và sử dụng tương tự. Khi viết một biểu thức tính toán, giá trị của biểu thức này sẽ được tính ra và trình biên dịch sẽ thay thế biểu thức này bằng một hằng số thực đã tính ra được. Điều đó gợi ý rằng trong những chương trình lớn, để giảm thời gian biên dịch nên tính trước giá trị của những biểu thức thay vì bắt trình biên dịch tính toán. Ví dụ float a = .159; float b = 0.159; // a = b Bài giảng lập trình nhúng 64
  69. Chương IV: Phần mềm nhúng Để biểu thị những hằng số thực có giá trị cực lớn hoặc cực nhỏ phải sử dụng 2 kí hiệu khoa học là "E" và "e". Hằng số thực Ý nghĩa Giá trị 10.0 10 2.34E5 2.34 * 105 234000 67e-12 67.0 * 10-12 0.000000000067 4.2.2.2 Kiểu dữ liệu 4.2.2.2.1 void "void" là một từ khóa chỉ dùng trong việc khai báo một function. Những function được khai báo với "void" sẽ không trả về bất kì dữ liệu nào khi được gọi. Ví dụ led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { blink(); } void blink() { digitalWrite(led, LOW); delay(1000); digitalWrite(led, HIGH); delay(1000); } Giải thích "blink" là một function được định nghĩa với từ khóa "void", do đó nó không trả về một giá trị nào. Nhiệm vụ của "blink" chỉ là làm nhấp nháy đèn LED ở chân số 13 trên mạch Arduino. Có thể thấy rằng những function kiểu này không dùng lệnh "return" để trả về giá trị của function. 4.2.2.2.2 boolean Bài giảng lập trình nhúng 65
  70. Chương IV: Phần mềm nhúng Một biến được khai báo kiểu boolean sẽ chỉ nhận một trong hai giá trị: true hoặc false và sẽ mất 1 byte bộ nhớ cho điều đó. Lưu ý Những cặp giá trị sau là tương đương nhau. Về bản chất, chúng đều là những hằng số nguyên với 2 giá trị 0 và 1: true - false HIGH - LOW 1 - 0 Ví dụ: int led = 13; boolean led_status; void setup() { pinMode(led, OUTPUT); led_status = true; // led ở trạng thái bật } void loop() { digitalWrite(led, led_status); // bật đèn, led_status = 1 delay(1000); digitalWrite(led, !led_status); // tắt đèn, !led_status = 0 delay(1000); } 4.2.2.2.3 char Kiểu dữ liệu này là kiểu dữ liệu biểu diễn cho 1 KÝ TỰ (nếu cần biểu diễn một chuỗi trong chương trình Arduino cần sử dụng kiểu dữ liệu String). Kiểu dữ liệu này chiếm 1 byte bộ nhớ. Kiểu char chỉ nhận các giá trị trong bảng mã ASCII. Kiểu char được lưu dưới dạng 1 số nguyên byte có số âm (có các giá trị từ -127 - 128), thay vì thiết đặt một biến kiểu char có giá trị là 'A', có thể đặt là 65. Ví dụ char myChar = 'A'; char myChar = 65; // cả 2 cách khai báo đều hợp lệ 4.2.2.2.4 unsigned char Giống kiểu char, tuy nhiên kiểu unsigned char lại biểu hiệu một số nguyên byte không âm (giá trị từ 0 - 255). Bài giảng lập trình nhúng 66