PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Lập nhóm PIC16F877A (http://www.picvietnam.com/forum/showthread.php?t=325)

nhh 17-03-2006 05:57 PM

Trích:

Nguyên văn bởi pb1
em đã nghiền hết mấy bài của bác nhh rồi, em đang chờ các bài tiếp theo của bác nhh đây. Bác nhanh nhanh viết thêm nữa đi chứ.

Mấy tuần rày hơi nhát!:D
Bài tiếp chắc là cái đồng hồ điện tử.Hy vọng là tuần tới tớ sẽ cơ bản xong và post lên cho anh em chỉ giáo thêm!

namqn 17-03-2006 06:14 PM

Những nhận xét của ntc là chính xác.
Cho dù bạn viết bằng ngôn ngữ gì thì cuối cùng con PIC cũng phải chạy chương trình của bạn, và bản thân nó chỉ hiểu mỗi mã nhị phân nằm trong bộ nhớ chương trình của nó mà thôi. Vì lập trình bằng mã nhị phân quá khó khăn đối với con người, nên mới có nhiều ngôn ngữ lập trình được tạo ra để giúp cho việc lập trình được dễ dàng hơn. Chẳng qua vào thời điểm này không có trình biên dịch (compiler) lý tưởng nào có thể thay thế được trình hợp dịch (assembler) trong mọi trường hợp mà thôi. Và để lập trình bằng hợp ngữ một cách hiệu quả thì thông thường bạn phải có một con vi điều khiển được mô phỏng trong chính bạn, để kiểm soát chương trình bạn đang viết, một công việc quá khó khăn cho những người mới học.
Không ít người đã tự xây dựng ngôn ngữ lập trình và trình biên dịch cho riêng mình, chẳng hạn như Vladimir Soso (viết Basic compiler) hay Wouter van Ooijen (sáng tạo JAL và viết JAL compiler).

Thân,

pb1 18-03-2006 08:54 PM

help me about motor
 
em đang sử dụng PIC16f877A để điều khiển động cơ DC, yêu cầu điều khiển động cơ:(1) ổn định tốc độ động cơ khi địa hình thay đổi. (2) Chuyển từ RF sang RR(trái->phai) không bị giật. (3) Tùy ý thiết đặt tốc độ.

Có bác nào đã làm về vấn đề này, xin chỉ giáo giúp

pb1 18-03-2006 08:56 PM

Bác nhh có thể giúp em một tay không?

nhh 19-03-2006 09:12 AM

Trích:

Nguyên văn bởi pb1
em đang sử dụng PIC16f877A để điều khiển động cơ DC, yêu cầu điều khiển động cơ:(1) ổn định tốc độ động cơ khi địa hình thay đổi. (2) Chuyển từ RF sang RR(trái->phai) không bị giật. (3) Tùy ý thiết đặt tốc độ.

Có bác nào đã làm về vấn đề này, xin chỉ giáo giúp

Chao ban!
De moi nguoi de hinh dung va tham gia nhiet tinh vao van de cua ban,ban co the post so do nguyen li va code ban viet len.Nhu the minh tin van de se duoc giai quyet nhanh hon!

Chao!

nhh 19-03-2006 09:26 AM

Traffic light
 
Chào cả nhà!

Ý định tuần này của nhh là viết chương trình cho cái digital clock với timer, led 7 đoạn, phím nhấn,...nhưng nghĩ đi nghĩ lại giang hồ luyện chiêu này bằng IC thời gian thực DS1307, DS1337,...giao tiếp I2C...mình lại dùng timer định thì nhảy tới nhảy lui thật khó coi quá !

Mục đích cũng để tìm hiểu hoạt động của các timer, do vậy mà nhh tạm gác cái digital clock này lại. Bù lại mình sẽ làm một cái mạch đèn giao thông ,dùng ngắt timer0.

PIC16F877A có 3 timer ,timer0 và timer2 là hai timer 8bit còn timer1 là timer 16bit.
nhh chỉ đề cập đến những phần có liên quan đến timer0 trong ứng dụng này.Còn lại tham khảo trong datasheet viết rất rõ.
Các thanh ghi tác động timer0 gồm INTCON và OPTION_REG. Để khởi động timer0,xóa bit T0CS về 0.Lúc này thanh ghi TMR0 sẽ tự động tăng lên một ứng với mỗi chu kỳ lệnh

http://www.freewebtown.com/bantoi/PIC/Timer0.gif

Hoạt động ngắt của timer0 rất đơn giản,ngắt xảy ra khi tràn timer0 từ FFh về 00h
Khi ngắt này xảy ra cờ ngắt timer0 phất lên (bit TMR0IF được set lên 1) ,khi vào ngắt phải xóa cờ này về 0.
Bit PSA trên thanh ghi OPTION_REG chỉ định Prescaler cho timer0 hay WDT.Dùng timer0 thì xóa bit này.
Ba bit PS0,PS1,PS2 dùng chia tốc độ timer0 từ 2 đến 256 ,chia tốc độ WDT từ 2 đến 128.

Trong ứng dụng này do timer0 tràn sớm hơn 1s khi dùng thạch anh 10MHz,do vậy dùng thêm một biến đếm số lần tràn sao cho khi biến này giảm xuống 0 thì xấp xỉ 1s.

Trong 20s đầu,đèn xanh bật ON,từ giây 21 đến 30 có thêm đèn vàng ON, 20s cuối đèn đỏ ON.

Các chân từ a đến g của led 7 seg đầu nối với RC0 đến RC6, led còn lại nối RB0 đến RB6.

nhh 19-03-2006 09:30 AM

1 Attachment(s)
Code:

;========================================
;Author:                NHH
;Date:                18/03/06
;Hardware:        PIC16F877A
;                QUARTZ  10MHz
;========================================
        PROCESSOR        PIC16f877A
        INCLUDE<P16f877A.inc>
        __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _CPD_OFF &_LVP_OFF
;========================================
        COUNT1 EQU 0x20
        COUNT2 EQU 0x21
        COUNT3 EQU 0x22
        w_temp                EQU        0x71                ; variable used for context saving
        status_temp        EQU        0x72                ; variable used for context saving
        pclath_temp        EQU        0x73                ; variable used for context saving
;===============MAIN PROGRAM===========
        ORG        0x000
        GOTO        MAIN
        ORG        0004h
        GOTO        INTERRUPT
;============INTERRUPT PROGRAM=========
INTERRUPT
        movwf w_temp        ; save off current W register contents
        movf STATUS,w        ; move status register into W register
        movwf status_temp        ; save off contents of STATUS register
        movf PCLATH,w        ; move pclath register into w register
        movwf pclath_temp        ; save off contents of PCLATH register
;****************************************
        BCF        INTCON,TMR0IF

        DECFSZ        COUNT1,F
        RETFIE
        MOVLW        d'154'
        MOVWF        COUNT1

        INCF        COUNT2,F
        MOVF        COUNT2,W
        CALL        TABLE
        MOVWF        PORTB

        CALL        CHECK_YELLOW
        CALL        CHECK_GREEN
        CALL        CHECK_RED

        MOVLW        d'10'
        SUBWF        COUNT2,W
        BTFSS        STATUS,0
        RETFIE
        CLRF        COUNT2
        INCF        COUNT3,F
        MOVF        COUNT3,W
        CALL        TABLE
        MOVWF        PORTC

        RETFIE       
;****************************************
        movf pclath_temp,w                ; retrieve copy of PCLATH register
        movwf PCLATH                ; restore pre-isr PCLATH register contents
        movf status_temp,w                ; retrieve copy of STATUS register
        movwf STATUS                ; restore pre-isr STATUS register contents
        swapf w_temp,f
        swapf w_temp,w                ; restore pre-isr W register contents
        retfie                        ; return from interrupt
;.............................................................................................
MAIN
        BCF        STATUS,RP1
        BSF        STATUS,RP0                ; select BANK 1
        CLRF        TRISB                        ; PORTB,C,D  output
        CLRF        TRISC
        CLRF        TRISD
        BSF        OPTION_REG,PS0                ;TMR0 rate 1: 64
        BCF        OPTION_REG,PS1
        BSF        OPTION_REG,PS2
        BCF        OPTION_REG,PSA                ;Prescaler is assigned to the Timer0 module
        BCF        OPTION_REG,T0CS                ;enable TMR0
        BCF        STATUS,RP0                ;select BANK 0

        BSF        INTCON,GIE
        BSF        INTCON,TMR0IE
        BCF        INTCON,TMR0IF

        MOVLW        d'154'
        MOVWF        COUNT1
        MOVLW        d'1'
        MOVWF        COUNT2
        CLRF        COUNT3
        MOVLW        b'00000110'
        MOVWF        PORTB
        MOVLW        b'00111111'
        MOVWF        PORTC

        MOVLW        b'00000100'
        MOVWF        PORTD
        GOTO        $
;========================================
CHECK_YELLOW
        BTFSS        PORTD,0
        GOTO        $+2
        RETURN
        MOVLW        d'2'
        SUBWF        COUNT3,W
        BTFSS        STATUS,0
        RETURN
        MOVLW        b'00000110'
        MOVWF        PORTD
        RETURN
CHECK_GREEN
        BTFSC        PORTD,0
        GOTO        $+2
        RETURN
        MOVLW        d'2'
        SUBWF        COUNT3,W
        BTFSS        STATUS,0
        RETURN
        GOTO        MAIN
        RETURN
CHECK_RED
        MOVLW        d'3'
        SUBWF        COUNT3,W
        BTFSS        STATUS,0
        RETFIE

        MOVLW        d'1'
        MOVWF        COUNT2
        CLRF        COUNT3
        MOVLW        b'00000110'
        MOVWF        PORTB
        MOVLW        b'00111111'
        MOVWF        PORTC
        MOVLW        b'00000001'
        MOVWF        PORTD
        RETURN       
;-----------------------------------------------------------------------
; Bang tra ve Digital tu 0 den 9
; Chi so dau truy cap la 0
; Bang o PAGE 0

        ORG 0x90
TABLE
;-----------------------------------------------------------------------
        ADDWF        PCL, F                        ; bat dau tai 0x80
        RETLW        b'11111111'                ; NO DISPLAY
        RETLW        b'00000110'                ; 1
        RETLW        b'01011011'                ; 2
        RETLW        b'01001111'                ; 3
        RETLW        b'01100110'                ; 4
        RETLW        b'01101101'                ; 5
        RETLW        b'01111101'                ; 6
        RETLW        b'00000111'                ; 7
        RETLW        b'01111111'                ; 8
        RETLW        b'01101111'                ; 9
        RETLW        b'00111111'                ; 0

        END

http://www.freewebtown.com/bantoi/PI...ic%20light.gif

nhh 19-03-2006 09:33 AM

Hex file
Code:

:020000040000FA
:020000002728AF
:080008000528F1000308F200D5
:100010000A08F3000B11A00B09009A30A000A10AF6
:1000200021089020860041204B2054200A302102D4
:10003000031C0900A101A20A2208902087000900E0
:1000400073088A0072088300F10E710E0900031311
:100050008316860187018801011481100115811121
:10006000811283128B178B160B119A30A00001306E
:10007000A100A201063086003F30870004308800CE
:100080004028081C4428080002302202031C0800F3
:1000900006308800080008184E28080002302202A6
:1000A000031C08002728080003302202031C090053
:1000B0000130A100A201063086003F3087000130E8
:0400C00088000800AC
:100120008207FF3406345B344F3466346D347D34DB
:0801300007347F346F343F34C3
:02400E00323F3F
:00000001FF


nhh 19-03-2006 09:47 AM

Các bác xem xét và cho ý kiến,hình như nó vẫn chưa tối ưu.Thiên hạ chắc cũng không ai làm thế này!:D

pb1 20-03-2006 12:06 AM

PWM cho PIC16f877A
 
Sử dụng PIC chạy với thạch anh là 4MHz, tần số điều chế độ rộng xung là 1000Hz với duty cycle là 50%
;================================================= ========
1/ thiết lập chu kì PWM (1000Hz=0.001S) bằng cách ghi vào thanh ghi PR2.
Chu kì điều chế độ rộng xung(PWM Period)=(PR2+1)*4*Tosc*TMR2 Prescale value
tỉ lệ TMR2 prescale là 1:4, thì ta có
Tosc=1/4000000=2.5*10-7
ta cũng có
PR2=(Period/(4*Tosc*TMR2 prescale))-1
nên: PR2=(0.001/(4*2.5*10-7*4))-1=249
bằng cách thiết lập như vậy ta có chương trình như sau:(viết bằng assembler, lần sau sẽ là Hi-Tech PIC) :D
bsf STATUS,PR0;change from bank 1 to bank 0
movlw d'249'
movwf PR2
bcf STATUS,PR0
;================================================= ========
2/ thiết lập PWM duty cycle bằng cách ghi vào thanh ghi CCPR1L và hai bit 5 và 4 của thanh ghi CCP1CON.
ta có công thức sau:
PWM duty cycle= (CCPR1L:CCP1CON<5:4>)*Tosc*TMR2 Prescale value
nên suy ra: CCPR1L:CCP1CON<5:4>=PWM duty cycle/(Tosc*TMR2 prescale)
PWM duty cycle=50% của chu kỳ
PWM duty cycle=50%*0.001=0.0005
CCPR1L:CCP1CON<5:4>=0.0005/(2.5*10-7*4)
CCPR1L:CCP1CON<5:4>=500
Số 500 trong số nhị phân viết là:0111110100
vậy:CCPR1L=01111101 và CCP1CON<5:4>=00
do đó, ta có chương trình sau:
movlw b'01111101'
movwf CCPR1L
bcf CCP1CON,CCP1X;set bit 1
bcf CCP1CON,CCP1Y;set bit 0
;================================================= ========
3/thiết lập chân CCP1 là một lối ra bằng cách xóa bit TRISC<2>
bsf STATUS,PR0
movlw b'11111011'
andwf TRISC
bcf STATUS,PR0
:D
;================================================= ========
4/thiết lập giá trị prescale TMR2 và cho phép TMR2 bằng cách ghi vào T2CON(thanh ghi điều khiển Timer2)
Ta đã sử dụng từ trước là thiết lập giá trị prescale là 1:4.
Prescale TMR2 là các bit 1 và 0 trong thanh ghi T2CON
Để cho phép TMR2 là bit số 2.
Ta có đoạn chương trình như sau:
movlw b'00000101' ;Timer2 on,prescale=1:4
movwf T2CON
;================================================= ========
5/Thiết lập CCP1 ở chế độ điều chế độ điều chế độ rộng xung (PWM module)
movf CCP1CON,W
andlw b'00110000'
iorlw b'00001111';cho phép module PWM
movwf CCP1CON
;================================================= ========
thế đã nhỉ, mệt quá, đi ngủ thôi
:D
Đã lâu không viết băng assembler, hôm nay tiện làm về điều khiển động cơ, thế là hứng lên viết mấy dòng, có lẽ có nhiều thếu sot, mong các bác góp ý cho em

Khi nào em làm xong về điều khiển động cơ thì em sẽ port các sch lên diễn đàn cho cả nhà xem, rất mong cả nhà góp ý


thân!

falleaf 20-03-2006 07:31 AM

Các bài viết trong luồng này rất hay, các bạn đang thảo luận về PWM, có thể nhấn thêm một bước bây giờ giả sử khi kết hợp 2 chân PWM nhưng làm xung trên 2 chân xen kẽ với nhau xem nào?

Đây có thể chỉ là một bài tập vui nhưng cũng có ứng dụng nhiều đấy.

Chúc vui.

pb1 20-03-2006 09:50 AM

hì, thế còn capture module thì sao nhỉ, có ai viết tiếp không?

ntc 20-03-2006 11:20 AM

Mình có một vài ý kiến về cách thiết kế mạch đèn giao thông của nhh như thế này: :D

Tất nhiên là chọn PORT điều khiển như thế nào cũng được, nhưng theo mình, khi thiết kế một ứng dụng, cần tìm cách để thiết kế là tối ưu.

Do PIC16F877A được tích hợp khá nhiều chức năng ngoài chức năng I/O thông thường, nên việc lựa chọn PORT điều khiển cũng nên cân nhắc. MÌnh nêu lên một số điểm như sau:

PORT C của PIC16F877A ngoài chức năng I/O là các chức năng CCP và giao tiếp nối tiếp (SPI, I2C,... ). Nếu nhh chọn PORT này làm PORT điều khiển các chân a-g của các LED thì các chức năng on-chip nêu trên sẽ không tương tác được nữa.

PORT D ngoài chức năng I/O là chức năng PSP (Parallel Slave Port). Chức năng giao tiếp này ít được sử dụng do số lượng chân cần cho giao tiếp khá lớn (8 chân PORT D và 3 chân PORT E), nhưng nhh đã sử dụng 3 chân để bật đèn giao thông. Như vậy chức năng này cũng bị mất luôn.

Có thể nói ta đã phí phạm 3 chức năng on-chip của PIC16F877A. Tất nhiên là trong ứng dụng của nhh ta chưa cần quan tâm đến vấn đề này, nhưng mình cũng muốn nêu lên để anh em cùng thảo luận.

Theo mình thì nên sửa lại như thế này:

Các chân data của Led 7 đoạn, mình sẽ đưa vào PORT D.
Các chân điều khiển đèn giao thông và quét LED sẽ đưa vào PORT B luôn.

Như vậy ta có thể tiết kiệm được các chức năng CCP và giao tiếp ở PORT C, cái mất đi chỉ là cái ít đụng tơi PSP, còn ngắt PORT B thì vẫn còn vài chân.

Trong các ứng dụng của mình có dính tới LED 7 đoạn, mình cũng bố trí các chân điều khiển như vậy.

Về chương trình cũng sẽ không có thay đổi lớn. Bạn nên "#define ..." các chân và PORT điều khiển. Như vậy khi cần thay đổi chân điều khiển, ta chỉ cần thay đổi cái phần define mà không cần phải sửa lại trong toàn bộ chương trình. Hơn nữa chương trình khi đọc cũng sẽ thân thiện và dễ hiểu hơn.

Một vài ý kiến góp vui như vậy. Anh em thấy thế nào.

:D

ntc 20-03-2006 12:06 PM

Tiếc quá nhh không làm cái Timer. Nếu làm cái Timer, bạn sẽ có thêm một kinh nghiệm sương máu và một thủ thuật kinh điển khi lập trình bằng ASM. Cái kinh nghiệm này mĩnh cũng chỉ vừa mới rút ra thôi. :D.

Nó có liên quan tới kĩ thuật bảng. :D

ngohaibac 20-03-2006 02:37 PM

Trích:

Nguyên văn bởi nhh
Để khởi động timer0,xóa bit T0CS về 0.Lúc này thanh ghi TMR0 sẽ tự động tăng lên một ứng với mỗi chu kỳ lệnh

T0CS không phải dùng để khởi động Timer0 mà T0CS dùng để chọn cho Timer0 ở chế độ timer hay counter.

Chế độ timer (T0CS = 0) thì TMR0 sẽ tăng lên 1 sau mỗi chu kì lệnh (khi prescaler = 1, nếu khác 1 thì là bộ của chu kì lệnh).

Chế độ counter thì T0CS =1 khi đó TMR0 sẽ tăng lên mỗi khi có một sườn lên hoặc sườn xuống xuất hiện trên chân T0CKI (RA4) ( chân này dạng open - drain nên bình thường nếu set dạng I/O bình thường thì phải mắc thêm trở kéo lên). Và chúng ta phải chọn sườn lên hay sườn xuống qua bít T0SE.
Trích:

Trong ứng dụng này do timer0 tràn sớm hơn 1s khi dùng thạch anh 10MHz,do vậy dùng thêm một biến đếm số lần tràn sao cho khi biến này giảm xuống 0 thì xấp xỉ 1s.

Trong 20s đầu,đèn xanh bật ON,từ giây 21 đến 30 có thêm đèn vàng ON, 20s cuối đèn đỏ ON.

Các chân từ a đến g của led 7 seg đầu nối với RC0 đến RC6, led còn lại nối RB0 đến RB6.
Mình nghĩ bạn nên làm một timer0 trễ 1ms. Sau đó tuỳ ứng dụng mình sẽ sử dụng là bội của 1ms này. Tức là dùng biến static để đếm sự kiện tràn timer0.

Lưu ý: timer0 là bộ free - auto counter sau khi thiết lập ở chế độ timer thì nó sẽ đếm mãi mà không dừng. thanh ghi OPTION ở chế độ sau reset = 0xFF nên ban đầu nó ở chế độ Counter sẽ đếm xung bên ngoài.

Mình xin ví dụ một hàm ngắt với timer0 dùng HTPIC. Với thạch anh 20MHZ thì hàm ngắt timer0 1ms -> TMR0 = 6

Code:

void interrupt inter0(void){
        static unsigned char i;
        static unsigned int counter; // bien dem su kien ngat timer0
        if(T0IF & T0IE){ // neu co ngat Timer0 xay ra
                TMR0 = 6;
                T0IF = 0 ; // xoa co ngat, cong viec khong the thieu sau ham ngat
                ++        counter;
                if (counter == a ) {
                        // do something
                };
                };
}

Trong hàm init chọn như sau: dùng pre cho timer0 với tỉ lệ 1:2
Code:

void init(void){
        // khoi tao cho các port

       
        // Khoi tao cho cac thanh ghi       
        OPTION  = 0x00; // dung prescaler cho timer0 voi ti le la 1:2

        // Khoi tao cho ngat Timer0
        GIE = 1; // cho phep ngat toan cuc
        T0IE = 1; // cho phep ngat timer0
        T0IF = 0; // xoa co ngat timer0
        TMR0 = 6; // khoi tao
}



Múi giờ GMT. Hiện tại là 01:09 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam