Thiết kế máy đo gia tốc theo hai phương X - Y

MUÏC LUÏC Lôøi caûm ôn Muïc luïc Chöông 1. Toång quan 1.1. Mục tiêu đề tài 1.2. Cơ sở lý thuyết 1.3. Đo gia tốc bằng cảm biến MEMS Chöông 2. Giôùi thieäu linh kieän 2.1. Màn hình LCD hiển thị ký tự 20x4 2.1.1. Tính năng 2.1.2. Mô tả chung 2.1.3. Sơ đồ chân 2.1.4. Sơ đồ kết nối 2.1.5. Thanh ghi 2.1.6. Tổ chức bộ nhớ 2.1.7. Điều khiển hiển thị Text LCD 2.2. Sensor gia tốc ADXL202 2.2.1. Tính năng 2.2.2. Mô tả chung 2.2.3. Sơ đồ khối chức năng 2.2.4. Sơ đồ chân 2.2.5. Nguyên lý vận hành 2.2.6. Linh kiện mạch ngoài 2.2.7. Đặt giải thông cho ADXL202 sử dụng Cx và Cy 2.2.8. Đặc tuyến ngõ ra của sensor ADXL202 2.3. Vi điều khiển ATMega32 2.3.1. Chức năng 2.3.2. Sơ đồ khối 2.3.2. Cấu trúc nhân AVR 2.3.3. Các thanh ghi chức năng chung 2.3.4. Con troû ngaên xeáp (SP) 2.3.5. Quaûn lyù ngaét 2.3.6. Cấu trúc bộ nhớ 2.3.7. Caùc coång vaøo ra (I/O) 2.3.9. Mô tả các thanh ghi 2.3.11. Bộ biến đổi A/D 2.4. MMC/SD Card 2.4.1. Sơ đồ khối SD Card 2.4.2. Sơ đồ chân của MMC/SD Card 2.4.3. Nguyên tắc hoạt động 2.4.4. Giao thức truyền nối tiếp đồng bộ SPI 2.4.4. Các tập lệnh của SD card Chöông 3. Thi coâng phaàn cöùng 3.1. Nguồn cung cấp 3.1.1. Sơ đồ mạch điện 3.1.2. Nguyên lý hoạt động 3.2. LCD 20x4 3.2.1. Sơ đồ mạch điện 3.2.2. Nguyên lý hoạt động 3.3. ADXL202E 3.3.1. Sơ đồ mạch điện 3.3.1. Nguyên lý hoạt động 3.4. ATMega32 3.4.1. Sơ đồ mạch điện 3.4.2. Nguyên lý hoạt động 3.5. SD Card 3.5.1. Sơ đồ mạch điện 3.5.2. Nguyên lý hoạt động 3.6. Max232 3.6.1 Sơ đồ mạch điện 3.6.2. Nguyên lý hoạt động 3.7. Phím nhấn Chöông 4. Coâng cuï laäp trình vaø löu ñoà giaûi thuaät 4.1. Giới thiệu phần mềm WinAVR 4.2. Giới thiệu phần mềm AVR Studio 4.3. Giải thuật chương trình chính Chöông 5. Thöïc hieän chöông trình 5.1. LCD 20x4 5.2. ADXL202E 5.3. SPI 5.4 SD Card 5.5. FAT32 5.6. Chương trình chính Chöông 6. Keát luaän 6.1. Những kết quả đạt được 6.2 Những kết quả chưa đạt được 6.3. Hướng phát triển cho đề tài Phaàn phuï luïc CHƯƠNG 6 KẾT LUẬN 6.1. Những kết quả đạt được: - Thiết kế và hoàn thiện máy đo gia tốc hiển thị kết quả trực tiếp trên LCD - Hiểu và thực hiện được các chuẩn giao tiếp I2C, SPI, USART, PWM - Nắm vững kiến thức về họ Vi điều khiển AVR - Sử dụng thành thạo việc chuyển đổi ADC - Sử dụng được các môi trường lập trình cho AVR như SDCC, WinAVR, Code Vision AVR - Tự xây dựng các thư viện riêng cho các môi trường lập trình AVR - Nắm rõ cấu trúc và cách thức điều khiển và hoạt động của thẻ nhớ 6.2 Những kết quả chưa đạt được: - Chưa hiểu rõ cách thức ghi và truy xuất tập tin trên định dạng FAT32, phải chỉnh sửa thư viện FAT32 từ bộ thư viện mã nguồn mở để sử dụng. - Chưa chống nhiễu cho sensor. - Chưa đặt tên file tự do mà chỉ ghi tiếp vào file đã có sẵn. 6.3. Hướng phát triển cho đề tài: - Xây dựng menu hoàn chỉ bao gồm các thao tác: đặt tên file, ghi kết quả theo thời gian định trước, ghi mỗi lần mốt số luwojgn kết quả cài đặt trước. - Mở rộng với ngõ vào là các loiaj sensor khác như: nhiệt độ, độ ẩm được chuyển đổi bằng menu thể hiện trên LCD - Thay LCD text bằng Graphic LCD để thể hiện tiếng Việt có dấu và vẽ được đồ thị kết quả đo được theo thời gian. - Giao tiếp với máy tính để đổ dữ liệu và xem kết quả với dạng đồ thị.

