PDA

View Full Version : pwm của 16F877A


anh_gioi
14-03-2008, 12:54 AM
#include "C:\Documents and Settings\anh gioi\Desktop\dieu xung\dieu xung.h"

//#use fast_io(b)

void main()
{

int8 i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

while(1)
{
setup_ccp1(ccp_pwm);
set_pwm1_duty(0);
setup_ccp2(ccp_pwm);
set_pwm2_duty(0);
delay_ms(3000);
setup_ccp1(ccp_pwm);
set_pwm1_duty(10);
setup_ccp2(ccp_pwm);
set_pwm2_duty(10);
delay_ms(3000);
setup_ccp1(ccp_pwm);
set_pwm1_duty(1024);
setup_ccp2(ccp_pwm);
set_pwm2_duty(1024);
delay_ms(3000);

}
}


khi chạy chương trình này tớ thấy không đúng? đo điện áp cũng chỉ ở mức 0 và 5v?
ko biết tại sao nữa.mong các bác chỉ dùm cái????
thank!!!!!

namqn
14-03-2008, 05:50 AM
Đề nghị bạn đọc mục 8.3.3 - SETUP FOR PWM OPERATION trong datasheet của PIC16F877A. Bạn sẽ thấy rằng CCP1 và CCP2 ở chế độ PWM sẽ dùng chung Timer2 làm bộ đếm thời gian chu kỳ. Bạn cũng dựa vào bảng 8-3 để xác định phạm vi cho phép của duty cycle, khi đã chọn giá trị cho PR2. Ngay cả khi dùng độ phân giải 10-bit cho duty cycle, bạn cũng không thể đặt duty cycle = 1024 (như bạn đã thực hiện trong code của bạn), vì 1024 không thể chứa trong 10 bit.

Thân,

0903579509
14-03-2008, 09:45 AM
Bạn phải kích hoạt T2 bằng cách dùng hàm setup_timer_2(T2_DIV_BY_16,255,1) thì module PWM mới hoạt động. Các thông số trong hàm này bạn có thể thay đổi có tần số mong muốn.
Bạn nên dùng PWM 8 bit trước sau đó mới nghĩ đến 10bit. Theo tôi sử dụng 8 bit là đủ rồi.
Đoạn Code sửa lại như sau:

#include "16F877a.h"
#device *=16
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES RC //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)

//#use fast_io(b)

void main()
{

//int8 i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1); // KICH HOAT T2 TAI DAY, BAN CO THE THAY DOI CAC THONG SO TRONG HAM NAY DE CO TAN SO MONG MUON
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

while(1)
{
setup_ccp1(ccp_pwm);
set_pwm1_duty(0);
setup_ccp2(ccp_pwm);
set_pwm2_duty(50);
delay_ms(300);
setup_ccp1(ccp_pwm);
set_pwm1_duty(128);
setup_ccp2(ccp_pwm);
set_pwm2_duty(100);
delay_ms(300);
setup_ccp1(ccp_pwm);
set_pwm1_duty(255);
setup_ccp2(ccp_pwm);
set_pwm2_duty(200);
delay_ms(300);

}
}
Tôi đã mô phỏng trên Protues chay tốt, không biết trên mạch thì thế nào.
Mạch mô phỏng dưới đây:
Chúc thành công!

anh_gioi
14-03-2008, 10:45 AM
Bạn phải kích hoạt T2 bằng cách dùng hàm setup_timer_2(T2_DIV_BY_16,255,1) thì module PWM mới hoạt động. Các thông số trong hàm này bạn có thể thay đổi có tần số mong muốn.
Bạn nên dùng PWM 8 bit trước sau đó mới nghĩ đến 10bit. Theo tôi sử dụng 8 bit là đủ rồi.
Đoạn Code sửa lại như sau:

#include "16F877a.h"
#device *=16
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES RC //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)

//#use fast_io(b)

void main()
{

//int8 i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1); // KICH HOAT T2 TAI DAY, BAN CO THE THAY DOI CAC THONG SO TRONG HAM NAY DE CO TAN SO MONG MUON
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

while(1)
{
setup_ccp1(ccp_pwm);
set_pwm1_duty(0);
setup_ccp2(ccp_pwm);
set_pwm2_duty(50);
delay_ms(300);
setup_ccp1(ccp_pwm);
set_pwm1_duty(128);
setup_ccp2(ccp_pwm);
set_pwm2_duty(100);
delay_ms(300);
setup_ccp1(ccp_pwm);
set_pwm1_duty(255);
setup_ccp2(ccp_pwm);
set_pwm2_duty(200);
delay_ms(300);

}
}
Tôi đã mô phỏng trên Protues chay tốt, không biết trên mạch thì thế nào.
Mạch mô phỏng dưới đây:
Chúc thành công!

chán thật! đọc ko chịu đọc.thank moi nguoi nha.
hóa ra pải dùng timer2 cho pwm,lại còn quên số bít nũa.hic.....mình GÀ thật !!
thank! tối mình về làm có gì hỏi tiếp nha...

vinasheva
22-10-2009, 06:11 PM
Em làm đoạn code như sau. Mặc định PWM là 8bit. Làm thế nào để khai báo PWM 10 bit?

setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,254,1);
set_pwm1_duty(100);
set_pwm2_duty(200);