![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
My project is to build an infrared RC system for indoor airplanes. Many have done it before that I could copy, but I want to learn to program. What I'm did first was learn to create PWM in software using a simple circuit. Then I put a potentiometer into the circuit to adjust the speed of the motor/force of a coil "BIRD" actuator. Later I will learn how to send the information over IR. The issue that I have is that the motor is not changing speeds when I adjust the potentiometer. I suspect that I am using the addlw improperly. The idea is to subtract the value read from the capacitor discharge time from 255 and get the bit high and bit low times of my bit-bang style PWM. I have included a drawing of the circuit and my code.
Code:
;PWM project list P=12f629 #include <p12f629.inc> __config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF ERRORLEVEL -302 cblock 20h AV,BH,BL,DELAY endc ORG 0000h ;start here on powerup goto START ;skip interrupt location ORG 0004h ;interrupt location goto AVinterrupt ;duh bcf INTCON,2 ;reset interrupt flag to 0 RETFIE START movlw 0x07 ;turn off comparitors movwf CMCON bsf INTCON,7 ;global interrupt enabled bsf INTCON,5 ;set timer interrupt bsf STATUS,RP0 ;switch to bank 1 movlw 0x02 ;set prescaler movwf OPTION_REG ;put in option register movlw 0x00 ;set pins I/O movwf TRISIO ;put value in tris bcf STATUS,RP0 ;switch back to bank 0 PWM addlw 0xFF-AV ;determine time to keep bit high movwf BH movlw 0x07 ;set output bit high movwf GPIO loop1 decfsz BH,f ;keep output bit high goto loop1 movlw 0x04 ;set output bit low movwf GPIO loop2 decfsz AV,f ;keep output bit low for the rest of the 256 goto loop2 goto PWM AVinterrupt bsf STATUS,RP0 ;set pin to input movlw 0x04 movwf TRISIO bcf STATUS,RP0 clrf AV ;clear AVloop incf AV,1 ;add one for every time the following test results in pin still high btfsc GPIO,2 ;test if pin still high goto AVloop bsf STATUS,RP0 ;set all to output movlw 0x00 movwf TRISIO bcf STATUS,RP0 return end
__________________
jeremy |
|
|
|
|
|
|
(permalink) |
|
Not sure if you need it but your code does not save the W & STATUS on interrupt.
Also you must wait a small amout of time for the A/D to setup before you use it. |
|
|
|
|
|
|
(permalink) |
|
What I have done to keep from waiting for the cap to charge in the interrupt code is I leave the bit high all the time so the cap should be charged all the time until I want to read it in my interrupt. Maybe I should make my prescaler bigger to wait longer?
I think I should save the W value. Does this sounds right....I should save it because if the interrupt cuts in right when I'm in the middle of a high or low of the PWM it will finish the cycle with the value 255 instead of what I had there.
__________________
jeremy |
|
|
|
|
|
|
(permalink) |
|
Yes save both the W and STATUS registers.
Here's some food for thought. When you need A/D or PWM choose a PIC that has them in hardware rather than doing it in software, it's so much easier. The 12F683 has both. Check the Toy Car project on my site to see A/D & PWM code for a 16F88. |
|
|
|
|
|
|
(permalink) |
|
I think it would be easier with hardware, but I want to implement up to 4 channels later on. With small SMD PICs I think I need to have the PWM in software to get that many channels. Also I'm simply interested in how to make it happen using a program.
So, what I have found is if I hold the pin where the pot is high or low it makes no difference in my motor speed. It should at least be all off or all on with that change. For some reason my value is not making it to the PWM cycle.
__________________
jeremy Last edited by jeremygaughan; 23rd November 2007 at 08:42 PM. |
|
|
|
|
|
|
(permalink) |
|
Well at least get an A/D port PIC like the 12F675.
|
|
|
|
|
|
|
(permalink) |
|
I agree, I'm more interested in learning to write the PWM and the IR code. The AtoD will be a lot more accurate done in the hardware. When I have the revised code for the 12f675 written I'll post it. Also what command saves the w and status registers?
__________________
jeremy |
|
|
|
|
|
|
(permalink) |
|
You need to assign them to two variables, here's some sample code from Peter Andersons site.
http://www.phanderson.com/PIC/16C84/...terrupt_1.html Code:
INT_SERV:
MOVWF W_SAVE ; save W
SWAPF STATUS, W ; save STATUS
MOVWF STATUS_SAVE
BCF STATUS, RP0 ; be sure we are in bank 0
; your stuff goes here
; and finishes here.
BCF INTCON, INTF ; indicate that interrupt has been serviced
SWAPF STATUS_SAVE, W
MOVWF STATUS ; restore W and STATUS
SWAPF W_SAVE, F
SWAPF W_SAVE, W
RETFIE
|
|
|
|
|
|
|
(permalink) |
|
I decided I've started a little too big. So I broke my code into two parts; PWM and AtoD. I'm ready to code now but now my PICKIT 2 is acting crazy. It recognizes the chip and then can read it....then when I try to program suddenly it says no device detected. If I unplug it and replug it again it will recognize the pic but when I try to do anything to it it says again no device detected. Anyway, here is the code for the PWM bit-bang. The idea is to change the brightness of a LED when I bring a pin high. I'm using a LED instead of a motor to make the circuit simpler and easier to problem solve.
Code:
#include <p12f629.inc> __config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF ERRORLEVEL -302 cblock 20h BH,DELAY endc bsf STATUS,RP0 ;bank 1 movlw 0x30 movwf TRISIO ;make bit 4 and 5 inputs bcf STATUS,RP0 start movlw 0x00 ;set BH to zero movwf BH call bithigh ;call to check if pin is high call bitlow ;call to check if pin is high movlw 0x01 ;turn led on movwf GPIO loop decfsz BH,1 ;count down time to keep led on goto loop movlw 0x00 ;turn led off movlw GPIO movlw 0x00 ;check again if pins are high movwf BH call bithigh call bitlow loop2 incfsz BH,1 ;count up to keep led off goto loop2 goto start bithigh btfss GPIO,4 ;test pin to see if high return movlw 0x88 ;if high make BH about half of 256 movwf BH return bitlow btfss GPIO,5 ;test if pin high return movlw 0xff ;if high make BH 256 movwf BH return end
__________________
jeremy |
|
|
|
|
|
|
(permalink) |
|
When using 12f629 and setting the program pin to out put there are problems entering program mode. In the menu bar >tools >VPP first program entry works most of the time. So pickit 2 problem mostly solved, now my program..... This is what happens with my PWM test program. It lights the led about half way when powered up. If I bring pin 6 or 7 high the led turns off instead of changing brightness. Any ideas about what I can change in my program?
__________________
jeremy |
|
|
|
|
|
|
(permalink) | |
|
Quote:
Mike. |
||
|
|
|
|
|
(permalink) |
|
I'll use bits next time to describe the process. So after a little homework I got my PWM to work, and even threw in a few inputs. The first thing I learned is that an input that is driven low to activate needs to be held high with a resistor in the mean time. Here is the circuit and the working code for any newbies like me that want to see.
Code:
;PWM simple list P=12f629 #include <p12f629.inc> __config _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _CP_OFF ERRORLEVEL -302 cblock 20h BH,BL,DELAY endc bsf STATUS,RP0 ;bank 1 movlw 0x30 movwf TRISIO ;make bit 4 and 5 inputs bcf STATUS,RP0 movlw 0x07 ;turn off comparitors movwf CMCON Start movlw 0x00 ;turn leds off movwf GPIO test btfss GPIO,4 ;test for bit 4 low call dim ;if low goto dim pwm test2 btfss GPIO,5 ;test if bit 5 low call bright ;if low goto btight pwm goto Start dim movlw 0x04 ;set on time of duty cycle movwf BH loop decfsz BH,1 ;count down the on time goto loop movlw 0x00 ;turn leds off movwf GPIO movlw 0x04 ;set off time of duty cycle movwf BH loop2 incfsz BH,1 ;count up to the off time goto loop2 movlw 0x07 ;turn leds on movwf GPIO goto test ;repeat until bit high bright movlw 0x10 ;set on time movwf BH loop3 decfsz BH,1 ;count down time to keep leds on goto loop3 movlw 0x00 ;turn leds off movwf GPIO movlw 0x10 ;set off time movwf BH loop4 incfsz BH,1 ;count up to keep leds off goto loop4 movlw 0x07 ;turn leds on movwf GPIO goto test2 ;repeat until bit high end
__________________
jeremy Last edited by jeremygaughan; 27th November 2007 at 11:14 PM. |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| I need some video software... | Marks256 | Chit-Chat | 7 | 6th January 2007 11:49 AM |
| B & C microsystems Proteus Eprom Programmer Software | dratomic | Datasheet/Parts Requests | 0 | 16th November 2005 12:16 AM |
| Breadboard design software? | ThermalRunaway | General Electronics Chat | 10 | 24th July 2005 12:34 PM |
| PCB designing software | mahesh_jo | General Electronics Chat | 3 | 6th September 2004 07:00 AM |
| Stimulation software savvy needed! | cwt | General Electronics Chat | 4 | 17th May 2004 08:28 AM |