Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Setting up CCP PWM in PIC16F628A

Status
Not open for further replies.
Thanks Wingmax.
I was looking for something like that.
 
Wingmax, I have a question about simple IR communication using PWM. I just want to start by sending an IR signal from one pic to another. To start I just want to send turn on and turn off. This will be to turn on a led. Could you tell me if I'm going in the right direction to start writing this code.
Transmitter:
A) set my PWM to 38KHz
B) send a few pulses of 10% to line up the transmitter and the receiver
C) send 80-100% duty cycle as on
D) send 60-79% duty cycle as off
E) repeat

Receiver:
D) set PWM to 38KHz
E) time the incoming pulse lengths
F) wait for 10% to happen a few times then take the next pulse as my real signal
G) call turn on for the longer pulses
H) call turn off for the shorter pulses
I) repeat

thanks for any help
 
Transmitter: looks fine, but don't try to line up the tx and rx. Just send 80% signal for on and 20% signal for off. Why are you using PWM though? Why not just send pulses out directly... 100 us for a zero, 200 us for a one, kind of thing?

Receiver: can't figure out what you're hoping to do here - PIC's don't have phase locked loops, so perhaps you want to use the CCP/PWM module as a capture module? I'd suggest that's easier - use CCP to capture the pulse edges, and process them in a loop in your main code (or perhaps under interrupt).
 
  • Like
Reactions: vdd
Nigel, Good tutorial I've got some thinking to do now. For right now your code is a little complicated for me. To me the cool thing about your code is I think the 8 bits could represent an analog input to the transmitter, and maybe with 24bits there could be three analog inputs. But that is the distant future.
So, first I'm going to try to send an always on or an always off just to see If my IR receptor and IR led are compatible. Then I'll try to modulate the signal. When that is working I'll come back with more information. Thanks
 
So heres what I figured out. With a pic on the transmission side and an IR receiver module connected to a led acting as a receiver I seem to be able to light a led with the PWM frequency in the attached code. I did some math and I think I'm running it at much lower than 38KHz, still it lights the light. 4MHz / 4 for the PIC's instruction cycle means 1MHz. I counted about 275 instructions. 1000000/275=3636.3 Does that mean that I'm running at 3.64KHz? Another thing, the IR module seems to work by driving the signal pin low, is that correct? The bit checks are for some switches that I put the change the duty cycle. That's how I'm guessing that it drives the pin low.


Code:
	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,wait,del_clk1,del_clk2,run,runn
	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
startt
	movlw	0x44
	movwf	run
start
	movlw	0x22
	movwf	BL
	btfss	GPIO,4			;call to see if low, if low make faster
	call	faster
	btfss	GPIO,5
	call	fastest			;call to see if low, if low make really fast

	movlw	0x07
	movwf	GPIO		;turn on leds
	movf	BL,0		;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
	movf	BL,0		;set off time of duty cycle
	movwf	BH
loop2
	incfsz	BH,1		;count up to the off time
	goto	loop2
	decfsz	run,1		;run the PWM for a moment
	goto	start
	goto	startt

faster
	movlw	0x02
	movwf	BL
	return
fastest
	movlw	0xff
	movwf	BL
	return
	end
 
After much googling I'm still having trouble calculating my PWM time. Here is the information that I'm using to calculate execution time.
1) 4MHz is divided into 4 to mean 1000000 instructions per second.
2) most instructions are 1 except the ones listed in the data sheet as taking 2 and sometimes, as in the case of decfsz, they take 1 normally but 2 when they test as true.
3) the formula is: crystal value divided by 4 gives instructions per second. Instructions per second divided by instructions per cycle gives cycles per second or Hz.
Does this sound right?
 
Last edited:
Why are you messing with PWM?, it's much simpler and more accurate to do it in software like my tutorials do - it also means you can more easily send exact numbers of cycles as well.
 
The reason I'm trying to use PWM is I thought the IR led and IR sensor will only communicate if the signal is PWM of 38KHz. I'm still studying your tutorial. I've been digging through the code and I have a ways to go before I understand it well. I'll post again after I've read your tutorial 3 or 4 more times.

About C... I know it's a lot less complicated to implement things like PWM or ADC. I'm going to delve into that realm soon, but first I want to have a good understanding of assembler, especially because all the data sheets use it.
 
