Cantafford
Member
Hey,
Basically what the title says. I'm generating some PWM signals from a pic microcontroller and feeding them to a DC motor. I'm using the ADC module to convert a continous voltage value to a digital one. Then I'm going to take this value and place it in the PIC's duty cycle register so I can vary the speed of the motor via the pot.
I wrote this code: I initialised the 2 LSB's of the duty cycle register with 0. The result of the ADC is left justified. My PWM will therefore have a resolution of 8 bits(the high byte of the ADC).
This is the schematic in proteus:
When I run the code my motor goes full speed no matter what the position of the pot is. It's the first time I try to do this in assembly. I'm not sure if I moved the value from the ADC conversion to the CCPR1L(duty cycle register).
Also in ISIS I get the following warning:
"ADC conversion clock period violates the required TAD time"
Does this mean I have to insert a delay somewhere in the code? Or increase the number of TADs?
Basically what the title says. I'm generating some PWM signals from a pic microcontroller and feeding them to a DC motor. I'm using the ADC module to convert a continous voltage value to a digital one. Then I'm going to take this value and place it in the PIC's duty cycle register so I can vary the speed of the motor via the pot.
I wrote this code: I initialised the 2 LSB's of the duty cycle register with 0. The result of the ADC is left justified. My PWM will therefore have a resolution of 8 bits(the high byte of the ADC).
Code:
; PIC18F2550 Configuration Bit Settings
; ASM source line config statements
#include "p18F2550.inc"
; CONFIG1L
CONFIG PLLDIV = 1 ; PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
CONFIG CPUDIV = OSC1_PLL2 ; System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
CONFIG USBDIV = 1 ; USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
; CONFIG1H
CONFIG FOSC = INTOSCIO_EC ; Oscillator Selection bits (Internal oscillator, port function on RA6, EC used by USB (INTIO))
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
CONFIG IESO = OFF ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
; CONFIG2L
CONFIG PWRT = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG BOR = OFF ; Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
CONFIG BORV = 3 ; Brown-out Reset Voltage bits (Minimum setting 2.05V)
CONFIG VREGEN = OFF ; USB Voltage Regulator Enable bit (USB voltage regulator disabled)
; CONFIG2H
CONFIG WDT = OFF ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
CONFIG WDTPS = 32768 ; Watchdog Timer Postscale Select bits (1:32768)
; CONFIG3H
CONFIG CCP2MX = ON ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
CONFIG LPT1OSC = OFF ; Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
CONFIG MCLRE = OFF ; MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)
; CONFIG4L
CONFIG STVREN = ON ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
CONFIG LVP = ON ; Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
CONFIG XINST = OFF ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
; CONFIG5L
CONFIG CP0 = OFF ; Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
CONFIG CP1 = OFF ; Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
CONFIG CP2 = OFF ; Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
CONFIG CP3 = OFF ; Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
; CONFIG5H
CONFIG CPB = OFF ; Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
CONFIG CPD = OFF ; Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
; CONFIG6L
CONFIG WRT0 = OFF ; Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
CONFIG WRT1 = OFF ; Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
CONFIG WRT2 = OFF ; Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
CONFIG WRT3 = OFF ; Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
; CONFIG6H
CONFIG WRTC = OFF ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
CONFIG WRTB = OFF ; Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
CONFIG WRTD = OFF ; Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
; CONFIG7L
CONFIG EBTR0 = OFF ; Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR1 = OFF ; Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR2 = OFF ; Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR3 = OFF ; Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
ES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
; TODO ADD INTERRUPTS HERE IF USED
MAIN_PROG CODE ; let linker place main program
START
call _PWM_Init
call _ADC_Init
loop ; loop forever
call _ADC_Conversion ;get value from AN0 and put it in PWM register(CCPR1L)
goto loop
_PWM_Init
BANKSEL OSCCON ;internal 8Mhz oscillator
movlw b'01110111'
movwf OSCCON
movlw b'01010010'
movwf PR2
movlw b'00000111'
movwf T2CON
BANKSEL CCP1CON ; PWM mode selected. LSBs of PWM duty cycle = 0
bsf CCP1CON, 3
bsf CCP1CON, 2
bcf CCP1CON, 4
bcf CCP1CON, 5
BANKSEL TRISC
clrf TRISC
bsf LATC, 0 ;direction for the motor
bcf LATC, 1
return
_ADC_Init
bsf TRISA, 0 ;AN0 made as input
BANKSEL ADCON0
movlw b'00000001' ; select chanel 0, turn on ADC
movwf ADCON0
movlw b'00001110' ;ref select, AN0 made analog
movwf ADCON1
movlw b'00001000' ;Fosc/2, result is left justified, 2 TAD
movwf ADCON2
return
_ADC_Conversion
bsf ADCON0, 1 ;start conversion by setting GODONE bit
btfsc ADCON0, 1 ;once the GODONE bit is cleared continue
goto _ADC_Conversion
MOVFF ADRESH, CCPR1L ; take the value from the pot and put it in the PWM register
return
END
This is the schematic in proteus:

When I run the code my motor goes full speed no matter what the position of the pot is. It's the first time I try to do this in assembly. I'm not sure if I moved the value from the ADC conversion to the CCPR1L(duty cycle register).
Code:
MOVFF ADRESH, CCPR1L ; take the value from the pot and put it in the PWM register
Also in ISIS I get the following warning:
"ADC conversion clock period violates the required TAD time"
Does this mean I have to insert a delay somewhere in the code? Or increase the number of TADs?