Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About Keenan

  • Rank
  1. Hello, I am using a PIC16F684 to control two servomotors and a variable dc motor. I am having trouble outputting the AD values from my accelerometer and interfacing the servomotors. Some of the problems that I have encountered are as follows: I will be using two servomotors but there is only one PWM modulated output from the PR1 register. The two servomotors will need to operate separately based on the accelerometer readings. The variable dc motor will control the speed of the airplane. This means that a square wave signal with a varying frquency will need to be output to increase and decrease motor functionality. Can anyone suggest how to output my AD values from the accelerometer, how to implement two separate PWM signals on the output ports to control the servomotors, and how to implement a a square wave with a varying frequency? Thx.
  2. I was able to get the problem fixed. It was a compiler issue with the software I was using. The other problem that I have run into is that I am trying to operate 2 servomotors and a variable dc motor with a PWM code. I was able to get the PWM registers working for a 20ms PWM. However, this PIC will only allow me to control one motor. I know that I can vary the PWM for three different motors easily. But how can I output that PWM signal to control three different motors using interrupts that incorporate getting data from a 3-axis accelerometer. Here's some code that I used to get the PWM output signal. Essentially, I will be varying the duty cycle based on accelerometer output readings to the adc. This code here uses the Potentiometer to simulate the accelerometer outputs to the adc. I plan to inplement the accelerometer this week as well. #include <system.h> #include <adc.h>// //#include <PIC16F684.h>// #pragma CLOCK_FREQ 125000 char a; short roll, pitch, yaw; void main() { //Initialize Porta/c trisc = 0; //configure port C as output portc = 0; //clear port C trisa = 0; //configure port a as output porta = 0; //clear port a a = 9; // Initialize ADC set_bit( adcon1, ADCS1 ); // Select Tad = 32 * Tosc (this depends on the Xtal here 10 MHz, should work up to 20 MHz) adcon0 = 0x80; // selects ad channel 0; // Vdd on Vcfg; AD result needs to be right justified volatile bit adc_on @ ADCON0 . ADON; //AC activate flag adc_on = 1; // Activate AD module // Initialize PWM mode set_bit( status, 5); osccon = 0x15; // select 125kHz Fosc and High Frequency Internal OSC is stable clear_bit( status, 5); // select bank 0; RPO bit set_bit(ccp1con, 3); // configure PWM mode; ccp1m3 bit set_bit(ccp1con, 2); // ccp1m2 bit set_bit(t2con, 2); // timer 2 enabled; timr2on set_bit(t2con, 1); //set timer2 prescaler to 16; t2ckps1 bit ccpr1l = 2; // questionable needs to set duty cycle to 7.5% set_bit(status, 5); // select bank 1 pr2 = 38; // sets frequency to 50Hz while (adc_on = 1) { portc = adc_measure( 0 )>> 5; // Outputs to portc 6 bits // THis needs to be assigned to a variable. delay_ms( 250 ); ansel = 0x0F; // analog select channels 0-3; trisa = 0x0F; // makes analog channels 0-3 inputs } I was also thinking about using this generated code that outputs a 20ms PWM with the use of interrupts and the accelerometer outputs to the adc. while(1) { portc = 255; //porta = 170; delay_100us(a); portc = 0; //porta = 85; delay_100us(200 - a); a+=1; if(a > 20) a = 9; }
  3. Hello, I was having trouble getting some code to produce in the proper start vector for a PIC16F684 using sourceBoost C compiler. Could anyone offer a hand with solving this problem. I have an asm program that works fine. But my program starts at address 0x03 rather than 0x04. This is keeping some of my code from working. But the asm code from someone else works. Could you please take a look at this for me and give me a hand with setting up the proper program start vector in C. The only code that I have available on this laptop is asm in text docs. Here is the code not working in C and asm: Org 0x03 is the problem that I'm having is generated by the c compiler #include <system.h> #include <adc.h> // #include <P16F684.INC> #pragma CLOCK_FREQ 4000000 #define Servopin porta,5 void main() { //Variables defined // unsigned char dc ; char Sstate@0x20; char Scount@0x22; short Dlay@0x24; char temp@0x26; char temp2@0x28; temp = 0; temp2 = 0; Sstate = 0; Scount = 0; trisa = 0; // configures porta as output clear_bit(status, 5); porta = 0; cmcon0 = 0x07 ; set_bit(status, 5); ansel = 0; trisa = 0x0C; clear_bit(status, 5); while( 1) { set_bit(porta, 5); clear_bit(porta, 5); Dlay = 4256; while(Dlay != 0) { Dlay = Dlay -1; } } ORG 0x00000000 0000 282A GOTO _startup ORG 0x00000003 0003 main 0003 ; { main ; function begin 0003 1283 BCF STATUS, RP0 0004 01A6 CLRF main_1_temp 0005 01A8 CLRF main_1_temp2 0006 01A0 CLRF main_1_Sstate 0007 01A2 CLRF main_1_Scount 0008 1683 BSF STATUS, RP0 0009 0185 CLRF gbl_trisa 000A 1283 BCF STATUS, RP0 000B 1283 BCF gbl_status,5 000C 0185 CLRF gbl_porta 000D 3007 MOVLW 0x07 000E 0099 MOVWF gbl_cmcon0 000F 1683 BSF gbl_status,5 0010 1683 BSF STATUS, RP0 0011 0191 CLRF gbl_ansel 0012 300C MOVLW 0x0C 0013 0085 MOVWF gbl_trisa 0014 1283 BCF STATUS, RP0 0015 1283 BCF gbl_status,5 0016 label1 0016 1685 BSF gbl_porta,5 0017 1285 BCF gbl_porta,5 0018 30A0 MOVLW 0xA0 0019 00A4 MOVWF main_1_Dlay 001A 3010 MOVLW 0x10 001B 00A5 MOVWF main_1_Dlay+D'1' 001C label2 001C 08A4 MOVF main_1_Dlay, F 001D 1D03 BTFSS STATUS,Z 001E 2822 GOTO label3 001F 08A5 MOVF main_1_Dlay+D'1', F 0020 1903 BTFSC STATUS,Z 0021 2816 GOTO label1 0022 label3 0022 3001 MOVLW 0x01 0023 0224 SUBWF main_1_Dlay, W 0024 00A1 MOVWF CompTempVar119 0025 1C03 BTFSS STATUS,C 0026 03A5 DECF main_1_Dlay+D'1', F 0027 0821 MOVF CompTempVar119, W 0028 00A4 MOVWF main_1_Dlay 0029 281C GOTO label2 002A ; } main function end ORG 0x0000002A 002A _startup 002A 118A BCF PCLATH,3 002B 120A BCF PCLATH,4 002C 2803 GOTO main Here's the working code that was written: list p=16F684 ; list directive to define processor #include <P16F684.INC> ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT #define BANK1 banksel 0x80 ; Select Bank1 #define BANK0 banksel 0x00 ; Select Bank0 #DEFINE ANBITS B'00000011' ; MAKE CHANNEL 0 AND 1 ANALOG INPUTS #define ANSEL0 b'00000011' ; A/D enable channel 0 #define ANSEL1 b'00000111' ; A/D enable channel 1 #define ADControl b'00000001' ; A/D on, left justified result #DEFINE D01OUT B'11001111' ; DDR FOR LED 0 AND 1 ON #DEFINE D0ON B'00010000' ; OUTPUT PATTERN FOR LED 0 ON #DEFINE D1ON B'00100000' ; OUTPUT PATTERN FOR LED 1 ON cblock 0x20 Delay ; Assign an address to label Delay1 Display ; define a variable to hold the diplay LastStableState ; keep track of switch state (open-1; closed-0) COUNTER temp TEMP LEFTSENH RIGHTSENH POSITION DIRECTION endc ORG 0x000 ; processor reset vector nop ; Inserted For ICD2 Use goto Init ; go to beginning of program ORG 0x04 goto interrupt interrupt retfie Delay1mS movlw .71 ; delay ~1000uS was .71 the . makes it unsigned decimal movwf Delay decfsz Delay,f ; this loop does 215 cycles goto $-1 decfsz Delay,f ; This loop does 786 cycles goto $-1 return Filer movlw #temp movwf FSR incf FSR,1 movwf INDF return CLOCKTABLE movf POSITION,W ; this is a load w from mem????? andlw 0x07 ; mask off invalid entries movwf temp ; saves current value of w in loc. temp...DG movlw high TableStart ; get high order part of the beginning of the table movwf PCLATH movlw low TableStart ; load starting address of table addwf temp,w ; add offset btfsc STATUS,C ; check for page overflow? incf PCLATH,f ; yes: increment PCLATH movwf PCL ; modify PCL, auto write pch from pclath TableStart ; PWM1 DIR1 PWM2 DIR2 ; 5 4 2 1 retlw 0x20 ; 0 North retlw 0x24 ; 1 North-East retlw 0x04 ; 2 East retlw 0x34 ; 3 South-East retlw 0x30 ; 4 South retlw 0x36 ; 5 South-West retlw 0x06 ; 6 West retlw 0x26 ; 7 North-West retlw 0x55 ; lost if here GETAD BANK0 ;BANK0 movwf ADCON0 ;Start A/D AND SELECT WHICH CHANNEL NOP NOP NOP waitad btfsc ADCON0,1 ;check for done goto waitad movf ADRESH,W ;Move the most significant byte of A/D Result to W return Init ;call 0x3FF ; retrieve factory calibration value ; comment instruction if using simulator, ICD2, or ICE2000 BANK1 ; movwf OSCCAL ; update register with factory cal value movlw 0x0 movwf TRISC ;set all 4 LOW NIBBLE outputs PORT C BANK0 ;BANK 0 clrf PORTC ;Clear Port BANK1 ;BANK 1 clrf VRCON ;Vref Off BANK0 ;BANK 0 clrf TMR0 movlw 0x07 ; movwf CMCON ;Comparator Off BANK1 ;BANK 1 movlw b'10000001' movwf OPTION_REG ;TIMER0 Prescaler = 4 and pull-ups disabled bsf INTCON,T0IE ;Interrupt on TIMER0 Overflow Enabled bcf INTCON,T0IF ;Clear TIMER0 Overflow Interrupt Flag ; bsf INTCON,GIE ;Turn on Global Interrupts movlw ANBITS movwf ANSEL ;Configure AN0,1 & prescale to A/D BANK0 ;BANK 0 movlw ADControl ; movwf ADCON0 ;Select AN0, Left justified & enables A/D ;**************************************************************************** ;MAIN - Main Routine ;**************************************************************************** MAIN MOVLW ANSEL0 call GETAD movwf LEFTSENH movlw ANSEL1 CALL GETAD MOVWF RIGHTSENH MOVLW #20 MOVWF COUNTER maindl call Delay1mS DECFSZ COUNTER,1 GOTO maindl call Delay1mS BANK0 CALL DECIDE CALL CLOCKTABLE CALL OUTMOT GOTO MAIN DECIDE MOVF LEFTSENH,W SUBWF RIGHTSENH,W BTFSS STATUS,C ; CHECK FOR A CARRY 0 IMPLIES W>F GOTO LGR MOVF RIGHTSENH,W SUBWF LEFTSENH,W SUBLW 0X20 BTFSC STATUS,C ; CHECK FOR CARRY GOTO DONDECISION INCF POSITION,F GOTO DONDECISION LGR SUBLW 0X20 BTFSC STATUS,C GOTO DONDECISION DECF POSITION,F DONDECISION RETURN OUTMOT ; A HORRIBLE ROUTINE TO OUTPUT BITS NON-OVERLAPPING(LY) BANK0 MOVWF TEMP BTFSC TEMP,5 ; PWM1 GOTO SBIT5 BCF PORTC,5 GOTO TBIT4 SBIT5 BSF PORTC,5 TBIT4 BTFSC TEMP,4 ; DIR1 GOTO SBIT4 BCF PORTC,4 GOTO TBIT2 SBIT4 BSF PORTC,4 TBIT2 BTFSC TEMP,2 GOTO SBIT2 BCF PORTC,2 GOTO TBIT1 SBIT2 BSF PORTC,2 TBIT1 BTFSC TEMP,1 GOTO SBIT1 BCF PORTC,1 GOTO DONOUT SBIT1 BSF PORTC,1 DONOUT RETURN END
  • Create New...