jeremygaughan said:
The reason I'm trying to use PWM is I thought the IR led and IR sensor will only communicate if the signal is PWM of 38KHz. I'm still studying your tutorial. I've been digging through the code and I have a ways to go before I understand it well. I'll post again after I've read your tutorial 3 or 4 more times.

The 38KHz is simply a carrier frequency, by calling it PWM you're just confusing yourself.

To generate any frequency, you simply set the pin high, wait half a cycle, then set it low again, wait a further half a cycle, then set it back high - repeat for as many exact cycles as you want.

There are occasions when using the PWM hardware could be advantageous, but for many purposes it's more of a disadvantage.
 
I think I´m starting to get it. The "PWM" I´ve been talking about is a carrier signal that is PWM at 50% duty cycle and at 38KHz. I take this carrier signal and turn it on an off for different periods of time to make a morse code type signal that the receiver will interpret. What I´ve figured out is using the internal crystal of 4MHZ my carrier signal should be 26instructions long. Turn on = 2 instructions, nop for 10, turn off = 2 instructions, nop for 10, goto start = 2 instructions. It´s not exactally 38KHz and not exactally 50% duty cycle, but I hope it will work.
 
jeremygaughan said:
I think I´m starting to get it. The "PWM" I´ve been talking about is a carrier signal that is PWM at 50% duty cycle and at 38KHz. I take this carrier signal and turn it on an off for different periods of time to make a morse code type signal that the receiver will interpret. What I´ve figured out is using the internal crystal of 4MHZ my carrier signal should be 26instructions long. Turn on = 2 instructions, nop for 10, turn off = 2 instructions, nop for 10, goto start = 2 instructions. It´s not exactally 38KHz and not exactally 50% duty cycle, but I hope it will work.

It doesn't have to be exactly 38KHz, and you're still confusing yourself calling it PWM of any type - PWM is a specific use of a rectangular wave - and a carrier of this type isn't PWM.

Why didn't you just take the transmit routines from my IR tutorial?, why reinvent the wheel?.
 
I took your advice and took parts of the tutorial code and made a transmitter. It works too. It only works 6" away and closer but I´m working on that problem. The new problem I´m having now is a simple one. I´m trying to understand the receiver code to make one of those also but I´m getting stuck at a particular instruction. The code says goto "$-1" and in another code it says goto "$+2" I´ve found them on the internet but I´m still not sure. Goto "$-1" means goto one before this location, and goto "$+2" means goto two after this location or in other words skip one?
 
jeremygaughan said:
I took your advice and took parts of the tutorial code and made a transmitter. It works too. It only works 6" away and closer but I´m working on that problem. The new problem I´m having now is a simple one. I´m trying to understand the receiver code to make one of those also but I´m getting stuck at a particular instruction. The code says goto "$-1" and in another code it says goto "$+2" I´ve found them on the internet but I´m still not sure. Goto "$-1" means goto one before this location, and goto "$+2" means goto two after this location or in other words skip one?

That's right - $ is the current address, it's explained in the MPASM/MPLAB helpfile.

As for range, assuming you're using the driver circuit from my tutorial?, I get at least 13 metres range (the maximum length of the room where I work).
 
Another rookie mistake. The 4K7 instead of a 4.7 resistor I used is probably what was causing such a short range. Now, now it shoots at least 10 meters (the length of the hall here). Now I´ve got to figure out the receiver code and build on of those.
 
jeremygaughan said:
Goto "$-1" means goto one before this location, and goto "$+2" means goto two after this location or in other words skip one?

Goto $+2 would be skip two instructions.

Mike.
 
Pommie said:
Goto $+2 would be skip two instructions.

I think it depends how you look at it?, I would consider his view was correct.

Goto $+1 jumps to the next line (so skips nothing), useful as a double length NOP, Goto $+2 goes to the line after that, so only skips one line.
 
Nigel Goodwin said:
I think it depends how you look at it?, I would consider his view was correct.

Goto $+1 jumps to the next line (so skips nothing), useful as a double length NOP, Goto $+2 goes to the line after that, so only skips one line.

Of course it does. Stupid me forgot how to count.:eek:

Mike.
 
Status
Not open for further replies.

Latest threads

Back
Top