![]() |
Em có vài câu hỏi nhỏ về PIC với DS1307
Chào các bác ạ
Trước tiên rất cám ơn các bác đã vào đọc. Em có một số câu hỏi rất gà, về một vấn đề cũng cũ lắm rồi, PIC với DS1307. (em dùng CCS C làm trình dịch) Có lẽ em không phải dân kĩ thuật và kiến thức lập trình chưa vững nữa nên có tham khảo rồi, vẫn có một số điều chưa hiểu: Thứ nhất, ds1307 xuất nhập giá trị dạng BCD, ví dụ nó truyền đến pic giá trị giây sec=15 giây chẳng hạn, thì pic sẽ nhận đuơc giá trị nào: 0001 0101 hay là 0x15 (viết có vẻ giống dạng hex 0x nhưng vẫn là BCD các bác nhỉ)? Thứ 2, em sử dụng code library có sẵn cho ds1307, trong đó đã có hàm bin2bcd và bcd2bin, nghĩa là giá trị ra vào pic từ rtc sẽ là dạng bin. Em gán giá trị đó vào biến sec, biến sec này đuợc khai báo ở đầu là dạng int. Vậy, giả sử biến sec đuợc gán giá trị lấy từ rtc là sec=0b00001111 tuơng ứng với 15 giấy như trên và em có lệnh abc = sec/10 thì abc sẽ là 7 hay là 1 ? Nghĩa là trình dịch có tự convert giá trị dạng bin sang int khi nhận giá trị dạng bin từ rtc nhét vào biến sec không ạ, hay phải làm thế nào ạ. Cảm ơn các bác đã quan tâm. Em rất mong đuợc học hỏi |
Trích:
Các hàm bin2bcd và bcd2bin cho phép bạn chuyển đổi giữa kiểu dữ liệu BCD của RTC và nhị phân của vi điều khiển. int tất nhiên là một trong những kiểu dữ liệu nhị phân. Với ví dụ của bạn, sec = 0b00001111 (15 giây), khi đó adc = sec/10 = 1 (phần nguyên khi chia 15 cho 10). Bạn cần xem lại prototype của các hàm bin2bcd và bcd2bin để biết chúng chấp nhận biến nhị phân kiểu gì, và chuyển kiểu khi tính toán trong trường hợp cần thiết. Thân, |
Vâng ạ, như vậy viết theo hai cách đều đuợc
prototype của 2 hàm chuyển đổi định dạng BYTE BYTE bin2bcd(BYTE binary_value); BYTE bcd2bin(BYTE bcd_value); như vậy em khai báo biến sec là int và biến sec này nhận giá trị return từ 2 hàm trên thì vẫn tính toán bình thường anh nhỉ Rất cảm ơn anh Nam, vì câu hỏi cơ bản thế này cũng đuợc anh chỉ bảo tận tình. Em không đuợc học cơ bản nên chỉ biết đọc và hỏi thôi ạ. |
cho em hỏi thêm một câu là em dùng CCS C thì
lệnh goto ở trong hàm con có cho phép nhảy qua label nằm ở hàm chính hay hàm con khác không Ví dụ: Code:
void main(){ |
Trích:
Thân, |
Em rất cảm ơn anh Nam và những người quan tâm.
Thú thật là tư duy lập trình của em kém quá. Ngồi cả ngày code đuợc một đoạn ngắn ngắn xong ra toàn error, chữa hết error, (vẫn còn warning), nạp thử nhưng ko chạy. Bản thân em cũng thấy những gì viết ra rất lủng củng và sai nhiều. Em cứ post lên đây các bác quan tâm thì chỉ cho em mấy lỗi cơ bản để em rút kinh nghiệm. Phần cứng thì cũng không có gì mấy ạ. Em miêu tả tạm thế này ạ 6led A chung. Các chân data là của portB, còn PortA để điều khiển qua 6 trans c1815, giao tiếp với ds1307 là rc3 và rc4. Riêng phím bấm thì em tham khảo của bác BA giới thiệu http://dientuvietnam.net/forums/atta...6&d=1175250495 keyboarout em nhét vào chân RC0. key=1 là mode, 2 là up, 3 là down, 4 là set Còn một vấn đề có lẽ của bài trước nữa nhưng em hỏi rồi mà vẫn chưa thấu lắm, về bộ đếm ấy ạ. BÁc thử nhìn cái code giao tiếp với ds1307 nó cho ra vào dữ liệu dang binary, còn em lại khai báo những biến đấy trong ct dạng int8. Như vậy có đuợc không ạ, Quả thật kiến thức của em về PIC cũng như điện tử chưa đâu vào đâu cả nên Em rất mong đuợc giúp đỡ, nếu đuợc anh Nam giúp đỡ nũa thì mừng quá có gì sai ngu quá các anh bỏ quá cho, em rất thích điện tử nhưng lại theo chuyên ngành khác, nên kiến thức không đuọc bài bản. |
Bạn xem lại chương trình mà bạn đã tham khảo, ở phần đọc dữ liệu từ DS1307, trong một loạt lệnh i2c_read(), chỉ có lệnh cuối là dùng i2c_read(0), còn những lệnh trước đó là i2c_read(), tức là tương đương với i2c_read(1). Đoạn code trong hàm ds1307_init() của bạn có 2 lệnh gọi i2c_read(0) ở phần đầu, đây chính là chỗ không ổn. Trong một loạt lệnh read từ I2C, mỗi lệnh đều phải ACK trừ lệnh sau cùng, để báo cho slave biết là master không muốn đọc nữa.
Bạn đọc thêm về I2C ở đây: https://www2.hcmut.edu.vn/~nqnam/Commu.php#i2c Và tham khảo thêm tập tin nguồn "Vidu4-4.c" trong tutorial 4 dành cho dsPIC của tôi, tôi đã chú thích thứ tự những thao tác cần thực hiện khi giao tiếp với DS1307. Thân, |
em không rõ là chỗ interrupts có đúng không nữa
có lẽ em hiểu về interrupts sai Em hiểu nôm na thế này PIC nó đang trơn tru làm một gói việc A thì bị interrupts và bắt nó nhảy sang làm việc B, làm xong việc B rồi nó lại quay lại chỗ đang làm dở việc A Hiểu nôm na thế có sai không ạ PS: bây giờ mới đọc đuợc bài của anh em có hiểu sơ qua về i2c, ví dụ trong truơng hợp write. quá trình gửi mỗi 8bit từ master thì sẽ theo sau một ACK (acknowledge) của slave để thông báo Em cũng thắc mắc về cái thư viện code nhặt đuợc ở trên, có giở qua CCS manual mà lại đọc không kĩ, vậy là 0 là nack, 1 là ack, em sẽ xem lại thêm ạ, tham khảo thêm phần anh viết ạ. Cũng tại copy paste dòng dưới lên dòng trên mà không kiểm tra lại thanks anh Nam nhiều anh nhiệt tình quá |
em đổi lại phần cứng rồi ạ, kiểu vừa quét led vừa bắt phím em làm chưa tốt
em chuyển phím bấm vào 3 chân RC0 1 2 mọi thứ đã tốt hơn nhiều rồi ạ. em vẫn chưa làm đuợc kiểu quét phím tiết kiêm chân, phải dùng thêm 3 chân nữa để bắt phím Thêm một cái nữa là em muốn tăng giảm độ sáng của led 7T thì làm thế nào ạ, bác nào giải thích cho em với ạ Một lần nữa rất cám ơn anh Nam đã quan tâm. Vậy là em mới làm xong time và date mode thôi, còn âm lịch, báo thức nữa Mong sẽ không phải làm phiền anh:D PS: em tìm ra lỗi rồi ạ, em dùng ngắt ngoài với chan RB0 đồng thời dùng portB đẻ đưa data vào led 7T nên bị thế ạ Vậy em phải làm thế nào để vừa dùng ngắt ngoài vừa dùng PORTB để đưa data vào leds ạ Thanks |
Sáng nay đọc thêm về timer nên đã làm 2 code, một dùng ds1307 và một chỉ dùng timer
dùng timer1 tạo ngắt, rồi đếm system clock (chứ không phải đếm số lần interrupt nên chính xác hơn) cho 1s lại update ds1307 một lần, Có vẻ tốt hơn rồi Đồng thời làm thêm đồng hồ số dựa trên timer, cho ra giá trị đúng 1s, em đang test rồi. cả hai cái đều chưa phát hiện thêm bug. Sai số phần lớn do XTAL Dùng timer như vậy có lợi thế nhỏ gọn hơn nhưng không có pin backup nên mất điện thì setup lại. Code:
#define XTAL_FREQUENCY 20000000 Code:
ticker = TIMER1_FREQUENCY; Code:
#int_TIMER1 Thanks PS: lần sau em sẽ rút kinh nghiệm không post code dài nữa ạ để tránh người đọc topic thấy chán ngán |
chào anh namqn và cá c anh em khác trong topic này . em đang làm con DS1307 bữa giờ , giao tiếp thành công rồi đọc set gia tri cho nó cũng được luôn rồi , chỉ mỗi tội là ko hiểu sao nó chạy hơn đồng hồ bình thường .cụ thể thế này : giả sử giờ hiện tại là 0h em set giá trị hour=0, minute=0, sec=0 và cho nó chạy, nó chạy bình thường, em canh đúng 1 tiếng đồng hồ với cái đồng hồ trên computer và xem lại thì cái đồng hồ chạy bằng con DS1307 chỉ mới chạy được 30 phút, vậy là do lý do gì, em thử so sánh 1 phút của nó cũng chay chậm hơn đồng hồ thường của mình. Em cung thư với cả hai loại VDK PIC và AVR đều cho chung kết quả như nhau. em đã cho thạch anh nằm gần sát với 2 chân dao động của con DS1307 .anh em nào bit tại sao chỉ giúp với.
|
Về số dạng BCD với ds1307
Nhân tiện xin hỏi thêm các huynh về số BCD trong ds1307 như sau:
Nếu ta ghi vào ds1307 giá trị là 0x15 thì nó nhận là 00010101 ở dạng BCD (giá trị = 15 thập phân). Như vậy, cùng một số 0x15, con ds1307 sẽ nhận là 15, còn con Pic nhận là 21 thập phân ? Không biết em hiểu như vậy đã chính xác chưa, có gì nhờ các huynh chỉ giáo. |
Trích:
Trong hệ đếm 16, số 21 (hệ đếm 10) được biểu là 15, và thường đc ký hiệu là 0x15 (0x ám chỉ con số sau nó ở hệ cơ số 16) Nhưng cũng số 21 (hệ đếm 10) nếu xét trong hệ mã hóa BCD thì nó có giá trị là 15 (hệ đếm 10). |
Trích:
Thân, |
em thử với thạch anh khác rồi , kết quả là nó còn chậm hơn cái thạch anh cũ. bây giờ làm sao đây anh , thay luôn con ds1307 mới luôn hả anh. sáng mai em định mang cả cái mạch đi nhờ cái máy hiện sóng kiểm tra thử xem thạch anh có hoạt động đúng tần số chưa (bằng cách đo xung ơ chân của thạch anh dao động khi mạch đang hoạt động , ko bít có đúng ko).
|
Múi giờ GMT. Hiện tại là 10:21 AM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam