int1 mode;
int8 duty_cycle,period;
//-----Ngat Ngoai------
#INT_EXT
void ngatngoai()
{
if (mode== 0) mode = 1;
else mode = 0;
}
//--------Ngat Noi Tiep------
#INT_RDA
void ngatrs232()
{
char c;
c = getc();
putc(c);
if (c=='h') duty_cycle++;
else if (c=='l') duty_cycle--;
if (duty_cycle > 20) duty_cycle=20;
if (duty_cycle < 1 ) duty_cycle=1;
}
void main()
{
// Khoi tao cho ngat ngoai + RS232 nhan byte
enable_interrupts (INT_EXT);
enable_interrupts(INT_RDA);
ext_int_edge(H_TO_L);
enable_interrupts (GLOBAL);
// ----------------------------
TRISD = 0;
duty_cycle = 2;
Printf("Chuong trinh dieu khien dong co buoc: ");
Printf(" Nhap chu ky:");
period = 3;
while (1)
{
//Dieu khien dong co buoc: DK nua buoc (ULN2803)
if (mode)
{
PortD = 0x60;
delay_ms(duty_cycle);
PortD = 0x70;
delay_ms(duty_cycle);
PortD = 0x30;
delay_ms(duty_cycle);
PortD = 0xB0;
delay_ms(duty_cycle);
PortD = 0x90;
delay_ms(duty_cycle);
PortD = 0xD0;
delay_ms(duty_cycle);
PortD = 0xC0;
delay_ms(duty_cycle);
PortD = 0xE0;
delay_ms(duty_cycle);
}
else
{
PortD = 0xE0;
delay_ms(duty_cycle);
PortD = 0xC0;
delay_ms(duty_cycle);
PortD = 0xD0;
delay_ms(duty_cycle);
PortD = 0x90;
delay_ms(duty_cycle);
PortD = 0xB0;
delay_ms(duty_cycle);
PortD = 0x30;
delay_ms(duty_cycle);
PortD = 0x70;
delay_ms(duty_cycle);
PortD = 0x60;
delay_ms(duty_cycle);
}
}
}
/*
// Dieu khien dong co buoc: DK 1 pha
if (mode)
{
PortD = 0x70;
delay_ms(20-duty_cycle);
PortD = 0xB0;
delay_ms(20-duty_cycle);
PortD = 0xD0;
delay_ms(20-duty_cycle);
PortD = 0xE0;
delay_ms(20-duty_cycle);
}
else
{
PortD = 0xE0;
delay_ms(20-duty_cycle);
PortD = 0xD0;
delay_ms(20-duty_cycle);
PortD = 0xB0;
delay_ms(20-duty_cycle);
PortD = 0x70;
delay_ms(20-duty_cycle);
}
//Dieu khien dong co buoc: DK 2 pha (ULN2803)
if (mode)
{
PortD = 0x60;
delay_ms(period-duty_cycle);
PortD = 0x30;
delay_ms(period-duty_cycle);
PortD = 0x90;
delay_ms(period-duty_cycle);
PortD = 0xC0;
delay_ms(period-duty_cycle);
}
else
{
PortD = 0xC0;
delay_ms(period-duty_cycle);
PortD = 0x90;
delay_ms(period-duty_cycle);
PortD = 0x60;
delay_ms(period-duty_cycle);
PortD = 0x30;
delay_ms(period-duty_cycle);
}
//Dieu khien dong co buoc: DK nua buoc (ULN2803)
if (mode)
{
PortD = 0x60;
delay_ms(period-duty_cycle);
PortD = 0x70;
delay_ms(period-duty_cycle);
PortD = 0x30;
delay_ms(period-duty_cycle);
PortD = 0xB0;
delay_ms(period-duty_cycle);
PortD = 0x90;
delay_ms(period-duty_cycle);
PortD = 0xD0;
delay_ms(period-duty_cycle);
PortD = 0xC0;
delay_ms(period-duty_cycle);
PortD = 0xE0;
delay_ms(period-duty_cycle);
}
else
{
PortD = 0xE0;
delay_ms(period-duty_cycle);
PortD = 0xC0;
delay_ms(period-duty_cycle);
PortD = 0xD0;
delay_ms(period-duty_cycle);
PortD = 0x90;
delay_ms(period-duty_cycle);
PortD = 0xB0;
delay_ms(period-duty_cycle);
PortD = 0x30;
delay_ms(period-duty_cycle);
PortD = 0x70;
delay_ms(period-duty_cycle);
PortD = 0x60;
delay_ms(period-duty_cycle);
}
*/
9.2.3. Chương trình điều khiển động cơ bước .
Bàn phím có 5 phím:quay thuận,quay ngược,quay thuận bước nhỏ,quay ngược bước nhỏ,stop. Trình dịch CCS.Mong các bạn cho ý kiến để cải tiến
#include "C:\Comport\ccs\DKMOTOR.h"
#define stop PIN_C0
#define dkth PIN_C1
#define dkng PIN_C2
#define hpb1 PIN_C3
#define hpb2 PIN_C4
#BYTE trisb =0x86
#BYTE OSCCON=0x8F
#BYTE trisc = 0x87
char a,b ;
char PeekKey() ;
char GetKey();
void buoc1();
void buoc2();
void stp();
void dkthuan();
void dknghich();
void main()
{ //su dung loai 2cuon co chan giua noi B+
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
trisc=7F;
b=2;
while(1)
{
a=PeekKey();
switch(a)
{
case 0 : stp();
break;
case 1 : dkthuan();
break;
case 2 : dknghich();
break;
case 3 : buoc1();
break;
case 4 : buoc2();
break;
case 5 : stp();
break;
}
}
}
//***************
char PeekKey(void)
{ if(input(stop)==0) return(0);
if(input(dkth)==0) return(1);
if(input(dkng)==0) return(2);
if(input(hpb1)==0) return(3);
if(input(hpb2)==0) return(4);
else return (a); }
// **********
char GetKey(void)
{ char nKey;
nKey=PeekKey();
// wait for key release
while ((input(stop)==0)||(input(dkth)==0) )
(input(dkng)==0 )||(input(hpb1)==0 )||(input(hpb2)==0) ;
delay_ms(10);
return(nKey); }
// *************
void dkthuan()
{ output_b(8);
delay_ms(b);
output_b(2);
delay_ms(b);
output_b(1);
delay_ms(b);
output_b(4);
delay_ms(b);
output_b(0);
}
//*******
void dknghich()
{ output_b(4);
delay_ms(b);
output_b(1);
delay_ms(b);
output_b(8);
delay_ms(b);
output_b(2);
delay_ms(b);
output_b(0);
}
// *********
void stp()
{ output_b(0);
delay_ms(2);
}
//*******
void buoc1()
{ char i;
for (i=1;i<=15;++i)
dkthuan();
a=0;
}
//**********
void buoc2()
{ char i;
for (i=1;i<=15;++i)
dknghich();
a=0;
}
// Thanhphuc email thuyphuc81@yahoo.com
// Dieu khien moto buoc loai 2 cuon day co chan giua
9.2.4. Điều khiển động cơ bước
//================================================= =======
// Ten chuong trinh : Thuc hien vao ra
// Nguoi thuc hien : linhnc308
// Ngay thuc hien : 1/09/2006
// Phien ban : 1.0
// Mo ta phan cung : Dung PIC16F877A - thach anh 20MHz
//================================================= =======
#include <16f877a.h>
#include
#device *=16 ADC=10
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#CASE
// Dinh nghia ten cac cong ra
#define Relay1 RD0
#define Relay2 RD1
#define Relay3 RD2
#define Relay4 RD3
#define Relay5 RD4
#define Relay6 RD5
#define Relay7 RD6
#define Relay8 RD7
#define Relay9 RC4
#define Relay10 RC5
#define Relay11 RC6
#define Relay12 RC7
#define IN1 RA0
#define IN2 RA1
#define IN3 RA2
#define IN4 RA3
#define AllRelay1 PORTD // PIN D0 : D7
#define AllRelay2 PORTC // PIN C4 : C7
#define Step PORTD
#Define AllInput PORTA
#define OFF 0
#define ON 1
#define OutEnable1 TRISD // Relay Output
#define OutEnable2 TRISC // Relay Output
#define InEnable TRISA // Input
#define StepEnable TRISD // Step Motor
#define PWM_Enable TRISC2 // PWM, PIN_C2
void main()
{
int8 duty_cycle;
delay_ms(250);
// Khoi tao che do vao ra
OutEnable1 = 0x00;
OutEnable2 = 0x00;
InEnable = 0xFF;
StepEnable = 0x00;
PWM_Enable = 1; // Khong cho phep xuat PWM
//=====================================
// Test Mode
duty_cycle = 1;
while (1)
{
//Dieu khien dong co buoc: DK nua buoc (ULN2803)
if (IN1 == 0)
{
Step = 0x1;
delay_ms(duty_cycle);
Step = 0x3;
delay_ms(duty_cycle);
Step = 0x2;
delay_ms(duty_cycle);
Step = 0x6;
delay_ms(duty_cycle);
Step = 0x4;
delay_ms(duty_cycle);
Step = 0xc;
delay_ms(duty_cycle);
Step = 0x8;
delay_ms(duty_cycle);
Step = 0x9;
delay_ms(duty_cycle);
}
else if (IN2 == 0)
{
Step = 0x9;
delay_ms(duty_cycle);
Step = 0x8;
delay_ms(duty_cycle);
Step = 0xc;
delay_ms(duty_cycle);
Step = 0x4;
delay_ms(duty_cycle);
Step = 0x6;
delay_ms(duty_cycle);
Step = 0x2;
delay_ms(duty_cycle);
Step = 0x3;
delay_ms(duty_cycle);
Step = 0x1;
delay_ms(duty_cycle);
}
else Step = 0x00;
}
}
/*
// Dieu khien dong co buoc: DK 1 pha
if (mode)
{
Step = 0x70;
delay_ms(20-duty_cycle);
Step = 0xB0;
delay_ms(20-duty_cycle);
Step = 0xD0;
delay_ms(20-duty_cycle);
Step = 0xE0;
delay_ms(20-duty_cycle);
}
else
{
Step = 0xE0;
delay_ms(20-duty_cycle);
Step = 0xD0;
delay_ms(20-duty_cycle);
Step = 0xB0;
delay_ms(20-duty_cycle);
Step = 0x70;
delay_ms(20-duty_cycle);
}
//Dieu khien dong co buoc: DK 2 pha (ULN2803)
if (mode)
{
Step = 0x60;
delay_ms(period-duty_cycle);
Step = 0x30;
delay_ms(period-duty_cycle);
Step = 0x90;
delay_ms(period-duty_cycle);
Step = 0xC0;
delay_ms(period-duty_cycle);
}
else
{
Step = 0xC0;
delay_ms(period-duty_cycle);
Step = 0x90;
delay_ms(period-duty_cycle);
Step = 0x60;
delay_ms(period-duty_cycle);
Step = 0x30;
delay_ms(period-duty_cycle);
}
//Dieu khien dong co buoc: DK nua buoc (ULN2803)
if (mode)
{
Step = 0x60;
delay_ms(period-duty_cycle);
Step = 0x70;
delay_ms(period-duty_cycle);
Step = 0x30;
delay_ms(period-duty_cycle);
Step = 0xB0;
delay_ms(period-duty_cycle);
Step = 0x90;
delay_ms(period-duty_cycle);
Step = 0xD0;
delay_ms(period-duty_cycle);
Step = 0xC0;
delay_ms(period-duty_cycle);
Step = 0xE0;
delay_ms(period-duty_cycle);
}
else
{
Step = 0xE0;
delay_ms(period-duty_cycle);
Step = 0xC0;
delay_ms(period-duty_cycle);
Step = 0xD0;
delay_ms(period-duty_cycle);
Step = 0x90;
delay_ms(period-duty_cycle);
Step = 0xB0;
delay_ms(period-duty_cycle);
Step = 0x30;
delay_ms(period-duty_cycle);
Step = 0x70;
delay_ms(period-duty_cycle);
Step = 0x60;
delay_ms(period-duty_cycle);
}
*/
10. Capture
10.1. Code cho CCS
/////////////////////////////////////////////////////////////////////////
//// EX_CCPMP.C ////
//// ////
//// This program will show how to use the built in CCP to ////
//// measure a pulse width. ////
//// ////
//// Configure the CCS prototype card as follows: ////
//// Connect a pulse generator to pin 3 (C2) and pin 2 (C1) ////
//// See additional connections below. ////
//// ////
//// This example will work with the PCM and PCH compilers. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for each compiler. Change the device, clock and ////
//// RS232 pins for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#if defined(__PCM__)
#include <16F88.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#endif
long rise,fall,pulse_width;
#int_ccp2
void isr()
{
rise = CCP_1;
fall = CCP_2;
pulse_width = fall - rise; // CCP_1 is the time the pulse went high
} // CCP_2 is the time the pulse went low
// pulse_width/(clock/4) is the time
// In order for this to work the ISR
// overhead must be less than the
// low time. For this program the
// overhead is 45 instructions. The
// low time must then be at least
// 9 us.
void main()
{
printf("\n\rHigh time (sampled every second):\n\r");
setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_FE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL); // Start timer 1
enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);
while(TRUE) {
delay_ms(1000);
printf("\r%lu us ", pulse_width/5 );
}
}
10.2. Sử dụng capture newcode
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT, NOPROTECT
#use rs232(baud=4800,xmit=PIN_C6,rcv=PIN_C7)
#bit TMR1IF 0x0C.0
int16 CCP1Value;
int16 CCP1OldValue;
BOOLEAN CCP1Captured;
#int_CCP1
CCP1_isr()
{
if(TMR1IF)
{
CCP1Value = CCP_1 +(65535-CCP1OldValue);
CCP1OldValue = CCP_1;
TMR1IF=0;
}
else
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
}
CCP1Captured = TRUE;
}
//--------------------------------------------------------------------------
void Init_ccp(void)
{
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
CCP1Value = 0;
CCP1OldValue = 0;
CCP1Captured = TRUE;
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
void main()
{
float Freq;
Init_ccp();
printf("Frequence test:\r\n");
while (TRUE) {
if (CCP1Captured) {
// F = 1/T
// Timer1 prescaler DIV_BY_8
// Pic16F877A 4MHz -> 0.000001 * 8 = 1uS * 8
// PIC16f877a 20MHz -> 200nS * 8
Freq = 1.0/((float)CCP1Value*8e-6);
printf("Freq:%f\r\n",Freq);
CCP1Captured = FALSE;
}
}
}
10.3. Capture_LCD_5MHz
#include <16F877A.h>
#include
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
#bit TMR1IF = 0x0C.0
#include
int16 CCP1Value; // Gia tri CCP hien tai
int16 CCP1OldValue; // Gia tri CCP truoc do
BOOLEAN CCP1Captured;
float Freq;
int8 char1,char2,char3,char4,char5,char6,mode;
int8 count,count1,count2,count3;
#int_CCP1
CCP1_isr()
{
if(TMR1IF)
{
CCP1Value = CCP_1 +(65535-CCP1OldValue);
CCP1OldValue = CCP_1;
TMR1IF=0;
}
else
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
}
CCP1Captured = TRUE;
}
//--------------------------------------------------------------------------
#INT_TIMER0
Timer0_isr()
{
}
//----------------------------------------
void Init_ccp(void)
{
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_64);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer0(0);
CCP1Value = 0;
CCP1OldValue = 0;
CCP1Captured = TRUE;
enable_interrupts(INT_CCP1);
//enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
void Convert_CCP1()
{
int32 temp;
//Freq = (1.0/((float)CCP1Value*2e-7)); // For Time_Div_1
Freq = (1.0/((float)CCP1Value*16e-7)); //For_Time_Div_8
if (Freq >= 1000 )
{
mode = 1;
temp = freq;
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
else
if (Freq >= 1000000 )
{
mode = 2;
temp = freq;
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
else
{
mode = 0;
temp = (int32)(freq * 1000);
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
exit:
temp = 0;
}
//--------------------------------------------
void convert_timer0_value()
{
count = get_timer0();
count1 = count/100 + 0x30;
count = count%100;
count2 = count/10 + 0x30;
count3 = count%10 + 0x30;
}
//---------------------------------------------------------------
void main()
{
TRISB = 0; // F = 1/T
Init_ccp(); // Timer1 prescaler DIV_BY_1
LCD_init(); // PIC16f877a 20MHz -> 0.0000002 = 200nS
//printf("Frequence test:\r\n"); // Pic16F877A 4MHz -> 0.000001 = 1uS
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Counter = ");
LCD_putcmd(0x80);
Printf(LCD_putchar,"Freq = ");
while (TRUE)
{
if (CCP1Captured)
{
Convert_CCP1();
LCD_putcmd(0x87);
if (char1 != 0x30) LCD_putchar(char1);
if (((char1 != 0x30) && (char2 == 0x30)) || (char2 != 0))
LCD_putchar(char2);
LCD_putchar(char3);
LCD_putchar(".");
LCD_putchar(char4);
LCD_putchar(char5);
switch (mode)
{
case 0: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_putchar," Hz");} break;
case 1: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_putchar,"KHz");} break;
case 2: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_putchar,"MHz");} break;
}
printf("Freq:%f\r\n",Freq);
CCP1Captured = FALSE;
}
convert_timer0_value();
LCD_putcmd(0xCa);
LCD_putchar(count1);
LCD_putchar(count2);
LCD_putchar(count3);
}
}
Chia sẻ với bạn bè của bạn: