báo cáo bài tập lớn môn vi điều khiển
DESCRIPTION
ênsssTRANSCRIPT
![Page 1: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/1.jpg)
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
ĐẠI HỌC QUỐC GIA HÀ NỘI
Khoa : Cơ học kỹ thuật và tự động hóa.
Ngành : Công nghệ Cơ điện tử.
BÀI TẬP LỚN VI ĐIỀU KHIỂN
Đề tài : Thiết kế mạch đồng hồ thời gian thực hiển thị led 7 đoạn.
Giáo viên hướng dẫn :
Sinh viên thực hiện :Nguyễn Mạnh Quân.
MSV:
Phạm Văn Tâm.
MSV:
Nguyễn Hữu Thưởng.
MSV: 09020507.
Lớp : K54M.
Hà nội ngày 14 tháng 11 năm 2012.
1
![Page 2: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/2.jpg)
MỤC LỤC
I. Mô tả hệ thống. …………………………………………………………….……3
II. Tổng quan về các khối……………………………………………….....3
III. Sơ đồ mạch nguyên lý và mạch in………………………………….....20
IV. Code của chương trình mô phỏng…………………………………….21
V. Kết quả mô phỏng…………………….……………………………….44
VI. Mức độ hoàn thành công việc và hướng phát triển....…………………45
VII. Các phần mềm sử dụng trong bài tập………………………………….45
VIII. Tài liệu tham khảo…………………………………….……………….45
2
![Page 3: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/3.jpg)
I. Mô tả hệ thống :
Đề tài nhằm thiết kế 1 bộ đồng hồ thời gian thực đảm bảo tự cập nhật thời gian của hệ thống và hiển thị giá trị lên LED 7SEG. Với thiết kế sử dụng cả nguồn ngoài và PIN VBat làm cho hệ thống hoạt động cả khi mất điện thì hệ thống thời gian thực vẫn hoạt động.
II. Tổng quan về các khối:
1. Tổng quan về ATmega8:
a) Một số đặc tính kỹ thuật.
3
![Page 4: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/4.jpg)
ATMega8 là một con Vi Điều Khiển thuộc dòng Mega AVR của hãng ATMEL. Dòng Vi Điều Khiển này có tính năng nổi trộ như:
32 thanh ghi đa dụng Tốc độ tối đa lên đến 16MIPS với thạch anh 16MHz Có 8KB bộ nhớ Flash lập trình ISP
o 512 byte EFPROM.
o 1k SRAM.
o Chu kỳ ghi/ xóa 10000 lần cho bộ nhớ flash ROM và 100000 lần
cho bộ nhớ EFPROM. Tính năng ngoại vi
o 2 bộ timer/counter 8 bít, 1 bộ so sánh.
o 1 bộ timer/counter 16 bit.
o Bô đếm thời gian thực với đao động riêng.
o 3 kênh PWM.
4
![Page 5: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/5.jpg)
o 6 kênh ADC 10 bits cho kiểu vỏ PDIP, 8 kênh ADC 10 bits cho
kiểu vỏ TQFP.o Giao tiếp nối tiếp TWI, 2 chân ngắt ngoài INT0 và INT1 ứng với 2
chân PD2 và PD3.o Lập trình nối tiếp USART, giao tiếp nối tiếp SPI master/slave.
o Bộ so sánh analog on-chip.
I/Oo 23 ngõ vào/ra khả trình.
o Được đóng gói trong 28 chân kiểu vỏ PDIP.
o Điện áp hoạt động 2,7V-5,5V(ATmega8L)và 4,5-5,4V(ATmega8).
o Tần số hoạt động 0-8MHz(ATmega8L) và 0-16MHz(ATmega8)
động.
b. Một số chức năng của ATmega8 sử dụng trong bài tập lớn.
Ngắt ngoài:Interrupts, thường được gọi là ngắt, là một tín hiệu khẩn cấp gởi đến
bộ xử lí, yêu cầu bộ xử lí tạm ngừng tức khắc các hoạt động hiện tại để “nhảy” đến một nơi khác thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này gọi là trình phục vụ ngắt – isr (interrupt service routine ). Sau khi kết thúc nhiệm vụ trong isr, bộ đếm chương trình sẽ được trả về giá trị trước đó để bộ xử lí quay về thực hiện tiếp các nhiệm vụ còn dang dở. Như vậy, ngắt có mức độ ưu tiên xử lí cao nhất, ngắt thường được dùng để xử lí các sự kiện bất ngờ nhưng không tốn quá nhiều thời gian.
Các tín hiệu dẫn đến ngắt có thể xuất phát từ các thiết bị bên trong chip (ngắt báo bộ đếm timer/counter tràn, ngắt báo quá trình gởi dữ liệu bằng RS232 kết thúc…) hay do các tác nhân bên ngoài (ngắt báo có 1 button được nhấn, ngắt báo có 1 gói dữ liệu đã được nhận…).Hình minh họa cách tổ chức ngắt thông thường trong các chip AVR:
5
![Page 6: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/6.jpg)
Có 3 thanh ghi liên quan đến ngắt ngoài đó là MCUCR, GICR và GIFR:
Thanh ghi điều khiển MCU – MCUCR (MCU Control Register) là thanh ghi xác lập chế độ ngắt cho ngắt ngoài:
Nếu không nhấn, trạng thái các chân INT là HIGH do điện trở kéo lên, khi vừa nhấn 1 button, sẽ có chuyển trạng thái từ HIGH sang LOW, chúng ta gọi là cạnh xuống - Falling Edge, khi button được nhấn và giữ, trạng thái các chân INT được xác định là LOW và cuối cùng khi thả các button, trạng thái chuyển từ LOW sang HIGH, gọi là cạnh lên – Rising Edge.
Dưới đây là cấu trúc thanh ghi MCUCR được trích ra từ datasheet của chip atmega8.
6
![Page 7: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/7.jpg)
MCUCR là một thanh ghi 8 bit nhưng đối với hoạt động ngắt ngoài, chúng ta chỉ quan tâm đến 4 bit thấp của nó (4 bit cao dùng cho Power manager và Sleep Mode). Bốn bit thấp là các bit Interrupt Sense Control (ISC) trong đó 2 bit ISC11:ISC10 dùng cho INT1 và 2 bit ISC01:ISC00 dùng cho INT0. Hãy nhìn vào bảng tóm tắt bên dưới để biết chức năng của các bit trên, đây là bảng “chân trị” của 2 bit ISC11, ISC10. Bảng chân trị cho các bit ISC01, ISC00 hoàn toàn tương tự.
Thanh ghi điều khiển ngắt chung – GICR (General Interrupt Control Register).
GICR cũng là 1 thanh ghi 8 bit nhưng chỉ có 2 bit cao (bit 6 và bit 7) là được sử dụng cho điều khiển ngắt, cấu trúc thanh ghi như bên dưới (trích datasheet).
Bit 7 – INT1 gọi là bit cho phép ngắt 1(Interrupt Enable), set bit này bằng 1 nghĩa bạn cho phép ngắt INT1 hoạt động, tương tự, bit INT0 điều khiển ngắt INT0.
Thanh ghi cờ ngắt chung – GIFR (General Interrupt Flag Register).
Có 2 bit INTF1 và INTF0 là các bit trạng thái (hay bit cờ - Flag) của 2 ngắt INT1 và INT0. Nếu có 1 sự kiện ngắt phù hợp xảy ra trên chân INT1, bit INTF1 được tự động set bằng 1 (tương tự
7
![Page 8: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/8.jpg)
cho trường hợp của INTF0), chúng ta có thể sử dụng các bit này để nhận ra các ngắt, tuy nhiên điều này là không cần thiết nếu chúng ta cho phép ngắt tự động, vì vậy thanh ghi này thường không được quan tâm khi lập trình ngắt ngoài. Cấu trúc thanh ghi GIFR được trình bày trong hình ngay bên dưới.
Giao tiếp TWI-I2C.
TWI (Two-Wire Serial Intereafce) là một module truyền thông nối tiếp đồng bộ trên các chip AVR dựa trên chuẩn truyền thông I2C.
TWI trên AVR được vận hành bởi 5 thanh ghi bao gồm thanh ghi tốc độ giữ nhịp TWBR, thanh ghi điều khiển TWCR , thanh ghi trạng thái TWSR, thanh ghi địa chỉ TWAR và thanh ghi dữ liệu TWDR.
- TWBR (TWI Bit Rate Register): là 1 thanh ghi 8 bit quy định tốc độ phát xung giữ nhịp trên đường SCL của chip Master.
Tốc độ phát xung giữ nhịp được tính theo công thức:
Trong đó CPU Clock frequency là tần số hoạt động chính của AVR, TWBR là giá trị thanh thi TWBR và TWPS là giá trị của 2 bits TWPS1 và TWPS0 nằm trong thanh thi trạng thái TWSR. Hai bits này được gọi là bit prescaler.
- TWCR (TWI Control Register): là thanh ghi 8 bit điều khiển hoạt động của TWI.
8
![Page 9: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/9.jpg)
Một điều cần chú ý là các bit trong thanh ghi TWCR không cần được set cùng lúc, tùy vào từng giai đoạn trong quá trình giao tiếp TWI các bit có thể được set riêng lẻ.
- TWSR (TWI Status Register): là 1 thanh ghi 8 bit trong đó có 5 bit chứa code trạng thái của TWI và 2 bit chọn prescaler.
- TWDR (TWI Data Register): là thanh ghi dữ liệu chính của TWI. Trong quá trình nhận, dữ liệu nhận về sẽ được lưu trong TWDR. Trong quá trình gởi, dữ liệu chứa trong TWDR sẽ được chuyển ra đường SDA.
- TWAR (TWI Address Register): là thanh ghi chứa device address của chip Slave. Cấu trúc thanh ghi được trình bày trong hình dưới.
2. Khối thời gian thực DS1307:
a) Giới thiệu về DS1307.
DS1307 là chip thời gian thực hay RTC (Read time clock). Đây là một IC tích hợp cho thời gian bởi vì tính chính xác về thời gian tuyệt đối cho thời gian : Thứ, ngày,tháng, năm, giờ, phút, giây. DS1307 là chế tạo bởi Dallas. Chip này có 7 thanh ghi 8 bit mỗi thanh ghi này chứa : Thứ, ngày, tháng, năm, giờ, phút, giây. Ngoài ra DS1307 còn chứa 1 thanh ghi điều khiển ngõ ra phụ và 56 thanh ghi trống các thanh ghi này có thể dùng như là RAM. DS1307 được đọc thông qua chuẩn truyền thông I2C nên do đó để đọc được và ghi từ DS1307 thông qua chuẩn truyền thông này. Do nó được giao tiếp chuẩn I2C nên cấu tạo bên ngoài nó rất đơn giản. Ví dụ 1 dạng đóng vỏ của DS1307 như sau :
9
![Page 10: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/10.jpg)
Trên là hai dạng cấu tạo của DS1307. Chip này có 8 chân và chúng ta hay dùng là dạng Dip và các chân nó được mô tả như sau :
+ X1 và X2 là đầu vào dao động cho DS1307. Cần dao động thạch anh 32.768Khz.
+ Vbat là nguồn nuôi cho chip. Nguồn này từ ( 2V- 3.5V) ta lấy pin có nguồn 3V. Đây là nguồn cho chip hoạt động liên tục khi không có nguồn Vcc mà DS1307 vẫn hoạt động theo thời gian.
+ Vcc là nguồn cho giao tiếp I2C. Điện áp cung cấp là 5V chuẩn và được dùng chung với vi xử lý. Nếu mà Vcc không có mà Vbat có thì DS1307 vẫn hoạt động bình thường nhưng mà không ghi và đọc được dữ liệu.
+ GND là nguồn Mass chung cho cả Vcc và Vbat.+ SQW/OUT là một ngõ ra phụ tạo xung dao động (xung vuông).
Chúng ta sẽ dùng chân này tạo ra 1 xung 1KHz nhờ bộ ngắt ngoài để đếm + SCL và SDA là hai bus dữ liệu của DS1307. Thông tin truyền và
ghi đều được truyền qua 2 đường truyền này theo chuẩn I2C.
b) Ghép nối DS1307 với vi điều khiển.
Do DS1307 giao tiếp chuẩn I2C nên việc ghép nối nó với vi điều khiển khá là đơn giản và theo datasheet thì tôi đưa ra sơ đồ sau :
10
![Page 11: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/11.jpg)
c) Tổ chức thanh ghi trong DS1307.
Nhìn bảng trên chúng ta thấy các thanh ghi được mã hóa theo bit. Mỗi bit trong thanh ghi đều có chức năng riêng và tôi sẽ trình bày chi tiết như sau:
11
![Page 12: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/12.jpg)
+ Thanh ghi giây (0x00) : Đây là thanh ghi giây của DS1307. Nhìn trên bảng trên ta thấy được từ bit 0 đến bit 3 là dùng để mã hóa số BCD hàng đơn vị của giây. Tiếp theo từ bit 4 đến bit 6 dùng để mã hóa BCD hàng chục của giây. Tại sao nó chỉ sử dụng có 3 bit này là do giây của chúng ta lớn nhất chỉ đến 59 nên hàng chục lớn nhất là 5 nên chỉ cần 3 thanh ghi này là cũng đủ mã hóa rồi! Còn bit thứ 7 có tên là “CH” theo tôi nó có nghĩa là “ Clock Halt – Treo đồng hồ” Do đó nếu mà bit 7 này mà được đưa lên 1 tức là khóa đồng hồ nên do đó nó vô hiệu hóa chip và chip không hoạt động. Nên do vậy lúc nào cũng phải cho bit 7 này luôn xuống 0 từ lúc đầu( cái này sử dụng lệnh end với 0x7F).
+ Thanh ghi phút (0x01) : Đây là thanh ghi phút của DS1307. Cũng nhìn trên bảng thanh ghi này được tổ chức như thanh ghi giây. Cũng là 3 bit thấp dùng để mã hóa BCD chữ số hàng đơn vị và số hàng trục chỉ lớn nhất là 5 nên do đó chỉ cần dùng từ bit 4 đến bit 6 để mã hóa BCD tiếp chữ số hàng chục. Nhưng thanh ghi này có sự khác biệt với thanh ghi giây là bit 7 nó đã mặc định bằng 0 rồi nên do đó chúng ta không phải làm gì với bit 7.
+ Thanh ghi giờ (0x02) : Đây là thanh ghi giờ của DS1307. Trước tiên chúng ta thấy được rằng từ bit 0 đến bit 3 nó dùng để mã hóa BCD của chữ số hàng đơn vị của giờ. Nhưng mà giờ nó còn có chế độ 24h và 12h nên do đó nó phức tạp ở các bit cao (bit 4 đến bit 7) và sự chọn chế độ 12h và 24h nó lại nằm ở bit 6. Nếu bit 6=0 thì ở chế độ 24h thì do chữ số hàng trục lớn nhất là 2 nên do đó nó chỉ dùng 2 bit ( bit 4 và bit 5 ) để mã hóa BCD chữ số hàng trục của giờ. Nếu bit 6 =1 thì chế độ 12h được chọn nhưng do chữ số của hàng trục của giờ trong chế độ này chỉ lớn nhất là 1 nên do đó bit thứ 4 là đủ để mã hóa BCD chữ số hàng trục của giờ rồi nhưng mà bit thứ 5 nó lại dùng để chỉ buổi sáng hay chiều, nếu mà bit 5 = 0 là AM và bit 5 =1 là PM. Trong cả 2 chế độ 12h và 24h thì bit 7 =0 nên ta ko cần chú ý đến thanh ghi này.
+ Thanh ghi thứ (0x03): Đây là thanh ghi thứ trong tuần của DS1307 và thanh ghi này khá là đơn giản trong DS1307. Nó dùng số để chỉ thứ trong tuần nên do đó nó chỉ lấy từ 1 đến 7 tương đương từ thứ hai đến chủ nhật. Nên do đó nó dùng 3 bit thấp (bit 0 đến bit 2) để mã hóa BCD ra thứ trong ngày. Còn các bit từ 3 đến 7 thì nó mặc định bằng 0 và ta không làm gì với các bit này.
12
![Page 13: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/13.jpg)
+ Thanh ghi ngày (0x04) : Đây là thanh ghi ngày trong tháng của DS1307. Do trong các tháng có số ngày khác nhau nhưng mà nằm trong khoảng từ 1đến 31 ngày. Do đó thanh ghi này các bit được tổ chức khá là đơn giản. Nó dùng 4 bit thấp (bit0 đến bit 3) dùng để mã hóa BCD ra chữ số hàng đơn vị của ngày trong tháng. Nhưng do chữ số hàng trục của ngày trong tháng chỉ lớn nhất là 3 nên chỉ dùng bit 4 và bit 5 là đủ mã hóa BCD rồi. Còn bit 6 và bit 7 chúng ta không làm gì và nó mặc định bằng 0.
+ Thanh ghi tháng (0x05) : Đây là thanh ghi tháng trong năm của DS1307. Tháng trong năm chỉ có từ 1 đến 12 tháng nên việc tổ chức trong bit cũng tương tự như ngày trong tháng nên do cũng 4 bit thấp (từ bit 0 đến bit 3) mã hóa BCD hàng đơn vị của tháng. Nhưng do hàng chục chỉ lớn nhất là 1 nên chỉ dùng 1 bit thứ 4 để mã hóa BCD ra chữ số hàng trục và các bit còn lại từ bit 5 đến bit 7 thì bỏ trống và nó mặc định cho xuống mức 0.
+ Thanh ghi năm (0x06): Đây là thanh ghi năm trong DS1307. DS1307 chỉ có 100 năm thôi tương đương với 00 đến 99 nên nó dùng tất cả các bit thấp và bit cao để mã hóa BCD ra năm.
+ Thanh ghi điều khiển (0x07): Đây là thanh ghi điều khiển quá trình ghi của DS1307 và Quá trình ghi phải được kết thúc bằng địa chỉ 0x93.
3. Khối LED 7SEG.
a) Các khái niệm cơ bản
Led 7 đoạn có cấu tạo bao gồm 7 led đơn có dạng thanh xếp theo hình
và có thêm một led đơn hình tròn nhỏ thể hiện dấu chấm tròn ở góc dưới, bên phải của led 7 đoạn.
8 led đơn trên led 7 đoạn có Anode(cực +) được nối chung với nhau vào một điểm, được đưa chân ra ngoài để kết nối với mạch điện. 8 cực còn lại trên mỗi led đơn được đưa thành 8 chân riêng, cũng được đưa ra ngoài để kết nối với mạch điện. Đầu chung này được nối với +Vcc, các chân còn lại dùng để điều khiển trạng thái sáng tắt của các led đơn, led chỉ sáng khi tín hiệu đặt vào các chân này ở mức 0.
13
![Page 14: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/14.jpg)
Vì led 7 đoạn chứa bên trong nó các led đơn, do đó khi kết nối cần đảm bảo dòng qua mỗi led đơn trong khoảng 10mA-20mA để bảo vệ led. Nếu kết nối với nguồn 5V có thể hạn dòng bằng điện trở 330Ω trước các chân nhận tín hiệu điều khiển.
b ) Kết nối với Vi điều khiển
Ngõ nhận tín hiệu điều khiển của led 7 đoạn có 8 đường, vì vậy có thể dùng 1 Port nào đó của Vi điều khiển để điều khiển led 7 đoạn. Như vậy led 7 đoạn nhận một dữ liệu 8 bit từ Vi điều khiển để điều khiển hoạt động sáng tắt của từng led led đơn trong nó, dữ liệu được xuất ra điều khiển led 7 đoạn thường được gọi là "mã hiển thị led 7 đoạn". Để hiện thị số 1 cần làm cho các led ở vị trí b và c sáng, nếu sử dụng led 7 đoạn có Anode chung thì phải đặt vào hai chân b và c điện áp là 0V(mức 0) các chân còn lại được đặt điện áp là 5V(mức 1), nếu sử dụng led 7 đoạn có Cathode chung thì điện áp(hay mức logic) hoàn toàn ngược lại, tức là phải đặt vào chân b và c điện áp là 5V(mức 1).
Bảng mã hiển thị led 7 đoạn:
Phần cứng được kết nối với 1 Port bất kì của Vi điều khiển, để thuận tiện cho việc xử lí về sau phần cứng nên được kết nối như sau: Px.0 nối với chân a, Px.1 nối với chân b, lần lượt theo thứ tự cho đến Px.7 nối với chân h.
Dữ liệu xuất có dạng nhị phân như sau : hgfedcba
Bảng mã hiển thị led 7 đoạn dành cho led 7 đoạn có Anode chung (các led đơn sáng ở mức 0):
Số hiển thị trên led 7 đoạn
Mã hiển thị led 7 đoạn dạng nhị phân
Mã hiển thị led 7 đoạn dạng thập lục phân
h g f e d c b a
0 1 1 0 0 0 0 0 0 C0
1 1 1 1 1 1 0 0 1 F9
2 1 0 1 0 0 1 0 0 A4
14
![Page 15: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/15.jpg)
3 1 0 1 1 0 0 0 0 B0
4 1 0 0 1 1 0 0 1 99
5 1 0 0 1 0 0 1 0 92
6 1 1 0 0 0 0 1 0 82
7 1 1 1 1 1 0 0 0 F8
8 1 0 0 0 0 0 0 0 80
9 1 0 0 1 0 0 0 0 90
A 1 0 0 0 1 0 0 0 88
B 1 0 0 0 0 0 1 1 83
C 1 1 0 0 0 1 1 0 C6
D 1 0 1 0 0 0 0 1 A1
E 1 0 0 0 0 1 1 0 86
F 1 0 0 0 1 1 1 0 8E
- 1 0 1 1 1 1 1 1 BF
4. IC ghi dịch 74HC595.
a, Chức năng:
Là ic ghi dịch 8bit kết hợp chốt dữ liệu , đầu vào nối tiếp đầu ra song song.
Chức năng: Thường dùng trong các mạch quét led 7 , led matrix …để tiết kiệm số chân VDK tối đa (3 chân) . Có thể mở rộng số chân vi điều khiển bao nhiêu tùy thích mà không ic nào có thể làm được bằng việc mắc nối tiếp đầu vào dữ liệu các ic với nhau .
b, Sơ đồ chân:
15
![Page 16: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/16.jpg)
Giải thích ý nghĩa hoạt động của một số chân quan trọng:
Input: Chân 14 : đầu vào dữ liệu nối tiếp . Tại 1 thời điểm xung clock chỉ đưa vào được 1 bit.
Output: QA=>QH : trên các chân (15,1,2,3,4,5,6,7). Xuất dữ liệu khi chân chân 13 tích cực ở mức thấp và có một xung tích cực ở sườn âm tại chân chốt 12.
Output-enable: Chân 13 : Chân cho phép tích cực ở mức thấp (0) .Khi ở mức cao, tất cả các đầu ra của 74595 trở về trạng thái cao trở, không có đầu ra nào được cho phép.
SQH: Chân 9: Chân dữ liệu nối tiếp. Nếu dùng nhiều 74595 mắc nối tiếp nhau thì chân này đưa vào đầu vào của con tiếp theo khi đã dịch đủ 8bit.
Shift clock: Chân 11: Chân vào xung clock . Khi có 1 xung clock tích cực ở sườn dương(từ 0 lên 1) thì 1bit được dịch vào ic.
Latch clock: Chân 12 : xung clock chốt dữ liệu . Khi có 1 xung clock tích cực ở sườn dương thì cho phép xuất dữ liệu trên các chân output . lưu ý có thể xuất dữ liệu bất kỳ lúc nào bạn muốn ,ví dụ đầu vào chân 14 dc 2 bit
16
![Page 17: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/17.jpg)
khi có xung clock ở chân 12 thì dữ liệu sẽ ra ở chân Qa và Qb (chú ý chiều dịch dữ liệu từ Qa=>Qh).
Reset: Chân 10: khi chân này ở mức thấp(mức 0) thì dữ liệu sẽ bị xóa
c. Bảng thông số chip:
Đây là ic đầu ra hoạt động ở 2 mức 0 &1 dòng ra tầm 35mA . điện áp hoạt động <=7V . Công suất trung bình 500Mw.
5. IC giải mã 74HC238.
Control Register: Thanh ghi này có địa chỉ là 07h, nó được dùng để điều khiển chân SWQ/OUT hoạt động.
OUT 0 0 SQWE 0 0 RS1 RS0
OUT: Bit điều khiển đầu ra của chân SQW/OUT khi không phát xung. Khi SQWE = 0 nếu OUT = 1 thì đầu ra chân SQW/OUT = 1, nếu OUT = 0 thì đầu ra chân SQW/OUT = 0.
17
![Page 18: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/18.jpg)
SQWE: = 1 sẽ cho phép bộ phát xung hoạt động. Tần số xung vuông được xác định dựa trên các bit RS, RS0.
RS1 RS0 Tầnsốđầurachân SQW
0 0 1Hz
0 1 4.096 kHz
1 0 8.192 kHz
1 1 32.768 kHz
Bộ giải mã 74HC238: giải mã 3 sang 8 tác động cao. Ứng với mỗi tổ hợp được đưa vào các đầu vào A0, A1, A2 thì một ngõ ra Y0 – Y7 được tác động cao nếu được cho phép bởi 2 bit tác động thấp E1, E2 và 1 bit tác động cao E3. Mọi đầu ra sẽ ở trạng thái trở cao nếu không đồng thời E1 = E2 = thấp và E3 = cao.
Sơ đồ chân của 74HC238
Sơ đồ chức năng
18
![Page 19: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/19.jpg)
19
![Page 20: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/20.jpg)
III. Sơ đồ mạch nguyên lý và mạch in.
20
![Page 21: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/21.jpg)
IV. Code của chương trình mô phỏng.
#include <mega8.h>
#include <delay.h>
unsigned char displayMode = 1;
#define timeMode 0b00000001
#define dateMode 0b00000011
#define timeChangeMode 0b00000100
#define dateChangeMode 0b00001100
unsigned char buttonStatusRegister = 0;
#define pressedChange 0b00100000
#define keepChange 0b00010000
21
![Page 22: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/22.jpg)
#define pressedUp 0b00001000
#define keepUp 0b00000100
#define pressedDown 0b00000010
#define keepDown 0b00000001
#define released 0b00000000
//con tro module cac khoi 7seg
unsigned char point = 0;
#define all 1
#define only 0
//definition type of buttons
#define change 2
#define up 1
#define down 0
#define changeButtonIsPressed !(PINB & (1 << PINB4))
#define upButtonIsPressed !(PINC & (1 << PINC0))
#define downButtonIsPressed !(PINC & (1 << PINC3))
//the variables is used for button debouncing
unsigned char pressedConfidenceLevel[3];
unsigned char releasedConfidenceLevel[3];
//the variables is used to determine that button is pressed or released
unsigned char pressedButton[3];
unsigned char releasedButton[3];
//the variables is used to display data on seven segment
unsigned char timeData[8] = {0, 0, 0, 0, 0, 0, 13, 12};
22
![Page 23: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/23.jpg)
unsigned char dateData[8] = {0, 1, 0, 1, 0, 0, 0, 0};
unsigned char code238[8] = {0b100, 0b010, 0b001, 0b110, 0b111, 0b011, 0b101, 0b000};
unsigned char sevenSegData[15] = {0x40, 0x75, 0x0c, 0x24, 0x31, 0x22, 0x02, 0x74, 0x00, 0x20, 0x10, 0x18, 0x1a, 0x6f, 0xff};
//the variables is used for interfacing the DS1307 with the Atmega8 microcontroller
unsigned char time[3] = {0, 0, 0};
unsigned char date[3] = {1, 1, 0};
unsigned char changeRate = 0;
unsigned char blinkRate;
unsigned char control;
void processPressedButton(unsigned char button);
void processReleasedButton(unsigned char button);
void normalDisplay(unsigned char *displayData);
void changeDisplay(unsigned char *displayData);
void processNormalMode(void);
void processChangeMode(void);
void processChangeHourMode(void);
void processPressedUpDown(unsigned char);
void changeByOne(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char);
23
![Page 24: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/24.jpg)
void readDataFromDs1307(unsigned char onlyOrAll, unsigned char registerAddress);
void sendDataToDs1307(unsigned char, unsigned char*, unsigned char);
void convertTimeToDisplay(void);
void convertDateToDisplay(void);
interrupt [EXT_INT1] void ext_int1_isr(void);
void main(void)
{
//setting up ports and data direction register
DDRB = 0b00001111; //set direction for input on x1 and x2 pins
DDRC = 0b00110110; //set direction for output on SCL and SDA pins
DDRD = 0b11010111; //PD4 pin is conected to Vcc, PD6 and PD7 pins are conected to Ground
PORTB= 0b00110000; //x1 = 0, x2 = 0
PORTC= 0b11111111; //PC1 = 1 PC2 = 1
PORTD = 0b00111000; //PD4 = 1, PD6 = 0 PD7 = 0
// External Interrupt(s) initialization
MCUCR = (1 << ISC11) | (1<< ISC10); // INT1: On
GICR |= (1 << INT1); // INT1 Mode: Rising Edge
// TWI initialization
// Bit Rate: 100.000 kHz
TWBR=0x20;
TWSR=0x00;
TWAR=0x00;
// Generate Acknowledge Pulse: On
24
![Page 25: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/25.jpg)
// TWI Interrupt: Off
// Global enable interrupts
#asm("sei")
control = 0b10010000;
sendDataToDs1307(7, &control, 1); //enable the oscillator output up to 1Hz frequency on SQW/OUT pin of Ds1307
readDataFromDs1307(only, 8); //reading the fist two digits of year which was saved in the 8th register of Ds1307 before the last turning off the clock
dateData[4] = time[0] >> 4; //converting data every reading from Ds1307
dateData[5] = time[0] & 0b00001111;
readDataFromDs1307(all, 0);
control = 0b01111111 & time[0]; //clock halt (CH) bit is cleared to a zero
sendDataToDs1307(0, &control, 1); //enable the oscillator then the time and calender could run
convertTimeToDisplay();
convertDateToDisplay();
while(1)
{
//finding out which button is pressed, released or keepping
if(changeButtonIsPressed) processPressedButton(change);
else processReleasedButton(change);
if(upButtonIsPressed) processPressedButton(up);
else processReleasedButton(up);
if(downButtonIsPressed) processPressedButton(down);
else processReleasedButton(down);
//chosing operating mode
25
![Page 26: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/26.jpg)
switch(displayMode)
{
case timeMode:
{
normalDisplay(timeData);//each mode has a different display data or a different way to display data upon 8 seven segments
processNormalMode();
processChangeHourMode(); //there is 2 hour modes which is changed each other if pressing up or down button
break;
}
case dateMode:
{
normalDisplay(dateData);
processNormalMode();
break;
}
case timeChangeMode:
{
changeDisplay(timeData);
processChangeMode();
break;
}
case dateChangeMode:
{
changeDisplay(dateData);
processChangeMode();
}
}
26
![Page 27: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/27.jpg)
}
}
void processPressedButton(unsigned char button)
{
pressedConfidenceLevel[button] ++; //removing intermediate noise states from a discrete switch
releasedConfidenceLevel[button] = 0;
if(pressedConfidenceLevel[button] > 10) //if pressed confidence level is big enough then we know button is pressed
{
pressedButton[button] ++;
if((pressedButton[button] > 8) & (releasedButton[button] == 1))
{
//keeping button states
buttonStatusRegister = 1 << (2*button);
releasedButton[button] = 0;
}
pressedConfidenceLevel[button] = 0;
}
}
void processReleasedButton(unsigned char button)
{
releasedConfidenceLevel[button] ++;
pressedConfidenceLevel[button] = 0;
if(releasedConfidenceLevel[button] > 5) //if released confidence level is big enough then we know button is released
{
if((pressedButton[button] > 0) & (pressedButton[button] <= 8))
{
//pressed button states
27
![Page 28: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/28.jpg)
buttonStatusRegister = 1 << (2*button + 1);
}
pressedButton[button] = 0;
releasedConfidenceLevel[button] = 0;
releasedButton[button] = 1;
}
}
void normalDisplay(unsigned char *displayData)
{
unsigned char i, j, serialData;
for(i = 0; i < 8; i++)
{
//shifting data
serialData = sevenSegData[displayData[i]];
PORTB = 0b10000 | (serialData & 1); //shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = dataBit
for(j = 0; j < 7; j++)
{
//enable to shift another bit
PORTB |= 0b11000; //shiftClock = 1 enableOutput = 0 storageClock = 0 serialData = dataBit
serialData >>= 1;
PORTB = 0b10000 | (serialData & 1);//shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = newDataBit
}
//data is disable on output pins of 74HC595
PORTB = 0b10100; //shiftClock = 0 enableOutput = 1 storageClock = 0 serialData = 0
//power supply to another seven segment
PORTD = 56 + code238[i];
28
![Page 29: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/29.jpg)
//storage data on output pins of 74HC595
PORTB = 0b10110; //shiftClock = 0 enableOutput = 1 storageClock = 1 serialData = 0
//data is enable on output pins of 74HC595
PORTB = 0b10000; //shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = 0
delay_ms(1);
}
}
void changeDisplay(unsigned char *displayData)
{
unsigned char i, j, x, y, serialData; //x, y module is pointed
x = displayData[point];
y = displayData[point + 1];
if(blinkRate > 59) blinkRate = 0; //setting blink rate
if(blinkRate > 29)
{
displayData[point] = 14;
displayData[point + 1] = 14;
}
for(i = 0; i < 8; i++)
{
//shifting data
serialData = sevenSegData[displayData[i]];
PORTB = 0b10000 | (serialData & 1); //shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = dataBit
for(j = 0; j < 7; j++)
{
//enable to shift another bit
29
![Page 30: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/30.jpg)
PORTB |= 0b11000; //shiftClock = 1 enableOutput = 0 storageClock = 0 serialData = dataBit
serialData >>= 1; //shifting the next bit
PORTB = 0b10000 | (serialData & 1);//shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = newDataBit
}
//data is disable on output pins of 74HC59
PORTB = 0b10100; //shiftClock = 0 enableOutput = 1 storageClock = 0 serialData = 0
//power supply to another seven segment
PORTD = 56 + code238[i];
//storage data on output pins of 74HC595
PORTB = 0b10110; //shiftClock = 0 enableOutput = 1 storageClock = 1 serialData = 0
//data is enable on output pins of 74HC595
PORTB = 0b10000; //shiftClock = 0 enableOutput = 0 storageClock = 0 serialData = 0
delay_ms(1);
}
displayData[point] = x;
displayData[point + 1] = y;
blinkRate ++;
}
void processNormalMode(void)
{
if(buttonStatusRegister == pressedChange)
{
displayMode ^= 0b00000010; //if change button is pressed normal modes are changed each other
buttonStatusRegister = released;
}
30
![Page 31: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/31.jpg)
if((buttonStatusRegister == keepChange))
{
displayMode <<= 2; //if change buton is kept normal modes are changed to change modes
buttonStatusRegister = released;
}
}
void processChangeMode(void)
{
switch(buttonStatusRegister)
{
case pressedChange:
{
point += 2; //shifting the point to another module
if((displayMode == timeChangeMode) & (point == 4)) point = 6;
if(point > 6) point = 0;
buttonStatusRegister = released;
break;
}
case keepChange:
{
//send data to the ds1307 ic
if(displayMode == timeChangeMode)
{
time[1] = (timeData[2] << 4) + timeData[3];//minute
if (timeData[7] == 10) time[2] = 0b01000000 | ((timeData[0] << 4) + timeData[1]); //am
if (timeData[7] == 11) time[2] = 0b01100000 | ((timeData[0] << 4) + timeData[1]); //pm
31
![Page 32: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/32.jpg)
if (timeData[7] == 12) time[2] = (timeData[0] << 4) + timeData[1]; //fullday
sendDataToDs1307(0, time, 3);
}
else
{
date[0] = (dateData[0] << 4) + dateData[1]; //date
date[1] = (dateData[2] << 4) + dateData[3]; //month
date[2] = (dateData[6] << 4) + dateData[7]; //year
sendDataToDs1307(4, date,3);
control = (dateData[4] << 4) + dateData[5];
sendDataToDs1307(8, &control, 1);
}
displayMode >>= 2; //change modes are changed to normal modes
buttonStatusRegister = released;
break;
}
case pressedUp:
{
processPressedUpDown(up); //increase by one for every up-button pressing
buttonStatusRegister = released;
break;
}
case keepUp:
{
changeRate++;
if(changeRate > 20) //setting change rate
{
32
![Page 33: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/33.jpg)
processPressedUpDown(up); //increase by one for every up-button pressing
changeRate = 0;
}
if(releasedButton[up] == 1) buttonStatusRegister = released;
break;
}
case pressedDown:
{
processPressedUpDown(down); //decrease by one for every down-button pressing
buttonStatusRegister = released;
break;
}
case keepDown:
{
changeRate++;
if(changeRate > 20)
{
processPressedUpDown(down); //decrease by one for every down-button pressing
changeRate = 0;
}
if(releasedButton[down] == 1) buttonStatusRegister = released;
}
}
}
void processChangeHourMode(void)
{
33
![Page 34: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/34.jpg)
if((buttonStatusRegister == pressedUp) | (buttonStatusRegister == keepUp) | (buttonStatusRegister == pressedDown) | (buttonStatusRegister == keepDown))
{ //if hour mode is half-day mode
if(time[2] >= 0b01000000) //half-day mode is changed to full-day mode
{
if(time[2] >= 0b01100000)//pm
{
if(time[2] == 0b01110010) time[2] = 0b00010010; //changing 12h pm to 12h full day
else time[2] = ((time[2] & 0b00001111) +2) | ((time[2] & 0b00010000) + 0b10000);
}
else //am
{
if(time[2] == 0b01010010) time[2] = 0; //changing 12h to 0h full day
else time[2] &= 0b00111111;
}
timeData[1] = time[2] & 0b00001111;
timeData[0] = time[2] >>4;
timeData[7] = 12; // 7seg code of F word is 12
}
//if hour mode is full-day mode
else
{
if(time[2] >= 0b00010010) //full-day mode is changed to half-day mode
{
if(time[2] == 0b00010010) time[2] = 0b01110010; //12h is changed to 12h pm
34
![Page 35: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/35.jpg)
else time[2] = ((time[2] & 0b00001111) -2) | ((time[2] & 0b00110000) - 0b10000) | 0b01100000;
timeData[7] = 11; //7seg code of P word is 11
}
else //neu <12h
{
if(time[2] == 0) time[2] = 0b01010010; //0h is changed to 12h am
else time[2] |= 0b01000000;
timeData[7] = 10; //7seg code of A is 10
}
timeData[1] = time[2] & 0b00001111;
timeData[0] = (time[2] & 0b00010000) >>4;
}
sendDataToDs1307(2, time + 2, 1); //send hour to ds1307
buttonStatusRegister = released;
}
}
void processPressedUpDown(unsigned char upOrDown)
{
if(displayMode == timeChangeMode)
{
switch (point)
{
case 0:
{
if(timeData[7] == 12) changeByOne(timeData, upOrDown, 2, 3, 0, 0); //limit of changing
35
![Page 36: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/36.jpg)
else changeByOne(timeData, upOrDown, 1, 2, 0, 1); //hour can change from 1 to 12
break;
}
case 2:
{
changeByOne(timeData, upOrDown, 5, 9, 0, 0);
break;
}
case 6: changeByOne(timeData, upOrDown, 13, 12, 13, 10); //hour mode changing: am -> pm ->fullday
}
}
else
{
switch (point)
{
case 0:
{
changeByOne(dateData, upOrDown, 3, 1, 0, 1);
break;
}
case 2:
{
changeByOne(dateData, upOrDown, 1, 2, 0, 1);
break;
}
case 4: case 6: changeByOne(dateData, upOrDown, 9, 9, 0, 0);
}
36
![Page 37: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/37.jpg)
}
}
void changeByOne(unsigned char *data, unsigned char upOrDown, unsigned char xTop, unsigned char yTop, unsigned char xBottom, unsigned char yBottom)
{
if(upOrDown == up) //pressing up-button
{
if((data[point] >= xTop) & (data[point + 1] >= yTop))
{
data[point] = xBottom;
data[point + 1] = yBottom;
}
else
{
if(data[point + 1] == 9)
{
data[point]++;
data[point + 1] = 0;
}
else data[point + 1]++;
}
}
else //pressing down-button
{
if(((data[point] == xBottom) & (data[point + 1] == yBottom)) | ((data[point] >= xTop) & (data[point + 1] > yTop)))
{
data[point] = xTop;
data[point + 1] = yTop;
37
![Page 38: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/38.jpg)
}
else
{
if(data[point + 1] == 0)
{
data[point]--;
data[point + 1] = 9;
}
else data[point + 1]--;
}
}
}
void sendDataToDs1307(unsigned char registerAddress, unsigned char *DA, unsigned char length)
{
unsigned char i;
//Send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //CleaR TWINT bit, set START bit, set TWEN bit
while(!(TWCR & (1 << TWINT))); // Waitting for TWINT Flag set
//send Ds1307 adress + w (1101000 << 1) + 0
TWDR = 11010000; //Ds1307 address is 0b1101000
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1 << TWINT))); //Check and wait for TWINT bit = 1
//register address sending
TWDR = registerAddress; //Load DATA into TWDR Register.
38
![Page 39: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/39.jpg)
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit in TWCR to start transmission of data
while(!(TWCR & (1 << TWINT)));
//send data
for(i = 0; i < length; i++)
{
TWDR = *(DA+i); //Load DATA into TWDR Register.
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit in TWCR to start transmission of data
while(!(TWCR & (1 << TWINT)));
}
//transmit TOP condition
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
void readDataFromDs1307(unsigned char onlyOrAll, unsigned char registerAddress)
{
unsigned char i;
/********SENDING ADDRESS OF REGISTER FROM WHERE DATA IS TRANSMITED TO THE AMEGA8******/
//Send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while(!(TWCR & (1 << TWINT))); // Wait for TWINT Flag set
//send Ds1307 address + w (1101000 << 1) + 0
TWDR = 11010000; //Ds1307 address is 0b1101000
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1 << TWINT))); //Check and wait for TWINT bit = 1
39
![Page 40: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/40.jpg)
//send address
TWDR = registerAddress; //Load register address into TWDR Register.
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit in TWCR to start transmission of data
while(!(TWCR & (1 << TWINT)));
/********GETTING DATA*************/
//Send REPEAT START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //clear TWINT bit, set START bit, set TWEN bit
while(!(TWCR & (1 << TWINT))); // Wait for TWINT Flag set
//send Ds1307 address + R (1101000 << 1) + 1
TWDR = 11010001;//Ds1307 address is 0b1101000
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1 << TWINT))); //Check and wait for TWINT bit = 1
if(onlyOrAll == all)
{
//getting time data
for(i = 0; i < 3; i++)
{
TWCR = (1<<TWINT) | (1 << TWEA) | (1<<TWEN);//clear TWINT and enable send ACK
while(!(TWCR & (1 << TWINT)));
time[i] = TWDR;
}
40
![Page 41: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/41.jpg)
//getting day but no saving
TWCR = (1<<TWINT) | (1 << TWEA) | (1<<TWEN); //clear TWINT and enable send ACK
while(!(TWCR & (1 << TWINT)));
// getting date and month
for(i = 0; i < 2; i++)
{
TWCR = (1<<TWINT) | (1 << TWEA) | (1<<TWEN);//clear TWINT and enable send ACK
while(!(TWCR & (1 << TWINT)));
date[i] = TWDR;
}
//getting year
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit to read data (NOT send ACK)
while(!(TWCR & (1 << TWINT)));
date[2] = TWDR;
}
else
{
//geting second
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit to read data (NOT send ACK)
while(!(TWCR & (1 << TWINT)));
time[0] = TWDR;
}
//transmit TOP condition
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
41
![Page 42: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/42.jpg)
interrupt [EXT_INT1] void ext_int1_isr(void)
{
if(displayMode == timeChangeMode)
{
readDataFromDs1307(only, 0); //read only second
timeData[5] = time[0] & 0b00001111;
timeData[4] = time[0] >> 4;
}
else
{
if (time[0] == 0x59)
{
//23h 59' 31/12/xx99
if(time[1] == 0x59)
if((time[2] == 0x23) | time[2] == 0b01110001) //23h or 11h pm
if(date[0] == 0x31)
if(date[1] == 0x12)
if(date[2] == 0x99)
{
if((dateData[4] == 9) & (dateData[5] == 9))
{
dateData[4] = 0;
dateData[5] = 0;
}
else
{
if(dateData[5] == 9)
{
dateData[4] ++;
42
![Page 43: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/43.jpg)
dateData[5] = 0;
}
else dateData[5] ++;
}
control = (dateData[4] << 4) + dateData[5];
sendDataToDs1307(8, &control, 1);
}
readDataFromDs1307(all, 0);
convertTimeToDisplay();
convertDateToDisplay();
}
else
{
readDataFromDs1307(only, 0); //read only second
timeData[5] = time[0] & 0b00001111;
timeData[4] = time[0] >> 4;
}
}
}
void convertTimeToDisplay(void)
{
timeData[5] = time[0] & 0b00001111; //getting 4 higher bits
timeData[4] = time[0] >> 4; //getting 4 lower bits
timeData[3] = time[1] & 0b00001111;
timeData[2] = time[1] >> 4;
timeData[1] = time[2] & 0b00001111;
if(time[2] >= 0b01000000) //if half-day mode
{
43
![Page 44: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/44.jpg)
if(time[2] >= 0b01100000) timeData[7] = 11; //code of P (pm)
else timeData[7] = 10; //code of A (am)
timeData[0] = (time[2] & 0b00010000) >> 4;
}
else //if full-day mode
{
timeData[7] = 12; //code of F (full)
timeData[0] = (time[2] & 0b00110000) >> 4;
}
}
void convertDateToDisplay(void)
{
dateData[7] = date[2] & 0b00001111;
dateData[6] = date[2] >> 4;
dateData[3] = date[1] & 0b00001111;
dateData[2] = date[1] >> 4;
dateData[1] = date[0] & 0b00001111;
dateData[0] = date[0] >>4;
}
44
![Page 45: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/45.jpg)
V. Kết quả mô phỏng
45
![Page 46: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/46.jpg)
VI. Mức độ hoàn thành công việc và hướng phát triển.
1. Mức độ hoàn thành công việc.
Nhìn chung đã hoàn thành về mạch mô phỏng và chạy ổn định các khâu của bài tập lớn.
2. Hướng phát triển.
Có thể thêm vào phần hẹn giờ báo thức và chuông báo chuyển giờ.
VII. Các phần mềm đã sử dụng trong quá trình làm bài tập.
- Proteus version 7.8
- Codevison AVR 2.5.3
- Altium Designer 10.
VIII. Tài liệu tham khảo.
Website:
http://google.com.vn
http://hocavr.com
http://hoiquandientu.com
http://dientuvietnam.com
http://dientu.org
http://machdientu.net
Ebook:
46
![Page 47: báo cáo bài tập lớn môn vi điều khiển](https://reader033.vdocuments.site/reader033/viewer/2022061109/54516fe4b1af9f7c318b47a6/html5/thumbnails/47.jpg)
Datasheet : Atmeaga8, 74HC595, 74HC238, DS1307.
47