![]() |
|
Tài trợ cho PIC Vietnam |
PIC - Thiết kế và Ứng dụng Ý tưởng cho các sản phẩm sử dụng PIC/dsPIC và các sản phẩm của Microchip |
|
Ðiều Chỉnh | Xếp Bài |
![]() |
#7 |
Đệ tử 2 túi
Tham gia ngày: Feb 2009
Bài gửi: 35
: |
PIC16F877 bị tuyệt chủng từ từ, nên tôi khuyên bạn nên dùng PIC16F887 giống y hệt nhau, chỉ khác 877 bền hơn thôi. Lý do tôi khuyên bạn là vì 877 không còn được hổ trợ trong MPLAB IDE_HT PIC.
Bạn muốn điều khiển động cơ vòng kín, có hồi tiếp hay vòng hở. Tôi có làm mạch vòng hở dùng biến trở --> ADC --> PWM/ hien thị LCD16x2: //================================================== ============// // Module : main.c // Description : DIEU KHIEN TOC DO DONG CO BANG CACH DIEU CHE, // XUNG, KET HOP VOI BO CHUYEN DOI ADC,HIEN THI // GIA TRI ADC & TOC DO RA LCD 16X2. // // CONTROL MOTOR SPEED WITH PWM BY INPUT ADC VALUE // DISPLAY ADC & RPM ON LCD 16X2. // Tool : MPLAB IDE V8.63_HI-TECH PIC PRO V9.8 // Chip : 16F887A // DATE : 29 AUG 2012 // // Author : TRAN THANH TUAN // Notes : //================================================== ============// #include<htc.h> #include "lcd.h" #include <stdio.h> __CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS); //================================================== ============// //===========DEFINE GLOBAL VARIABLE=============================// //===========DINH NGHIA CAC BIEN TOAN CUC=======================// int xung; int adc;//Define variable ADC as integer //================================================== ============// //===================INITIALIZE ADC MODUL=======================// void init_adc() { ANS3 = 1; //SET RA3 RECEIVING ANALOG SIGNAL //SEE DATASHEET PAGE 99 VCFG0 = VCFG1 = 0; //SELECT VOLT REFERENCE BY INPUT RA3 ADCS0 = ADCS1 = 1; //Nguon dao dong Frc<=>500kHz ADFM = 1; //Canh phai ket qua CHS0 = CHS1 = 1; CHS2 = CHS3 = 0; //SELECT ADC CHANEL 3 ADON = 0;// Turn on function of ADC modul GODONE = 0;//Will set on in main program __delay_ms(1);//Waiting for MCU starting } //================Initialize PWM modul==========================// void init_pwm() { TRISC2 = 0; //Set RC3/CCP1 Output PWM //Set CCP1CON register for single PWM output //See page 124 of datasheet //CCP1CON = 0x0C;// //CCP2CON = 0x00; //CHOSE PWM 1KHz <=> TIMER2 PRESCALE 1/16; Bit PR2=0x7C; //PR2=0XF9<=>PWM=500Hz //SETTING TIMER 2, PRESCALE = 1:16 //T2CKPS<1:0> --> 00=1:4; 01=1:8; 1x=1:16 T2CKPS1 = 1; T2CKPS0 = 1; PR2 = 0x7C;// TMR2ON = 1;//START TIMER 2 } //===========INITIALIZE PWM MODUL===============================// void init_ngat() //XEM DATASHEET TRANG 128 { PEIE = 1;//cho phep ngat ngoai vi GIE = 1;//cho phep ngat toan cuc INTEDG = 0;//ngat RB0 khi co xung xuong INTF = 0;//xoa co ngat RB0 //INTE = 1;// chua cho phep ngat ngoai RB0 hoat dong //ADIE = 1;// cho phep ngat ADC //ADIF = 0;// xoa co bao ngat ADC } //================================================== ============// void init_timer1() { // TMR1CS: Timer 1 clock source select bit // TMR1CS = 1 : External clock form pin RC0 // TMR1CS = 0 : Internal clock Fosc/4 TMR1CS=0; // T1OSCEN: Timer1 oscillator enable control bit // T1OSCEN = 0 : Enable // T1OSCEN = 1 : Shut-off T1OSCEN=0; // T1CKPS1:T1CKPS0 Prescale clock select bit // 11 : 1/8; 10 : 1/4; 01 : 1/2; 00 : 1/1 T1CKPS1 = T1CKPS0 = 1; //presclaer = 1:8 TMR1GE=0;//Not used Gate Control T1SYNC=0;//khong dong bo TMR1IF=0;//CLEAR TIMER1 INTERRUPT FLAG //TMR1H = 0xCF;//100 ms //TMR1L = 0x2B; TMR1ON=0;//Not run Timer1 jet } //================================================== ============// void init_port() { ANS12 = 0;//Chon chuc nang cua chan RB0 la I/O digital TRISD = 0X00;//Cho port D xuat du lieu ra LCD TRISB0 = 1;//Cho chan RB0 nhan xung tu encoder RBPU = 0;//Xoa bit nay de chon chuc nang danh thuc don le WPUB = 0xff;//Bat chuc nang danh thuc MCU } //=====CHUONG TRINH DEM XUNG ENCODER====================// void interrupt ISR() { if(INTF && INTE) { xung++; INTF =0; } } //=====KHOI TAO HAM readADC(), gia tri tra ve la so nguyen======// int readADC() { int kq;//Define variable kq as integer GODONE=1;//Start ADC modul //ADON=1; while(GODONE);//Loop run when bit GODONE=0_see datasheet kq=((ADRESH<<8)|ADRESL); return kq; } //========Goi ham xuat ky tu ra LCD=============================// void putch(char c) { lcd_putc(c); } //================================================== ============// //===================MAIN PROGRAM===============================// void main() { OSCCON = 0x70; lcd_init(); init_port(); init_ngat(); init_timer1(); init_adc(); init_pwm(); while (1) { ADON=1;//Bat ADC va bat dau chuyen doi adc = readADC(); printf("\nADC:%d",adc); __delay_ms(100); if(adc>0 && adc<1020){ CCP1CON = 0x0C;//PWM hoat dong o che do logic tich cuc muc cao CCPR1L = adc/10;//Duty cycle thay doi theo gia tri ADC ADON=0;//Tat ADC de thuc hien tiep lan chuyen doi moi } else { CCPR1L=0x00; CCP1CON = 0x00; } ADON=0; for(int i=0;i<10;i++) { INTE = 1; TMR1ON = 1;//Start timer1 //Khi co tran timer1 bao, thi lenh while se duoc thuc hien while(!TMR1IF);//cho timer dem du 100ms //Ham while ben tren la vong lap thuc hien khi true<=>TMR1IF=1 //do ham rong nen khi gap dieu kien tren ham while thuc hien xong //thi chuyen xuong cau lenh ke tiep. TMR1IF = 0; //Xung clock cho timer1 la Fosc/8=(Crytal/4)/8=250KHz nhung thanh //ghi bo nho den 16bit=FFFF=65535, de co 100s lam chuan tinh RPM //thi can phai dat gia tri ban dau sao cho thanh ghi 16bit sao cho //khi tran la vua du 100ms. //Ma 1s=250K -> 0.1s=25K; lay 65535-25K = 40535 = 9E57. //Nen set gia tri ban dau cho thanh ghi 16bit TMR1H = 0x9E; //100 ms nap lai TMR1L = 0x57; } TMR1ON =0;//Turn off time1 INTE = 0; //Turn off INT RB0 //So xung dem duoc chia cho so lo encoder 200 lo, duoc so vong //trong 100ms nhan tiep 10 duoc so vong/1s, //nhan tiep voi 60s<=>RPM(vong/phut) printf("\fRPM:%0.1f",xung*0.3); xung = 0; //Clear variable xung } } |
![]() |
![]() |
|
|