Năm nay được nghỉ tết sớm, về quê với con Pic 16f887 vừa mua trước khi về. Quyết tâm học thêm chút ít về VDK trong những ngày nghỉ lai rai
.
Dạo quanh 1 vòng dientuvietnam, picvietnam, kiếm được cuốn " Microcontroller - Fundamentals and Applications with PIC" của tác giả Fernando E. Valdes-Perez và Ramon Pallas-Areny. Đây là cuốn sách đầu tiên về PIC mình đọc. Vì đã download và xem qua rất nhiều sách, nhưng chưa thấy cuốn nào viết dễ hiểu như cuốn này, giải thích rất cặn kẽ và căn bản. Bạn nào mới học Pic thì mình khuyên nên đọc cuốn này trước
Đọc được mấy chương thì bắt đầu ngứa ngáy, mở MPLAB IDE 8.43 mới kit vừa down hôm trước, tập tọe viết vài dòng để tắt mở led, đếm ngược đếm xuôi, delay đủ kiểu, chỉ chưa dám đụng đến timer, interrupt, PWM thôi
. Viết hoài mấy cái này cũng chán, ngồi nghĩ hoài không biết viết cái gì cho vui 1 chút. Chợt nhớ ra có cái đầu thu IR làm cách đây lâu lắc, theo hướng dẫn này . Lôi ra tháo con mắt hồng ngoại, cắm vào để thử nhận tín hiệu từ cái remote TV.


Khó khăn đầu tiên là: Con IR receiver này mua ở Nhật Tảo, ko có ghi thông số gì cả. Loay hoay mãi rồi cũng tìm được đâu là signal Out, Vcc, GND.
Cắm con mắt vào board, nối thêm cái C1815 để khuếch đại tín hiệu ra xem thử, thấy led vẫn nháy khi bấm remote: OK
vẫn hoạt động tốt ( dù lúc nãy cắm ngược Vss và Vcc và có mùi hơi khét
)
Xong, Giờ nối trực tiếp cái tín hiệu ra vào chân PIC và bắt đầu cho chạy thử, đoạn code thế này
Pic sẽ nhận tín hiệu từ mắt hồng ngoại ở chân RA5 và phát led tín hiệu ở RA4, tức là khi có xung 1 từ mắt hồng ngoại thì led sẽ sáng. Biến DAT0 để lưu giữ trạng thái ở 8 lần lấy mẫu và xuất ra RB0.
Khoảng thời gian delay là ước chừng, vì mình ko có datasheet của con hồng ngoại, cũng không biết được cách mã hóa của cái remote TV, thử tìm tài liệu cũng không thấy.
Lấy remote ra bấm bấm, led RB4 sáng, RB0 hiển thị 1010... gì đó. Nhưng mỗi lần bấm thì lại không giống nhau, như vậy có lẽ thời gian delay không đúng, nên lấy mẫu không được chính xác rồi.
Thử thay đổi thời gian delay -> build-> nạp-> chạy cũng không khả quan gì, kiểu này mà làm xong chắc con PIC hết nạp được nữa luôn quá
Tới đây bắt đầu thấy bí, giá mà có cái oscilloscope thì hay biết mấy
Mà giờ kiếm oscilloscope ở đâu ra chứ
, thôi đành tiếp tục dùng cách này.
Để thay đổi thời gian delay mà không phải nạp đi nạp lại, mình viết thêm 1 hàm nhận số liệu từ PC, rồi viết luôn cái đoạn gửi mẫu về PC theo đường UART, lần này số byte mẫu là 8 => 8x8 = 64 lần lấy mẫu, khoảng thời gian delay sẽ được PC truyền qua. Code mình bây giờ thế này
Mô tả xíu về ý tưởng:
Sau khi khởi tạo các giá trị cho UART, pic sẽ đợi nhận 1 byte từ PC, chuyển byte đó cho biến IR_TIME. thì bắt đầu lấy mẫu từ tín hiệu hồng ngoại. Khi thấy MSB của DAT7 bằng 1 thì dừng lấy mẫu và chuyển lần lượt 8 byte đó về PC. Muốn thay đổi thời gian delay thì chỉ cần reset lại pic và truyền giá trị mới
Sau khi thử vô số lần với delay khác nhau, mình cũng tìm ra được thời gian delay để lấy mẫu được khớp. Tuy nhiên mẫu lấy về vẫn bị lỗi khá nhiều. Đặc biệt là khi ấn nút liên tục .

Đây là hình mình chụp lúc lấy mẫu cùng 1 nút nhiều lần.
Vấn để ở đây là không biết nhiễu từ đâu mà ra, có thể do mắt thu hồng ngoại chất lượng ko đảm bảo. Hoặc do khử nhiễu không tốt, hoặc do thời gian lấy mẫu chưa đúng.
Ai biết ký hiệu của mắt hồng ngoại trong orcad/proteus là gì không,mình định vẽ sơ cái mạch mà không biết ký hiệu của nó.
Bài viết sẽ được tiếp tục cập nhật

Dạo quanh 1 vòng dientuvietnam, picvietnam, kiếm được cuốn " Microcontroller - Fundamentals and Applications with PIC" của tác giả Fernando E. Valdes-Perez và Ramon Pallas-Areny. Đây là cuốn sách đầu tiên về PIC mình đọc. Vì đã download và xem qua rất nhiều sách, nhưng chưa thấy cuốn nào viết dễ hiểu như cuốn này, giải thích rất cặn kẽ và căn bản. Bạn nào mới học Pic thì mình khuyên nên đọc cuốn này trước

Đọc được mấy chương thì bắt đầu ngứa ngáy, mở MPLAB IDE 8.43 mới kit vừa down hôm trước, tập tọe viết vài dòng để tắt mở led, đếm ngược đếm xuôi, delay đủ kiểu, chỉ chưa dám đụng đến timer, interrupt, PWM thôi



Khó khăn đầu tiên là: Con IR receiver này mua ở Nhật Tảo, ko có ghi thông số gì cả. Loay hoay mãi rồi cũng tìm được đâu là signal Out, Vcc, GND.

Cắm con mắt vào board, nối thêm cái C1815 để khuếch đại tín hiệu ra xem thử, thấy led vẫn nháy khi bấm remote: OK


Xong, Giờ nối trực tiếp cái tín hiệu ra vào chân PIC và bắt đầu cho chạy thử, đoạn code thế này
Code:
MAIN_PROG: banksel ANSEL movlw 00h movwf ANSEL ; all pin of RA is digital input banksel TRISA bsf TRISA,5 ;RA5 is input bcf TRISA,4 ;RA4 is ouput movlw 00h movwf TRISB ;all pins of RB is digital ouput banksel PORTA ;select bank0 movlw 00h movwf PORTB LOOP: btfsc PORTA,5 goto LED_OFF LED_ON: bsf PORTA,4 ;Led indicator bsf STATUS,C movf DAT0,0 ;DAT0 là biến lưu dữ liệu movwf PORTB goto END_IF LED_OFF: bcf PORTA,4 bcf STATUS,C movf DAT0,0 movwf PORTB END_IF: call DELAY ;Delay giữa mỗi lần lấy mẫu btfss DAT0,7 goto LOOP STOP: call BIG_DELAY ;Lấy đủ 1 byte mẫu, dừng để hiển thị lên led goto LOOP
Khoảng thời gian delay là ước chừng, vì mình ko có datasheet của con hồng ngoại, cũng không biết được cách mã hóa của cái remote TV, thử tìm tài liệu cũng không thấy.
Lấy remote ra bấm bấm, led RB4 sáng, RB0 hiển thị 1010... gì đó. Nhưng mỗi lần bấm thì lại không giống nhau, như vậy có lẽ thời gian delay không đúng, nên lấy mẫu không được chính xác rồi.
Thử thay đổi thời gian delay -> build-> nạp-> chạy cũng không khả quan gì, kiểu này mà làm xong chắc con PIC hết nạp được nữa luôn quá

Tới đây bắt đầu thấy bí, giá mà có cái oscilloscope thì hay biết mấy

Mà giờ kiếm oscilloscope ở đâu ra chứ

Để thay đổi thời gian delay mà không phải nạp đi nạp lại, mình viết thêm 1 hàm nhận số liệu từ PC, rồi viết luôn cái đoạn gửi mẫu về PC theo đường UART, lần này số byte mẫu là 8 => 8x8 = 64 lần lấy mẫu, khoảng thời gian delay sẽ được PC truyền qua. Code mình bây giờ thế này

