Trích:
Nguyên văn bởi messitoan
các bác ơi xin giúp em với!
|
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
}
}