docx115 trang | Chia sẻ: lvcdongnoi | Lượt xem: 2305 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Thiết kế máy đo gia tốc theo hai phương X - Y, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
u ñöôøng ñieàu khieån SS treân Master, tuøy thuoäc vaøo thieát keá cuûa ngöôøi duøng. Hoaït ñoäng: Moãi chip Master hay Slave coù moät thanh ghi döõ lieäu 8 bits. Cöù moãi xung nhòp do Master taïo ra treân ñöôøng giöõ nhòp SCK, moät bit trong thanh ghi döõ lieäu cuûa Master ñöôïc truyeàn qua Slave treân ñöôøng MOSI, ñoàng thôøi moät bit trong thanh ghi döõ lieäu cuûa chip Slave cuõng ñöôïc truyeàn qua Master treân ñöôøng MISO. Do 2 goùi döõ lieäu treân 2 chip ñöôïc gôûi qua laïi ñoàng thôøi neân quaù trình truyeàn döõ lieäu naøy ñöôïc goïi laø “song coâng”. Hình 2 moâ taû quaù trình truyeàn 1 goùi döõ lieäu thöïc hieän bôûi module SPI trong AVR, beân traùi laø chip Master vaø beân phaûi laø Slave. Hình 2.39. Moâ taû giao tieáp SPI 2.4.4. Caùc taäp leänh cuûa SD card: Baûng 2.9. Caùc taäp leänh cuûa LCD: CMD Teân vieát taét Thoâng soá Chöùc naêng CMD0 GO_IDLE_STATE - Ñöa SD veà cheá ñoä chôø CMD1 SEND_OP_COND - Khôûi taïo SD CMD9 SEND_CSD - Laáy döõ lieäu SD CMD10 SEND_CID - Nhaän daïng SD CMD13 SEND_STATUS - Laáy traïng thaùi thanh ghi CMD16 SET_BLOCKLEN Kích thöôùc goùi Ñaët kich thöôùc goùi (maëc ñònh 512) CMD17 READ_SINGLE_BLOCK Ñòa chæ Ñoïc moät goùi döõ lieäu CMD24 WRITE_BLOCK Ñòa chæ Ghi moät goùi döõ lieäu CMD32 TAG_SECTOR_START Ñòa chæ Ñaët sector ñaàu tieân ñeå xoaù CMD33 TAG_SECTOR_END Ñòa chæ Ñaët sector cuoái ñeå xoaù CMD35 TAG_ERASE_GROUP_START Ñòa chæ Ñaët nhoùm ñaàu tieân ñeå xoaù CMD36 TAG_ERASE_GROUP_END Ñòa chæ Ñaët nhoùm sau cuøng ñeå xoaù CMD38 ERASE - Xoaù taát caû nhoùm vaø sector Moät leänh göûi ñeán theû nhôù bao goàm 6 bytes, göûi baèng SPI transfer). Chöùc naêng cuûa caùc byte nhö sau: - Byte5: Command Index: luoân baét ñaàu baèng 01xx xxxx, vôùi xx xxxx = teân command. Ví duï, ñoái vôùi: Command0: byte5 = 0100 0000 = 0x40 Command1: byte5 = 0100 0001 = 0x41 Command24: byte5 = 0101 1000 = 0x68 - Byte4 - 1: 4 byte naøy laø tham soá cho command. Ñoái vôùi töøng loaïi command, 4 byte naøy coù chöùc naêng khaùc nhau vôùi byte4 laø MS byte vaø byte1 laø LS byte. - Byte0: ñaây laø byte CRC. Thoâng thöôøng, ngoaøi leänh cmd0, söû duïng CRC = 0x95 thì ñoái vôùi caùc cmd khaùc, byte0 = 0x00. Ñoù laø do khi baét ñaàu, MMC or SD chöa söû duïng cheá ñoä SPI maø ñang ôû cheá ñoä maëc ñònh. Sau khi göûi CMD0 chuùng ta môùi coù theå taét CRC. taát nhieân coù theå enable noù, nhöng khoâng thöïc söï caàn thieát. SD seõ phaûn hoài laïi command cuûa uC baèng 3 response. Vieát taét laø R1, R2, R3. Trong ñoù, caùc caáu truùc response nhö sau: R1 = 0 x6 x5 x4 x3 x2 x1 x0 : Trong ñoù, moãi xi thoâng baùo moät traïng thaùi khaùc nhau nhö: (chuù yù, bit 7 bao giôø cuõng laø 0) x6: Loãi tham soá, seõ set khi khung 4byte(ñaõ noùi ôû treân) coù loãi x5: Loãi ñòa chæ, seõ set khi ñòa chæ loãi (chaúng haïn theû nhôù coù 100 sector, caùc baùc ñoïc sector 200 seõ gaây loãi) x4: Loãi xoùa (thöôøng khoâng coù do cta khoâng söû duïng leänh xoùa multi block) - c x3: loãi CRC (tröø leänh CMD0, caùc leänh khaùc khoâng söû duïng CRC neân x3 clear) x2: Xoùa reset (cuõng khoâng gaëp do khoâgn söû duïng CMD) x1: Thoâng baùo MMC,SD coù ôû traïng thaùi chôø idle hay khoâng. set khi idle R2, R3: khoâng söû duïng (vì khoâng caàn thieát) Moät ñieàu caàn chuù yù ñoù laø: moãi khi göûi moät leänh baát kyø, SD seõ traû laïi moät response R1 - 3 naøo ñoù, Trong caùc command toâi giôùi thieäu thì chæ coù response R1 maø thoâi. Bôûi vaäy, sau moãi command, chuùng ta phaûi nhaän döõ lieäu response ñeå xöû lyù. CHÖÔNG 3 THI COÂNG PHAÀN CÖÙNG 3.1. Nguoàn cung caáp: Maïch nguoàn duøng cung caáp ñieän aùp cho toaøn maïch, cuï theå nhö sau: Ñieän aùp 5V oån ñònh caáp cho ATMega32 vaø MAX232 Ñieän aùp 5V oån ñònh duøng laøm chaân so saùnh aùp cho boä bieán ñoåi ADC vaø cung caáp cho sensor ADXL202E Ñieän aùp 3.3V oån ñònh duøng cung caáp cho SD Card 3.1.1. Sô ñoà maïch ñieän: Hình 3.1. Sô ñoà maïch nguoàn cung caáp 3.1.2. Nguyeân lyù hoaït ñoäng: Ñieän aùp 7.5V moät chieàu cung caáp cho maïch nguoàn töø ngoõ vaøo Jack 3, coù dieän aùp töø 7.5V à 12V, ñi qua diode D1 choáng ngöôïc cöïc tính, sau ñoù ñöôïc loïc nhieãu baèng hai tuï C10 vaø C16 ñeå cung caáp cho IC U4 oån aùp 5V caáp cho ATMega32, ngoõ ra ñieän aùp cuûa U4 cuõng ñöôïc loïc baèng hai tuï C11 vaø C17. Ngoõ ra ñieän aùp naøy coù doøng toái ña 1,5A theo datasheet töø nhaø saûn xuaát. Ñieän aùp 5V töø ngoõ ra U3 cung caáp cho IC oån aùp U3, ñeå oån ñònh ñieän aùp 3.3V caáp cho SD Card. Ngoõ vaøo U3 ñöôïc loïc baèng tuï C20, ngoõ ra ñöôïc loïc baèng caùc tuï C13 vaø C15. IC oån aùp U3 cung caáp ñieän aùp 5V cho chaân Avcc duøng so aùp cho boä bieán ñoå ADC cuûa ATMega32 vaø cung caáp nguoàn nuoâi cho sensor ADXL202E, ngoõ vaøo U3 ñöôïc loïc baèng C14 vaø C18, ngoõ ra ñöôïc loïc baêng C13 vaø C18. Trò soá caùc tuï theo khuyeán caùo töø nhaø saûn xuaát. 3.2. LCD 20x4: LCD giao tieáp vôùi ATMega32 baèng PortC, giao tieáp 4 bit döõ lieäu. 3.2.1. Sô ñoà maïch ñieän: Hình 3.2. Maïch LCD 20x4 3.2.2. Nguyeân lyù hoaït ñoäng: LCD 20x4 ñöôïc caáp nguoàn 5V ôû chaân soá 2, chaân 1 ñöôïc noái ñaát. Chaân soá 3 laø chaân ñieàu chænh ñoä töông phaûn thoâng qua bieán trôû tinh chænh VR6. Chaân 15 vaø chaân 16 laø chaân caáp nguoàn cho LED neàn, treân LCD, caùc LED naøy ñaõ ñöôïc gaén ñieän trôû haïn doøng neân caáp tröïc tieáp nguoàn 5V. Caùc chaân coøn laïi noái vôùi ATMega32 ñeå ñieàu khieån, cuï theå nhö sau: Chaân soá 4: RS noái vôùi chaân 22 PortC.0 Chaân soá 5: R/W noái vôùi chaân 23 PortC.1 Chaân soá 6: E noái vôùi chaân 24 PortC.2 Chaân soá 11: DB4 noái chaân 26 PortC.4 Chaân soá 12: DB5 noái chaân 27 PortC.5 Chaân soá 13: DB6 noái chaân 28 PortC.6 Chaân soá 14: DB7 noái chaân 29 PortC.7 Caùc chaân khoâng söû duïng ñöôïc noái ñaát goàm: chaân 7, 8, 9, 10 3.3. ADXL202E: ADXL202E ñöôïc cung caáp nguoàn nuoâi oån ñònh 5V, ñöôïc raùp rieâng beân ngoaøi so vôùi board maïch chính ñeå tieän vieäc ño ñaïc. 3.3.1. Sô ñoà maïch ñieän: Hình 3.3. Sô ñoà maïch keát noái sensor ADXL202E 3.3.1. Nguyeân lyù hoaït ñoäng: Jack caém J1 goàm coù 4 chaân ñeå keát noái ñeán board maïch chính, trong ñoù chaân 2 ñöôïc noái ñaát, chaân 1 nhaän nguoàn 5V töø IC oån aùp U5, qua cuoän loïc L1 caáp nguoàn cho sensor hoaït ñoäng. Vì ñeà taøi duøng ngoõ ra analog cuûa sensor neân ngoõ ra xung soá töø chaân 4 vaø 5 khoâng ñöôïc söû duïng. Tuy nhieân ñeå tieän trong quaù trình kieåm tra loãi sau khi laép raùp, hai chaân naøy ñöôïc ñöa ra socket J2 chaân ñeå ño kieåm treân ocsillocope. Chaân soá 2 gaén vôùi hai ñieän trôû noái tieáp R1 vaø R2 ñeå coù ñöôïc trò soá 250K duøng ñònh khoaûng T2 cho ngoõ ra xung soá. Chaân 6 vaø chaân 7 laø ngoõ ra analog, ñöôïc noái vôùi socket J1 noái veà board maïch chính. Taïi 2 chaân naøy ñöôïc noái vôùi 2 tuï C1 vaø C2, hai tuï naøy keát hôïp vôùi ñieän trôû noäi taïo thaønh mac dao ñoäng RC vaø laáy ñieän aùp ngoõ ra analog. Ngay caû trong tröôøng hôïp chæ söû duïng ngoõ ra soá thì hai tuï naøy vaãn phaûi ñöôïc laép ñaët. 3.4. ATMega32: ATMega32 laø Vi ñieàu khieån xöû lyù trung taâm ñöôïc laép treân board maïch chính. 3.4.1. Sô ñoà maïch ñieän: Hình 3.4. Sô ñoà maïch ATMega32 3.4.2. Nguyeân lyù hoaït ñoäng: ATMega32 ñöôïc caáp nguoàn 5V vaøo chaân soá 10, loïc nguoàn bôûi tuï C4, chaân soá 11 noái ñaát. Chaân soá 30 AVcc laáy ñieän aùp so saùnh thoâng qua cuoän loïc nhieãu L1 vaø tuï loïc C5, chaân 31 vaø chaân noái ñaát vôùi nguoàn aùp maãu Avcc, chaân AVREF noái vôùi ñaáât thoâng qua tuï C3. Tuï C3 duøng loïc nhieãu trong tröôøng hôïp söû duïng ñieän aùp tham chieáu noäi cho boä bieán ñoåi ADC. Hai chaân 12 vaø 13 ñöôïc noái vôùi thaïch anh duøng taïo xung dao ñoäng cho ATMega32, hai tuï C1 vaø C2 coù trò coá nhoû duøng ñeå loïc nhieãu ôû taàn soá cao. Tuy nhieân trong ñeà taøi naøy, uC söû duïng dao ñoäng noäi neân thaïch anh khoâng söû duïng ñeán, nhöng trong quaù trình vieát chöông trình caàn set caùc fuse bit neân thaïch anh naøy vaãn ñöôïc laép ñeà phoøng trong tröôøng hôïp set sai hoaëc disable nhaàm SPI khoâng theå naïp noái tieáp ñöôïc maø phaûi duøng cheá ñoä naïp HV (hight voltage) 3.5. SD Card: Ñeà taøi naøy söû duïng MicroSD, ñaây cuõng chính laø SD card nhöng coù hình daïng vaø socket nhoû goïn. 3.5.1. Sô ñoà maïch ñieän: Hình 3.5. Sô ñoà maïch SD Card 3.5.2. Nguyeân lyù hoaït ñoäng: SD Card ñöôïc caáp nguoàn 3,3V töø IC oån aùp U3 vaøo chaân soá 4, caùc chaân 6, 9, 10 ñöôïc noái ñaát. Caùc chaân 2, 3, 5 ñöôïc noái vôùi ATMega32 qua caùc ñieän trôû duøng caàu phaân aùp ñeå töông thích möùc logic. Caùc chaân noái vôùi ATMega32 cuï theå nhö sau: Chaân 2: CS noái vôùi chaân 5 PortB.4 Chaân 3: MOSI noái vôùi chaân 6 PortB.5 Chaân 5: SCK noái vôùi chaân 8 PortB.7 Chaân 7: MISO noái vôùi chaân 7 PortB.6 Do chaân MISO chæ nhaän möùc logic ñeán neân khoâng caàn ñieän trôû ñeå chia aùp. 3.6. Max232: Ñeå môû roäng vieäc giao tieáp vaø xöû lyù soá lieäu khi phaùt trieån ñeà taøi, maïch ñöôïc laép theâm IC chuyeån ñoåi möùc logic MAX232 ñeå giao tieáp baát ñoàng boä vôùi maùy tính thoâng qua coång COM. 3.6.1 Sô ñoà maïch ñieän: Hình 3.6. Sô ñoà maïch MAX232 3.6.2. Nguyeân lyù hoaït ñoäng: Do maïch thieát keá hoaït ñoäng vôùi ñieän aùp 5V, coù möùc logic 0-1. Trong khi ñoù giao tieáp coång COM vôùi maùy tính laïi coù caùc möùc ñieän aùp ± 12V, do ñoù caàn coù IC chuyeån ñoåi ñieän aùp ôû ngoõ vaøo vaø ra, caùc trò soá linh kieän ñöôïc söû duïng theo maéc ñònh cuûa nhaø saûn xuaát, nguoàn cung caáp 5V sau oån aùp. Chaân 13 vaø chaân 11 noái vôùi ATMega32, chaân 12 vaø 14 noái vôùi socket neát noái chuaån DB9. 3.7. Phím nhaán: Maùy ño gia toác coù caùc phím nhaán ñeå caøi ñaët thoâng soá hoaït ñoäng, do caùc Port cuûa ATMega32 coøn dö khaù nhieàu neân caùc phím baám naøy ñöôïc noái tröïc tieáp ñeán caùc port troáng, sô ñoà maïch nhö hình 3.7 Hình 3.7. Sô ñoà maïch phím nhaán Ngoõ ra bình thöôøng seõ coù möùc logic 1 do caùc ñieän trôû keùo leân R2, R3, R4. Khi phím ñöôïc nhaán seõ coù möùc logic 0. Söû duïng möùc tích cöïc 0 coù ñieåm lôïi laø khaû naêng khaùng nhieãu trong tröôøng hôïp caùc phím khoâng ñöôïc nhaán. CHÖÔNG 4 COÂNG CUÏ LAÄP TRÌNH VAØ GIAÛI THUAÄT Ñeå laäp trình caùc Vi ñieàu khieån , thoâng thöôøng söû duïng ngoân ngöõ caáp thaáp Asembler, tuy nhieân vôùi caùc chöông trình coù ñoä daøi code lôùn thì vieäc debug kieåm loãi seõ khoâng ñöôïc thuaän lôïi. Do ñoù, ñeå tieän lôïi hôn khi laäp trình, xu höôùng thöôøng löïa choïn caùc ngoân ngöõ baäc cao nhö C, Pascal, Basic, sau ñoù thoâng qua phaàn meàm cuûa haõng thöù 3 ñeå bieân dòch sang maõ maø Vi ñieàu khieån hieåu ñöôïc theo tieâu chuaån nhaø saûn xuaát. Öùu ñieåm cuûa vieäc söû duïng ngoân ngöõ laäp trình caáp cao laø ñôn giaûn, deã hieåu do tính gaàn guõi vaø tröïc quan, khuyeát ñieåm laø maõ sinh ra thöôøng coù dung löôïng lôùn hôn khi laäp trình baèng ngoân ngöõ caáp thaáp. ATMega32 laø vi ñieàu khieån hoï AVR, coù nhieàu chöông trình hoã trôï laäp trình baèng ngoân ngöõ C nhö: CodeVisionAVR: Ñaây laø phaàn meàm thöông maïi, hoã trôï laäp trình baèng ngoân ngöõ C, coù trình sinh maõ töï ñoäng, ñôn giaûn, thö vieän keøm theo khaù nhieàu. WinAVR: Ñaây laø phaàn meàm mieãn phí maõ nguoàn môû, ngoaøi vieäc söû duïng chöông trình ñôn, phaàn meàm naøy coøn laø moät plugin khaù maïnh ñöôïc haõng Atmel hoã trôï raát toát baèng phaàn meàm AVR Studio 4.. AVR Studio 4: Phaàn meàm mieãn phí cuûa haõng Atmel, hoã trôï laäp trình baèng ngoân ngöõ ASM, tuy nhieân neáu keát hôïp vôùi AVR nhö moät plugin, phaàn meàm naøy trôû neân khaù maïnh vaø tröïc quan. Trong ñeà taøi naøy, toâi söû duïng phaàn meàm WinAVR vaø AVR Studio 4 ñeå vieát maõ leänh. 4.1. Giôùi thieäu phaàn meàm WinAVR: WinAVR (ñoïc laø Whenever: theo taùc giaû cuûa WinAVR) laø moät boä phaàn meàm maõ nguoàn môû bao goàm caùc coâng cuï cho doøng vi ñieàu khieån AVR . WinAVR chaïy treân neàn heä ñieàu haønh Windows, noù bao goàm caùc coâng cuï sau: Trình bieân dòch avr-gcc: GNU GCC laø trình bieân dòch C, C++ phaùt trieån bôûi coäng ñoàng maõ nguoàn môû GNU, avr-gcc phaùt trieån rieâng cho AVR. Chöông trình naïp chip avrdude. Chöông trình debugger avr-gdb. Programmer Notepad: trình bieân taäp code hoã trôï nhieàu ngoân ngöõ nhö C, C++, CSS, HTML, Java,… MFile: tieän ích taïo caùc file Makefile duøng trong quaù trình bieân dòch code… Coát loõi cuûa WinAVR laø trình bieân dòch GNU GCC vaø thö vieän avr-libc, ñaây laø boä coâng cuï laäp trình C mieãn phí hoaøn chænh duy nhaát cho AVR. Coù theå noùi boä coâng cuï naøy goùp phaàn khoâng nhoû giuùp cho chip AVR ngaøy caøng trôû neân phoå bieán. WinAVR lieân tuïc ñöôïc caäp nhaät vaø hoaøn thieän bôûi raát nhieàu ngöôøi, nguoàn taøi lieäu vaø chöông trình maãu vieát baèng coâng cuï naøy laø raát lôùn… Moät soá hình aûnh veà giao dieän cuûa chöông trình: Hình 4.1. Giao dieän Programmer Notepad Hình 4.2. Hoäp thoaïi tuyø choïn Hình 4.3. Hoäp thoaïi caáu hình caùch thöùc bieân dòch 4.2. Giôùi thieäu phaàn meàm AVR Studio: Ñaây laø moät chöông trình bieân dòch miễn phí do haõng Atmel cung caáp. Chöông trình bieân dòch naøy tuy khoâng coù saün nhieàu code vaø hoã trôï phaàn cöùng, nhöng ñöôïc söû duïng thoâng duïng vaø phoå bieán do caùc ví duï vieát baèng avr-gcc khaù nhieàu , do miễn phí neân haàu heát caùc laäp trình vieân nöôùc ngoaøi ñeàu duøng. Moät soá tính naêng tieâu bieåu: Hoã trôï ngoân ngöõ ASM vaø C Hoã trôï KIT phaùt trieån do Atmal phaân phoái Hoã trôï debug tröïc tieáp Thöông thích nhieàu loaïi maïch naïp raát tieän lôïi Ñöôïc caäp nhaät thöôøng xuyeân töø chính haõng Moät soá hình aûnh veà giao dieän chöông trình: Hình 4.4. Logo chöông trình Hình 4.5. Hoäp thoaïi taïo project môùi Hình 4.6. Khung chính cuûa chöông trình 4.3. Giaûi thuaät chöông trình chính: Löu keát quaû vaøo SD Card Hieån thò ra LCD Phím No Yes Thieát laäp ADC Thieát laäp SPI Thieát laäp USART Khôûi taïo LCD Khôûi taïo SD Card Ñoïc sensor Baét ñaàu Thieát laäp Port: PORTA: Ngoõ vaøo ADC PORTC: Giao tieáp LCD PORTB: Keát noái SD Card CHÖÔNG 5 THÖÏC HIEÄN CHÖÔNG TRÌNH 5.1. LCD 20x4: 5.1.1. Chöông trình con xuaát moät kyù töï: void LCDchar(uint8_t ch) { LDP=(ch&0b11110000); LCP|=1<<LCD_RS; LCP|=1<<LCD_E; _delay_ms(1); LCP&=~(1<<LCD_E); LCP&=~(1<<LCD_RS); _delay_ms(1); LDP=((ch&0b00001111)<<4); LCP|=1<<LCD_RS; LCP|=1<<LCD_E; _delay_ms(1); LCP&=~(1<<LCD_E); LCP&=~(1<<LCD_RS); _delay_ms(1); } Tham soá: maõ ascci kyù töï caàn hieån thò Keát quaû traû veà: khoâng coù 5.1.2. Chöông trình con göûi leänh ñeán LCD: void LCDsendCommand(uint8_t cmd) { LDP=(cmd&0b11110000); LCP|=1<<LCD_E; _delay_ms(1); LCP&=~(1<<LCD_E); _delay_ms(1); LDP=((cmd&0b00001111)<<4); LCP|=1<<LCD_E; _delay_ms(1); LCP&=~(1<<LCD_E); _delay_ms(1); } Tham soá: Maõ leänh caàn göûi Keát quaû traû veà: khoâng coù 5.1.3. Chöông trình con khôûi taïo LCD: LCD khôûi taïo vôùi cheá ñoä giao tieáp 4 bit döõ lieäu void LCDInit(void) { _delay_ms(15); LDP=0x00; LCP=0x00; LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4; LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS; LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS; _delay_ms(1); LCP&=~(1<<LCD_E); _delay_ms(1); LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS; _delay_ms(1); LCP&=~(1<<LCD_E); _delay_ms(1); LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4; LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS; _delay_ms(1); LCP&=~(1<<LCD_E); _delay_ms(1); LCDsendCommand(0b00101000); LCDsendCommand(0b00001100); uint8_t ch=0, chn=0; while(ch<64) { LCDdefinechar((LcdCustomChar+ch),chn++); ch=ch+8; } } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.1.4. Chöông trình con xoaù LCD: void LCDclr(void) { LCDsendCommand(1<<LCD_CLR); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.1.5. Chöông trình con ñöa con troû veà ñaàu doøng: void LCDhome(void) { LCDsendCommand(1<<LCD_HOME); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.1.6. Chöông trình con hieån thò chuoãi kyù töï: void LCDstring(char* data) { register uint8_t i, nBytes; if (!data) return; nBytes = strlen(data); for(i=0; i<nBytes; i++) { LCDchar((uint8_t)data[i]); } } Tham soá: Chuoãi caàn hieån thò coù ñoä daøi toát ña 20 kyù töï Keát quaû traû veà: Khoâng coù 5.1.7. Chöông trình con di chuyeån con troû ñeán vò trí X-Y: void LCDGotoXY(uint8_t x, uint8_t y) { register uint8_t DDRAMAddr; switch(y) { case 0: DDRAMAddr = Line0_DDRAMADDR+x; break; case 1: DDRAMAddr = Line1_DDRAMADDR+x; break; case 2: DDRAMAddr = Line2_DDRAMADDR+x; break; case 3: DDRAMAddr = Line3_DDRAMADDR+x; break; default: DDRAMAddr = Line0_DDRAMADDR+x; } LCDsendCommand(1<<LCD_DDRAM | DDRAMAddr); } Tham soá: - Toaï ñoä X - Toaï ñoä Y Keát quaû traû veà: khoâng coù 5.1.8. Chöông trình con hieån thò chuoãi löu trong Flash: void LCDstringF(const uint8_t *FlashLoc, uint8_t x, uint8_t y) { uint8_t i; LCDGotoXY(x,y); for(i=0;(uint8_t)pgm_read_byte(&FlashLoc[i]);i++) { LCDchar((uint8_t)pgm_read_byte(&FlashLoc[i])); } } Tham soá: - Maûng kyù töï löu trong flash - Toaï ñoä X - Toaï ñoä Y Keát quaû traû veà: Khoâng coù 5.1.9. Chöông trình con hieån thò kyù töï ñöôïc ñònh nghóa rieâng: void LCDdefinechar(const uint8_t *pc,uint8_t char_code){ uint8_t a, pcc; uint16_t i; a=(char_code<<3)|0x40; for (i=0; i<8; i++) { pcc=pgm_read_byte(&pc[i]); LCDsendCommand(a++); LCDchar(pcc); } } Tham soá: - Maûng löu kyù töï töï ñònh nghóa goàm 8 kyù töï - Soá thöù töï kyù töï caàn hieån thò Keát quaû traû veà: Khoâng coù 5.1.10. Chöông trình con hieån thò soá: void LCDNum(unsigned char x,unsigned char y,unsigned int n) { unsigned char a,b,c,d; a=n/1000; b=(n-1000*a)/100; c=(n-1000*a-100*b)/10; d=n-1000*a-100*b-10*c; LCDGotoXY(x,y); LCDchar(a+48); LCDchar(b+48); LCDchar(c+48); LCDchar(d+48); } Tham soá: - Toaï ñoä X - Toaï ñoä Y - Soá hieån thò coù 4 chuõ soá Keát quaû traû veà: Khoâng coù 5.2. ADXL202E: 5.2.1. Chöông trình con khôûi taïo cheá ñoä ADC: void ADCInit() { ADMUX=ADC_VREF_TYPE & 0xFF; ADCSRA=0x83; PORTA=0x00; DDRA=0x00; } Tham soá: Khoâng coù Keát quaû traû veà: khoâng coù 5.2.2. Chöông trình con ñoïc giaù trò chuyeån ñoåi ADC theo keânh ñaàu vaøo: uint16_t ReadADC(unsigned char adc_channel) { ADMUX=adc_channel | (ADC_VREF_TYPE & 0xff); _delay_us(10); ADCSRA|=0x40; while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCW; } Tham soá: soá keânh caàn ñoïc (0..7) Keát quaû: Giaù trò chuyeån ñoåi kieåu khoâng daáu 16 bit 5.2.3. Chöông trình con tính gia toác vôùi keát quaû chuyeån ñoåi: void TinhGiaToc(unsigned int n) { unsigned char i=0, flag, tmp1=0, tmp2=0, a, b, c, d; unsigned int t=0, Gchan, Gle, Ketqua=0; unsigned char KQStr[5]=" "; if(n>=511) { flag=1; t=n-511; t=t; } if(n<511) { flag=0; t=511-n; t=t; } tmp1=t/60; Gchan=((tmp1*98))*10; tmp2=t%60; Gle=(((tmp2*100)/60)*98)/10; Ketqua=Gchan+Gle; a=Ketqua/1000; b=(Ketqua-1000*a)/100; c=(Ketqua-1000*a-100*b)/10; d=Ketqua-1000*a-100*b-10*c; KQStr[0]=a+48; KQStr[1]=b+48; KQStr[2]=0x2E; KQStr[3]=c+48; KQStr[4]=d+48; for(i=0;i<5;i++) GTam[i]=KQStr[i]; } Tham soá: Giaù trò khoâng daáu 16 bit Keát quaû traû veà: Gia toác (m/s2) kieåu chuoãi löu trong maûng bieát toaøn cuïc 5.2.4. Chöông trình con löu keát quaû ño gia toác 2 keânh XY: Löu keát quaû löu gia toác 2 keânh X-Y sau jhi ñaõ chuyeån ñoåi vaø tính toaùn vaøo hai bieán maûng kieåu chuoãi, 2 maûng naøy khia baùo vôùi bieán toaøn cuïc. void GiaToc2Array() { unsigned char i=0; TinhGiaToc(ReadADC(0)); for(i=0;i<5;i++) GX[i]=GTam[i]; TinhGiaToc(ReadADC(1)-40); for(i=0;i<5;i++) GY[i]=GTam[i]; } Tham soá: Khoâng coù Keát quaû traû veà: khoâng coù 5.2.5. Chöông trình con kieåm tra hoaït ñoäng sensor ADXL202E: Chöông trình hieån thò giaù trò gia toác 2 keânh leân maøn mình LCD, muïc ñích kieåm trang hoaït ñoäng cuûa sensor. Ñoä nhaïy ñöôïc caøi ñaët 100ms. void TestSensor() { unsigned char i=0; GiaToc2Array(); LCDGotoXY(5,0); LCDstring(""); LCDGotoXY(6,1); LCDchar(0x58); LCDGotoXY(12,1); LCDchar(0x59); LCDGotoXY(9,2); LCDchar(0x3A); for(i=0;i<5;i++) { LCDGotoXY(i+4,2); LCDchar(GX[i]); LCDGotoXY(i+10,2); LCDchar(GY[i]); } _delay_ms(100); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.2.6. Chöông trình con chuyeån giaù trò hai keânh vaøo maûng SD: Löu giaù trò hai keânh vaøo maûng theo ñònh daïng ñeå löu vaøo SD Card. void GiaToc2ArrSD() { unsigned char i=0; GiaToc2Array(); Save2SD[0]=0x3B; Save2SD[1]=0x24; for(i=2;i<7;i++) Save2SD[i]=GX[i-2]; Save2SD[7]=0x3A; for(i=8;i<13;i++) Save2SD[i]=GY[i-8]; Save2SD[13]=0x7E; } Tham soá : Khoâng coù Keát quaû traû veà: Khoâng coù 5.3. SPI: 5.3.1. Chöông trình con khôûi taïo SPI: Khôûi taïo SPI vôùi taàn soá SCK 125KHz, Bit cao chuyeån tröôùc roài ñeán bit thaáp void spi_init(void) { SPCR = 0x52; SPSR = 0x00; } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.3.2. Chöông trình con göûi moät byte döõ lieäu: unsigned char SPI_transmit(unsigned char data) { SPDR = data; while(!(SPSR & (1<<SPIF))); data = SPDR; return(data); } Tham soá: Gia trò caàn truyeàn Keát quaû traû veà: Döõ lieäu nhaän ñöôïc 5.3.3. Chöông trình con nhaän moät byte döõ lieäu: unsigned char SPI_receive(void) { unsigned char data; SPDR = 0xff; while(!(SPSR & (1<<SPIF))); data = SPDR; return data; } Tham soá: Khoâng coù Keát quaû traû veà: Döõ lieäu nhaän ñöôïc. 5.4.. SD Card: 5.4.1. Chöông trình con khôûi taïo cheá ñoä giao tieáp vôùi SD Card: unsigned char SDInit(void) { unsigned char i, response, retry=0 ; SD_CS_ASSERT; do { for(i=0;i<10;i++) SPI_transmit(0xff); response = SD_sendCommand(GO_IDLE_STATE, 0); retry++; if(retry>0xfe) { return 1; } } while(response != 0x01); SD_CS_DEASSERT; SPI_transmit (0xff); SPI_transmit (0xff); retry = 0; do { response = SD_sendCommand(SEND_OP_COND, 0); response = SD_sendCommand(SEND_OP_COND, 0); retry++; if(retry>0xfe) return 1; } while(response); SD_sendCommand(CRC_ON_OFF, OFF); SD_sendCommand(SET_BLOCK_LEN, 512); return 0; } Tham soá: Khoâng coù Giaù trò traû veà: -0 neáu quaù trình khôûi taïo thaønh coâng -1 neáu quaù trình khôûi taïo thaát baïi 5.4.2. Chöông trình con göûi leänh ñeán SD Card, nhaän giaù trò traû veà: unsigned char SD_sendCommand(unsigned char cmd, unsigned long arg) { unsigned char response, retry=0; SD_CS_ASSERT; SPI_transmit(cmd | 0x40); SPI_transmit(arg>>24); SPI_transmit(arg>>16); SPI_transmit(arg>>8); SPI_transmit(arg); SPI_transmit(0x95); while((response = SPI_receive()) == 0xff) if(retry++ > 0xfe) break; SPI_receive(); SD_CS_DEASSERT; return response; } Tham soá: Maõ leänh caàn gôûi ñeán SD Card Keát quaû traû veà: Giaù trò SD card baùo veà uC 5.4.3. Chöông trình con xoaù moät block cuûa SD Card: unsigned char SD_erase (unsigned long startBlock, unsigned long totalBlocks) { unsigned char response; response = SD_sendCommand(ERASE_BLOCK_START_ADDR, startBlock<<9); if(response != 0x00) return response; response = SD_sendCommand(ERASE_BLOCK_END_ADDR, (startBlock + totalBlocks - 1)<<9); if(response != 0x00) return response; response = SD_sendCommand(ERASE_SELECTED_BLOCKS, 0); if(response != 0x00) return response; return 0; } Tham soá: - Giaù trò baét ñaàu block - Soá block caàn xoaù Keát quaû traû veà: 0 neáu quaù trình xoaù block thaønh coâng, maõ loãi neáu khoâng thaønh coâng 5.4.3. Chöông trình con ñoïc moät block cuûa SD Card: unsigned char SD_readSingleBlock(unsigned long startBlock) { unsigned char response; unsigned int i, retry=0; response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock<<9); if(response != 0x00) return response; SD_CS_ASSERT; retry = 0; while(SPI_receive() != 0xfe) if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } for(i=0; i<512; i++) buffer[i] = SPI_receive(); SPI_receive(); SPI_receive(); SPI_receive(); SD_CS_DEASSERT; return 0; } Tham soá: Giaù trò block caàn ñoïc noäi dung Keát quaû traû veà: - 0 neáu quaù trình ñoïc thaønh coâng - 1 neáu quaù trình ñoïc khoâng thaønh coâng, quaù thôøi gian ñoïc - Maõ loãi neáu quaù trình ñoïc thaát baïi 5.4.3. Chöông trình con ghi moät block leân SD Card: unsigned char SD_writeSingleBlock(unsigned long startBlock) { unsigned char response; unsigned int i, retry=0; response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock<<9); if(response != 0x00) return response; SD_CS_ASSERT; SPI_transmit(0xfe); for(i=0; i<512; i++) SPI_transmit(buffer[i]); SPI_transmit(0xff); SPI_transmit(0xff); response = SPI_receive(); if( (response & 0x1f) != 0x05) { SD_CS_DEASSERT; return response; } while(!SPI_receive()) if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } SD_CS_DEASSERT; SPI_transmit(0xff); SD_CS_ASSERT; while(!SPI_receive()) if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } SD_CS_DEASSERT; return 0; } Tham soá: Giaù trò baét ñaàu cuûa block Keát quaû traû veà: - 0 neáu quaù trình ghi thaønh coâng - 1 neáu quaù trình ghi thaát baïi - Maõ loãi khaùc traû veà töø SD Card 5.5. FAT32: 5.5.1. Chöông trình con ñoïc thoâng tin ban ñaàu cuûa Boot Sector: Ñoïc caùc thoâng tin caàn thieát cuûa Boot Sector, löu taát caû vaøo bieán toaøn cuïc unsigned char getBootSectorData (void) { struct BS_Structure *bpb; struct MBRinfo_Structure *mbr; struct partitionInfo_Structure *partition; unsigned long dataSectors; unusedSectors = 0; SD_readSingleBlock(0); bpb = (struct BS_Structure *)buffer; if(bpb->jumpBoot[0]!=0xE9 && bpb->jumpBoot[0]!=0xEB) { mbr = (struct MBRinfo_Structure *) buffer; if(mbr->signature != 0xaa55) return 1; partition = (struct partitionInfo_Structure *) (mbr->partitionData); unusedSectors = partition->firstSector; SD_readSingleBlock(partition->firstSector); bpb = (struct BS_Structure *)buffer; if(bpb->jumpBoot[0]!=0xE9 && bpb->jumpBoot[0]!=0xEB) return 1; } bytesPerSector = bpb->bytesPerSector; sectorPerCluster = bpb->sectorPerCluster; reservedSectorCount = bpb->reservedSectorCount; rootCluster = bpb->rootCluster; firstDataSector = bpb->hiddenSectors + reservedSectorCount + (bpb->numberofFATs * bpb->FATsize_F32); dataSectors = bpb->totalSectors_F32 - bpb->reservedSectorCount - ( bpb->numberofFATs * bpb->FATsize_F32); totalClusters = dataSectors / sectorPerCluster; if((getSetFreeCluster (TOTAL_FREE, GET, 0)) > totalClusters) freeClusterCountUpdated = 0; else freeClusterCountUpdated = 1; return 0; } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.5.2. Chöông trình con laáy ñòa chæ cuûa sector ñaàu tieân cuûa baát kyø cluser: unsigned long getFirstSector(unsigned long clusterNumber) { return (((clusterNumber - 2) * sectorPerCluster) + firstDataSector); } Tham soá: soá cluster caàn laáy ñòa chæ sector Keát quaù traû veà: ñòa chæ sector ñaàu tieân cuûa cluster 5.5.3. Chöông trình con xöû lyù cluster: Chöùc naêng laáy giaù trò cluster töø baûng FAT vaø tìm cluster tieáp theo trong baûng FAT, hoaëc ñaët môùi moät cluster trong baûng FAT. unsigned long getSetNextCluster (unsigned long clusterNumber, unsigned char get_set, unsigned long clusterEntry) { unsigned int FATEntryOffset; unsigned long *FATEntryValue; unsigned long FATEntrySector; unsigned char retry = 0; FATEntrySector = unusedSectors + reservedSectorCount + ((clusterNumber * 4) / bytesPerSector) ; FATEntryOffset = (unsigned int) while(retry <10) { if(!SD_readSingleBlock(FATEntrySector)) break; retry++; } FATEntryValue= (unsigned long *) &buffer[FATEntryOffset]; if(get_set == GET) return ((*FATEntryValue) & 0x0fffffff); *FATEntryValue = clusterEntry; SD_writeSingleBlock(FATEntrySector); return (0); } Tham soá: - Giaù trò cluster hieän thôøi - GET/SET : GET neáu cluster tieáp theo ñöôïc tìm thaáy, SET neáu cluster tieáp theo ñöôïc thieát laäp. - Soá cluster tieáp theo neáu tham soá thöù 2 laø laø set, ngöôïc laïi laø 0 Keát quaû traû veà: giaù trò cluster tieáp theo neáu thoâng soá thöù hai laø GET, ngöôïc laïi laø 0 5.5.4. Chöông trình con ñoïc toång soá cluster troáng hoaëc laáy cluster troáng tieáp theo: unsigned long getSetFreeCluster(unsigned char totOrNext, unsigned char get_set, unsigned long FSEntry) { struct FSInfo_Structure *FS = (struct FSInfo_Structure *) &buffer; unsigned char error; SD_readSingleBlock(unusedSectors + 1); if((FS->leadSignature != 0x41615252) || (FS->structureSignature != 0x61417272) || (FS->trailSignature !=0xaa550000)) return 0xffffffff; if(get_set == GET) { if(totOrNext == TOTAL_FREE) return(FS->freeClusterCount); else return(FS->nextFreeCluster); } else { if(totOrNext == TOTAL_FREE) FS->freeClusterCount = FSEntry; else FS->nextFreeCluster = FSEntry; error = SD_writeSingleBlock(unusedSectors + 1); } return 0xffffffff; } Tham soá: - TOTAL_FREE/NEXT_FREE - SET/GET - FS entry môùi, khi tham soá thöù 2 laø SET hoaëc 0, khi tham soá thöù 2 laø GET Keát quaû traû veà: - cluster troáng keá tieáp, neáu tham soá thöù 1 laø NEXT_FREE vaø tham soá thöù hai laø GET - Toång soá cluser troáng neáu tham soá thöù 1 laø TOTAL_FREE vaø tham soá thöù hai laø GET - 0xFFFFFFFF, neáu coù baát kyø loãi naøo hoaëc tham soá thöù hai laø SET. 5.5.5. Chöông trình con xöû lyù taäp tin: Cho pheùp ñoïc danh saùch thö muïc, taäp tin, ñòa chæ löu tröõ taäp tin, taäp tin toàn taïi hay ñaõ bò xoaù, xoaù taäp tin. struct dir_Structure* findFiles (unsigned char flag, unsigned char *fileName) { unsigned long cluster=0, sector=0, firstSector=0; struct dir_Structure *dir; unsigned int i=0; unsigned char j=0; cluster = rootCluster; //root cluster while(1) { firstSector = getFirstSector (cluster); for(sector = 0; sector < sectorPerCluster; sector++) { SD_readSingleBlock (firstSector + sector); for(i=0; i<bytesPerSector; i+=32) { dir =(struct dir_Structure *) &buffer[i]; if((dir->name[0] != DELETED)&& (dir->attrib != ATTR_LONG_NAME)) { if(flag == GET_FILE) { for(j=0; j<11; j++) if(dir->name[j]!= fileName[j]) break; if(j == 11) { if(flag == GET_FILE) { appendFileSector = firstSector + sector; appendFileLocation = i; appendStartCluster = (((unsigned long) dir->firstClusterHI) << 16) | dir->firstClusterLO; fileSize = dir- >fileSize; return (dir); } } } else { LCDGotoXY(5,0); for(j=0; j<11; j++) { if(j == 8) LCDstring("."); if(dir->name[j] !=0x20) LCDchar(dir- >name[j]); } if((dir->attrib!=0x10) && (dir->attrib!= 0x08)) { LCDGotoXY(5,1); displayMemory (dir- >fileSize); } } } } } cluster = (getSetNextCluster (cluster, GET, 0)); if(cluster > 0x0ffffff6) return 0; if(cluster == 0) return 0; } return 0; } Tham soá: - Côø: GET_LIST, GET_FILE, DELETE Keát quaû traû veà: - Cluster ñaàu tieân cuûa taäp tin - Danh saùch thö muïc - Danh saùch taäp tin 5.5.6. Chöông trình con chuyeån teân file theo ñònh daïng FAT ñeå xöû lyù: unsigned char convertFileName (unsigned char *fileName) { unsigned char fileNameFAT[11]; unsigned char j, k; for(j=0; j<12; j++) if(fileName[j] == '.') break; if(j>8) return 1; for(k=0; k<j; k++) fileNameFAT[k] = fileName[k]; for(k=j; k<=7; k++) fileNameFAT[k] = ' '; j++; for(k=8; k<11; k++) { if(fileName[j] != 0) fileNameFAT[k] = fileName[j++]; else while(k<11) fileNameFAT[k++] = ' '; } for(j=0; j<11; j++) if((fileNameFAT[j] >= 0x61) && (fileNameFAT[j] <= 0x7a)) fileNameFAT[j] -= 0x20; for(j=0; j<11; j++) fileName[j] = fileNameFAT[j]; return 0; } Tham soá : teân taäp tin Keát quaû traû veà: - 0 neáu quaù trình chuyeån ñoåi thaønh coâng - 1 neáu quaù trình chuyeån ñoåi thaát baïi 5.5.7. Chöông trình con ñoïc toaøn boä noäi dung trong taäp tin: unsigned char readFile (unsigned char flag, unsigned char *fileName) { struct dir_Structure *dir; unsigned long cluster, byteCounter = 0, fileSize, firstSector; unsigned int k; unsigned char j, error; error = convertFileName (fileName); if(error) return 2; dir = findFiles (GET_FILE, fileName); if(dir == 0) return (0); if(flag == VERIFY) return (1); cluster = (((unsigned long) dir->firstClusterHI) << 16) | dir->firstClusterLO; fileSize = dir->fileSize; while(1) { firstSector = getFirstSector (cluster); for(j=0; j<sectorPerCluster; j++) { SD_readSingleBlock(firstSector + j); for(k=0; k<512; k++) { LCDchar(buffer[k]); if ((byteCounter++) >= fileSize ) return 0; } } cluster = getSetNextCluster (cluster, GET, 0); if(cluster == 0) return 0; } return 0; } Tham soá: - VERYFI: kieåm tra toàn taïi, READ: ñoïc noäi dung - Teân taäp tin Keát quaû traû veà: Khoâng 5.5.8. Chöông trình con ñoïc 4 keát quaû löu sau cuøng vaø xuaát ra LCD: unsigned char readFile4Line (unsigned char *fileName) { struct dir_Structure *dir; unsigned long cluster, byteCounter = 0, fileSize, firstSector; unsigned int k=0; unsigned char j=0, error=0, x = 9 , y = 0; error = convertFileName (fileName); if(error) return 2; dir = findFiles (GET_FILE, fileName); if(dir == 0) return (0); cluster = (((unsigned long) dir->firstClusterHI) << 16) | dir->firstClusterLO; fileSize = dir->fileSize; while(1) { firstSector = getFirstSector (cluster); for(j=0; j<sectorPerCluster; j++) { SD_readSingleBlock(firstSector + j); for(k=0; k<512; k++) { if (byteCounter >= (fileSize-50) ) { if (((buffer[k]) !=0x0D) && ((buffer[k]) !=0x0A) && ((buffer[k]) !=0x1A)) { LCDGotoXY(x,y); LCDchar(buffer[k]); x++; if (x>19) { x=9; y++; } } } byteCounter++; if (byteCounter >= fileSize ) return 0; } } cluster = getSetNextCluster (cluster, GET, 0); if(cluster == 0) return 0; } return 0; } Tham soá: Teân taäp tin Keát quaû traû veà: Khoâng coù 5.5.9. Chöông trình taïo File theo ñònh daïng FAT32 trong thö muïc goác: void writeFile (unsigned char *fileName, unsigned char *DataNew) { unsigned char n = 0, j, data, error, fileCreatedFlag = 0, start = 0, appendFile = 0, sector; unsigned int i, firstClusterHigh, firstClusterLow; struct dir_Structure *dir; unsigned long cluster, nextCluster, prevCluster, firstSector, clusterCount, extraMemory; j = readFile (VERIFY, fileName); if(j == 1) { appendFile = 1; cluster = appendStartCluster; clusterCount=0; while(1) { nextCluster = getSetNextCluster (cluster, GET, 0); if(nextCluster == EOF) break; cluster = nextCluster; clusterCount++; } sector = (fileSize - (clusterCount * sectorPerCluster * bytesPerSector)) / bytesPerSector; start = 1; } else if(j == 2) return; else { cluster = getSetFreeCluster (NEXT_FREE, GET, 0); if(cluster > totalClusters) cluster = rootCluster; cluster = searchNextFreeCluster(cluster); if(cluster == 0) return; getSetNextCluster(cluster, SET, EOF); firstClusterHigh = (unsigned int) ((cluster & 0xffff0000) >> 16 ); firstClusterLow = (unsigned int) ( cluster & 0x0000ffff); fileSize = 0; } while(1) { if(start) { start = 0; startBlock =getFirstSector (cluster) + sector; SD_readSingleBlock (startBlock); i = fileSize % bytesPerSector; j = sector; } else { startBlock = getFirstSector (cluster); i=0; j=0; n=0; } do { data=DataNew[n]; if(data == ';') data=0x0D; if(data == '$') data=0x0A; buffer[i] = data; i++; n++; fileSize++; if(i == 512) { i=0; error = SD_writeSingleBlock (startBlock); j++; if(j == sectorPerCluster) { j = 0; break; } startBlock++; } }while (data != '~'); if(data == '~') { fileSize--; i--; for(;i<512;i++) buffer[i]= 0x00; error = SD_writeSingleBlock (startBlock); break; } prevCluster = cluster; cluster = searchNextFreeCluster(prevCluster); if(cluster == 0) return; getSetNextCluster(prevCluster, SET, cluster); getSetNextCluster(cluster, SET, EOF); } getSetFreeCluster (NEXT_FREE, SET, cluster); if(appendFile) { SD_readSingleBlock (appendFileSector); dir = (struct dir_Structure *) &buffer[appendFileLocation]; extraMemory = fileSize - dir->fileSize; dir->fileSize = fileSize; SD_writeSingleBlock (appendFileSector); freeMemoryUpdate (REMOVE, extraMemory); return; } prevCluster = rootCluster; // root cluster while(1) { firstSector = getFirstSector (prevCluster); for(sector = 0; sector < sectorPerCluster; sector++) { SD_readSingleBlock (firstSector + sector); for(i=0; i<bytesPerSector; i+=32) { dir =(struct dir_Structure *) &buffer[i]; if(fileCreatedFlag) { dir->name[0] = 0x00; return; } if((dir->name[0] == EMPTY) || (dir->name[0] == DELETED)) { for(j=0; j<11; j++) dir->name[j] = fileName[j]; dir->attrib = ATTR_ARCHIVE; dir->NTreserved = 0; dir->timeTenth = 0; dir->createTime = 0x9684; dir->createDate = 0x3a37; dir->lastAccessDate = 0x3a37; dir->writeTime = 0x9684; dir->writeDate= 0x3a37; dir>firstClusterHI = firstClusterHigh; dir->firstClusterLO = firstClusterLow; dir->fileSize = fileSize; SD_writeSingleBlock(firstSector +sector); fileCreatedFlag = 1; freeMemoryUpdate (REMOVE, fileSize); } } } cluster = getSetNextCluster (prevCluster, GET, 0); if(cluster > 0x0ffffff6) { if(cluster == EOF) { cluster = searchNextFreeCluster(prevCluster); getSetNextCluster(prevCluster, SET, cluster); getSetNextCluster(cluster, SET, EOF); } else return; } if(cluster == 0) return; prevCluster = cluster; } return; } Tham soá: Teân taäp tin Keát quaû traû veà: Khoâng coù 5.5.10. Chöông trình con ghi tieáp taäp tin: Ghi tieáp döõ lieäu vaøo beân döôùi taäp tin neáu taäp tin naøy ñaõ toàn taïi. void writeFileNext (unsigned char *fileName, unsigned char *DataNew) { unsigned char n = 1, j, data, error, start = 0, appendFile = 0, sector; unsigned int i; struct dir_Structure *dir; unsigned long cluster, nextCluster, prevCluster, clusterCount, extraMemory; j = readFile (VERIFY, fileName); if(j == 1) { appendFile = 1; cluster = appendStartCluster; clusterCount=0; while(1) { nextCluster = getSetNextCluster (cluster, GET, 0); if(nextCluster == EOF) break; cluster = nextCluster; clusterCount++; } sector = (fileSize - (clusterCount * sectorPerCluster * bytesPerSector)) / bytesPerSector start = 1; } else if(j == 2) { LCDGotoXY(0,0); LCDstring("Khong co File!"); return; } while(1) { if(start) { start = 0; startBlock =getFirstSector (cluster) + sector; SD_readSingleBlock (startBlock); i = fileSize % bytesPerSector; j = sector; n=1; } do { data=DataNew[n]; if(data == ';') data=0x0D; if(data == '$') data=0x0A; buffer[i++] = data; n++; fileSize++; if(i == 512) { i=0; error = SD_writeSingleBlock (startBlock); j++; if(j == sectorPerCluster) { j = 0; break; } startBlock++; } } while (data != '~'); if(data == '~') { fileSize--; i--; for(;i<512;i++) buffer[i]= 0x00; error = SD_writeSingleBlock (startBlock); break; } prevCluster = cluster; cluster = searchNextFreeCluster(prevCluster); if(cluster == 0) return; getSetNextCluster(prevCluster, SET, cluster); getSetNextCluster(cluster, SET, EOF); } getSetFreeCluster (NEXT_FREE, SET, cluster; if(appendFile) { SD_readSingleBlock (appendFileSector); dir = (struct dir_Structure *) &buffer[appendFileLocation]; extraMemory = fileSize - dir->fileSize; dir->fileSize = fileSize; SD_writeSingleBlock (appendFileSector); freeMemoryUpdate (REMOVE, extraMemory); return; } return; } Tham soá: Teân taäp tin Keát quaû traû veà: Khoâng coù 5.5.11. Chöông trình con tìm cluser troáng tieáp theo trong thö muïc goác: unsigned long searchNextFreeCluster (unsigned long startCluster) { unsigned long cluster, *value, sector; unsigned char i; startCluster -= (startCluster % 128); for(cluster=startCluster;cluster<totalClusters; cluster+=128) { sector = unusedSectors + reservedSectorCount + ((cluster * 4) / bytesPerSector); SD_readSingleBlock(sector); for(i=0; i<128; i++) { value = (unsigned long *) &buffer[i*4]; if(((*value) & 0x0fffffff) == 0) return(cluster+i); } } return 0; } Tham soá: Cluser ñaàu Keát quaû traû veà : Giaù trò cluser tieáp theo 5.5.12. Chöông trình con hieån thò dung löôïng theo Byte: void displayMemory (unsigned long memory) { unsigned char memoryString[] = " B"; unsigned char i; for(i=12; i>0; i--) { if(i == 5 || i == 9) { memoryString[i-1] = ','; i--; } memoryString[i-1] = (memory % 10) | 0x30; memory /= 10; if(memory == 0) break; } for(i=0;i<14;i++) LCDchar(memoryString[i]); } Tham soá: Giaù trò dung böôïng theo bit Keát quaû traû veà : Hieån thò dung löông baèng chuoãi treân LCD theo MB 5.5.13. Chöông trình con hieån trò dung löông theo Megabyte: void displayMBMemory (unsigned long memory) { unsigned char memoryString[] = " MB"; unsigned char i; memory /= 1024; for(i=8; i>0; i--) { if(i == 5 || i == 9) { memoryString[i-1] = ','; i--; } memoryString[i-1] = (memory % 10) | 0x30; memory /= 10; if(memory == 0) break; } for(i=0;i<10;i++) LCDchar(memoryString[i]); } Tham soá: Giaù trò dung böôïng theo bit Keát quaû traû veà : Hieån thò dung löông baèng chuoãi treân LCD theo MB 5.5.14. Chöông trình con hieån thò dung löôïng theû nhôù: void memoryStatistics (void) { unsigned long totalMemory, freeMemory, freeClusters, totalClusterCount, cluster; unsigned long sector, *value; unsigned int i; totalMemory=totalClusters * sectorPerCluster * bytesPerSector; LCDGotoXY(2,2); LCDstring("Tong : "); LCDGotoXY(9,2); displayMBMemory(totalMemory); freeClusters = getSetFreeCluster (TOTAL_FREE, GET, 0); if(freeClusters > totalClusters) { freeClusterCountUpdated = 0; freeClusters = 0; totalClusterCount = 0; cluster = rootCluster; while(1) { sector = unusedSectors + reservedSectorCount + ((cluster * 4) / bytesPerSector) ; SD_readSingleBlock(sector); for(i=0; i<128; i++) { value = (unsigned long *) &buffer[i*4]; if(((*value)& 0x0fffffff) == 0) freeClusters++;; totalClusterCount++; if(totalClusterCount = (totalClusters+2)) break; } if(i < 128) break; cluster+=128; } } if(!freeClusterCountUpdated) getSetFreeCluster (TOTAL_FREE, SET, freeClusters); freeClusterCountUpdated = 1; freeMemory = freeClusters * sectorPerCluster * bytesPerSector; LCDGotoXY(2,3); LCDstring("Trong: "); LCDGotoXY(9,3); displayMBMemory(freeMemory); } Tham soá : khoâng coù Keát quaû traû veà: Hieån thò dung löôïng toång cuûa theû SD vaø dung löôïng troáng coøn laïi. 5.5.15. Chöông trình con caäp nhaät dung löôïng troáng: Khi moät taäp tin ñöôïc taïo môùi hoaëc xoaù ñi, chöông trình con naøy seõ ñöôïc goïi ñeå caäp nhaät laïi dung löôïng troáng cuûa theû nhôù SD void freeMemoryUpdate (unsigned char flag, unsigned long size) { unsigned long freeClusters; if((size % 512) == 0) size = size / 512; else size = (size / 512) +1; if((size % 8) == 0) size = size / 8; else size = (size / 8) +1; if(freeClusterCountUpdated) { freeClusters =getSetFreeCluster(TOTAL_FREE, GET, 0); if(flag == ADD) freeClusters = freeClusters + size; else freeClusters = freeClusters - size; getSetFreeCluster (TOTAL_FREE, SET, freeClusters); } } Tham soá: - Côø traïng thaùi(REMOVE/ADD) - Dung löôïng hieän taïi Keát quaû traû veà: Khoâng coù 5.6. Chöông trình chính: 5.6.1. Caùc khai baùo thö vieän vaø bieán: #include #include #include #include #include "LCD20x4.h" #include "SPI_routines.h" #include "SD_routines.h" #include "UART_routines.h" #include "FAT32.h" #define F_CPU 8000000UL #define ADC_VREF_TYPE 0x40 const uint8_t Str01[] PROGMEM="Kiem tra..."; const uint8_t Str02[] PROGMEM=" "; const uint8_t Str03[] PROGMEM=" Tim thay: "; const uint8_t Str04[] PROGMEM=" Khong co: "; const uint8_t Str05[] PROGMEM=" "; const uint8_t Str06[] PROGMEM=" Thong tin "; const uint8_t Demo01[] PROGMEM="LUAN VAN TOT NGHIEP"; const uint8_t Demo02[] PROGMEM="De tai"; const uint8_t Demo03[] PROGMEM="May do Gia toc X-Y"; const uint8_t Demo04[] PROGMEM="GVHD"; const uint8_t Demo05[] PROGMEM="KS.DANG ANH TUAN"; const uint8_t Demo06[] PROGMEM="SVTH"; const uint8_t Demo07[] PROGMEM="HUYNH MINH NGUYEN"; unsigned char Save2SD[14]; unsigned char FileName[10]; unsigned char GTam[5]; unsigned char GX[5]; unsigned char GY[5]; 5.6.2. Chöông trình con khôûi taïo PORT: void PortInit() { PORTB = 0xEF; DDRB = 0xBF; } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.3. Chöông trình con khôûi taïo chung: void DevInit(void) { _delay_ms(10); PortInit(); LCDInit(); spi_init(); ADCInit(); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.5. Chöông trình con hieån thò thoâng tin löu trong Flash coù treã: void Display(unsigned char x, unsigned char y, unsigned int t, const uint8_t *st) { LCDstringF(st,x,y); _delay_ms(t); } Tham soá: - Toaï ñoä x - Toaï ñoä y - Thôøi gian treã t - Maûng löu chuoãi trong flash Keát quaû traû veà: Khoâng coù 5.6.6. Chöông trình con xoaù teân taäp tin löu trong boä ñeäm: void ClearFileName(void) { unsigned char i=0; for(i=0; i<10; i++) FileName[i] = 0x00; } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.7. Chöông trình con gaùn teân taäp tin cho maûng teân taäp tin laø bieán toaøn cuïc: void GetFileName(void) { unsigned char i=0; unsigned char str[10]="Result.dat"; for(i=0; i<10; i++) FileName[i] = str[i]; } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.8. Chöông trình con xöû lyù teân file trong maûng: void ReadFileName(void) { ClearFileName(); GetFileName(); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.9. Chöông trình con hieån thò thoâng tin ñeà taøi: void Demo() { Display(1,0,500,Demo01); Display(7,1,500,Demo02); Display(1,2,500,Demo03); _delay_ms(3000); LCDclr(); Display(8,0,500,Demo04); Display(2,1,500,Demo05); Display(8,2,500,Demo06); Display(1,3,500,Demo07); _delay_ms(5000); LCDclr(); } Tham soá: Khoâng coù Keát quaû traû veà: Khoâng coù 5.6.0. Chöông trình chính: int main(void) { unsigned char Error=0, FAT32_active,i; unsigned int DisTime=1000; DevInit(); LCDclr(); Demo(); Display(5,0,DisTime,Str01); Error=SDInit(); if(Error==1) { LCDclr(); Display(5,0,0,Str04); Display(5,1,DisTime,Str02); FAT32_active = 0; while(1); } LCDclr(); Display(5,0,0,Str03); Display(5,1,DisTime,Str02); SPI_HIGH_SPEED; _delay_ms(1); FAT32_active = 1; Error = getBootSectorData (); if(Error==1) { LCDclr(); Display(5,0,0,Str04); Display(5,1,DisTime,Str05); FAT32_active = 0; while(1); } LCDclr(); Display(5,0,0,Str03); Display(5,1,DisTime,Str05); LCDclr(); Display(5,0,0,Str06); Display(5,1,0,Str02); memoryStatistics(); _delay_ms(3000); LCDclr(); ReadFileName(); writeFileNext(FileName,GiaToc); ReadFileName(); readFile4Line(FileName); while(1) { TestSensor(); _delay_ms(100); } } CHÖÔNG 6 KEÁT LUAÄN 6.1. Nhöõng keát quaû ñaït ñöôïc: - Thieát keá vaø hoaøn thieän maùy ño gia toác hieån thò keát quaû tröïc tieáp treân LCD - Hieåu vaø thöïc hieän ñöôïc caùc chuaån giao tieáp I2C, SPI, USART, PWM - Naém vöõng kieán thöùc veà hoï Vi ñieàu khieån AVR - Söû duïng thaønh thaïo vieäc chuyeån ñoåi ADC - Söû duïng ñöôïc caùc moâi tröôøng laäp trình cho AVR nhö SDCC, WinAVR, Code Vision AVR - Töï xaây döïng caùc thö vieän rieâng cho caùc moâi tröôøng laäp trình AVR - Naém roõ caáu truùc vaø caùch thöùc ñieàu khieån vaø hoaït ñoäng cuûa theû nhôù 6.2 Nhöõng keát quaû chöa ñaït ñöôïc: - Chöa hieåu roõ caùch thöùc ghi vaø truy xuaát taäp tin treân ñònh daïng FAT32, phaûi chænh söûa thö vieän FAT32 töø boä thö vieän maõ nguoàn môû ñeå söû duïng. - Chöa choáng nhieãu cho sensor. - Chöa ñaët teân file töï do maø chæ ghi tieáp vaøo file ñaõ coù saün. 6.3. Höôùng phaùt trieån cho ñeà taøi: - Xaây döïng menu hoaøn chæ bao goàm caùc thao taùc: ñaët teân file, ghi keát quaû theo thôøi gian ñònh tröôùc, ghi moãi laàn moát soá luwojgn keát quaû caøi ñaët tröôùc. - Môû roäng vôùi ngoõ vaøo laø caùc loiaj sensor khaùc nhö: nhieät ñoä, ñoä aåm… ñöôïc chuyeån ñoåi baèng menu theå hieän treân LCD - Thay LCD text baèng Graphic LCD ñeå theå hieän tieáng Vieät coù daáu vaø veõ ñöôïc ñoà thò keát quaû ño ñöôïc theo thôøi gian. - Giao tieáp vôùi maùy tính ñeå ñoå döõ lieäu vaø xem keát quaû vôùi daïng ñoà thò. PHAÀN PHUÏ LUÏC

Các file đính kèm theo tài liệu này:

  • docxLuan Van tot nghiep.docx
  • rarCode.rar
  • docxLoi cam on.docx
  • docxLuu do.docx
  • docxMuc luc.docx
  • docxPhu luc.docx