Code:
ORG 05h MAIN_PROG: pagesel INIT_SCI call INIT_SCI banksel ANSEL movlw 00h movwf ANSEL ; all pin of RA is digital input banksel TRISA bsf TRISA,5 ;RA5 is input bcf TRISA,4 ;RA4 is ouput movlw 00h movwf TRISB ;all pin of RB is digital ouput banksel PORTA ;select bank0 movlw 00h movwf PORTB bsf PORTA,4 ;Turn led on call RCDATA movwf IR_TIME movwf PORTB bcf PORTA,4 ;Turn led off,start working LOOP: btfsc PORTA,5 goto LED_OFF LED_ON: bsf PORTA,4 ;Led indicator bsf STATUS,C rlf DAT0,1 rlf DAT1,1 rlf DAT2,1 rlf DAT3,1 rlf DAT4,1 rlf DAT5,1 rlf DAT6,1 rlf DAT7,1 movf DAT0,0 movwf PORTB goto END_IF LED_OFF: bcf PORTA,4 bcf STATUS,C rlf DAT0,1 rlf DAT1,1 rlf DAT2,1 rlf DAT3,1 rlf DAT4,1 rlf DAT5,1 rlf DAT6,1 rlf DAT7,1 movf DAT0,0 movwf PORTB END_IF: call DELAY btfss DAT7,7 goto LOOP STOP: movf DAT7,0 call TXDATA movf DAT6,0 call TXDATA movf DAT5,0 ;W = DATH call TXDATA movf DAT4,0 call TXDATA movf DAT3,0 call TXDATA movf DAT2,0 ;W = DATH call TXDATA movf DAT1,0 call TXDATA movf DAT0,0 call TXDATA call BIG_DELAY movlw 00h movwf DAT7 movwf DAT6 movwf DAT5 movwf DAT4 movwf DAT3 movwf DAT2 movwf DAT1 movwf DAT0 goto LOOP DELAY: movf IR_TIME,0 ;73 movwf COUNT2 LOOP2: movlw 0Fh movwf COUNT1 LOOP1: decfsz COUNT1,1 goto LOOP1 decfsz COUNT2,1 goto LOOP2 return BIG_DELAY: movlw 7h movwf COUNT3 LOOP3B: movlw 0FFh movwf COUNT2 LOOP2B: movlw 0FFh movwf COUNT1 LOOP1B: decfsz COUNT1,1 goto LOOP1B decfsz COUNT2,1 goto LOOP2B decfsz COUNT3,1 goto LOOP3B return INIT_SCI: banksel SPBRG movlw 4Dh ;9600bps with high baudrate mode selected movwf SPBRG movlw 00h movwf SPBRGH banksel RCSTA bsf RCSTA,SPEN ; enable serial port bcf RCSTA,RX9 bsf RCSTA,CREN ;enable receive banksel TXSTA bcf TXSTA,SYNC ;asynchronous transmission bcf TXSTA,TX9 ;disable 9bit transmission bsf TXSTA,BRGH ;enable hight baudrate bsf TXSTA,TXEN ;start transmission banksel PIE1 bcf PIE1,TXIE bcf PIE1,RCIE ;disable interrupt for EUSART banksel TRISC movlw 80h ;RX/RC7 is input movwf TRISC ;TX/RC6 is ouput return TXDATA: banksel PIR1 btfss PIR1,TXIF goto TXDATA movwf TXREG ;yes, the transmitter is free return RCDATA: banksel PIR1 btfss PIR1,RCIF goto RCDATA ;no, wait movf RCREG,0 return end
Sau khi khởi tạo các giá trị cho UART, pic sẽ đợi nhận 1 byte từ PC, chuyển byte đó cho biến IR_TIME. thì bắt đầu lấy mẫu từ tín hiệu hồng ngoại. Khi thấy MSB của DAT7 bằng 1 thì dừng lấy mẫu và chuyển lần lượt 8 byte đó về PC. Muốn thay đổi thời gian delay thì chỉ cần reset lại pic và truyền giá trị mới
Sau khi thử vô số lần với delay khác nhau, mình cũng tìm ra được thời gian delay để lấy mẫu được khớp. Tuy nhiên mẫu lấy về vẫn bị lỗi khá nhiều. Đặc biệt là khi ấn nút liên tục .

Đây là hình mình chụp lúc lấy mẫu cùng 1 nút nhiều lần.
Vấn để ở đây là không biết nhiễu từ đâu mà ra, có thể do mắt thu hồng ngoại chất lượng ko đảm bảo. Hoặc do khử nhiễu không tốt, hoặc do thời gian lấy mẫu chưa đúng.
Ai biết ký hiệu của mắt hồng ngoại trong orcad/proteus là gì không,mình định vẽ sơ cái mạch mà không biết ký hiệu của nó.
Bài viết sẽ được tiếp tục cập nhật

Comment