View previous topic :: View next topic |
Author |
Message |
educasoft
Joined: 02 Feb 2009 Posts: 82
|
Posted: Tue Feb 14, 2012 2:16 pm Post subject: Timing + PWM on same MCU ? |
|
|
Hi,
For a laser engraver machine I am writing a little bit of code to handle the laser power (PWM) and the length of 1 single laser shot (aprox 3ms)
The project will have 1 input line called SHOOT and 1 full port(8bits) will be used to atach dipswitch for pwm value select.
The project also will have 2 output pins being 1 SHOOT pin and 1 pwn signal
If the controler detects an active 1 on the input shoot pin, then it will set its output shoot pin to 1, but after 3ms will automatically reset it back to 0. This will repeat as soon as the controller receives anther 1 on the input shoot line
I was thinking of using timer1 for this, because its the highest resolution timer.
But then I also need in my main program loop (since the SHOOT will be in interrupt routine) some code to read the 8 bits of data from the 8 input pins (this will be done continuously, but speed isn't crucial as this value will not change a lot and only when it changes the pwm value will change)
I was thinking of using TIMER0 for this, but in the documentation I cannot find info about pwm on timer0.
Does this mean I cannot do pwm on timer0 ?
Or am I thinking totally wrong and should I run the PWM on my timer1 and then time that 3ms delay on timer0 ? Even at 8bits and using a bigger prescaler I guess aprox 3 ms would be easy to achieve ?
Fact is both pwm and 3ms delay would benefit if they are fairly accurate. That doesn't mean it should be exactly 3ms, but is can als be 3.0012154 ms , as long as it stays stable and doesn't change to much. The difference of 2.9ms , 3ms or 3.1ms of laser shooting is qute significant when
It would not be a problem if PWM only has 256 possible values, since I want to control laser power in percentages and that only needs 100 different steps, so even at 8bits I am 2.5 times more accurate then this.
I hope somebody can tell me if my thoughts are right ?
I also think an attiny2313 would be enough for this, since it won't need a lot of instructions. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Feb 14, 2012 2:26 pm Post subject: |
|
|
timer0 has pwm output. (pb2). have a look in the pin out viewer in bascom.
so yes a tiny2313 can do the job nicely. leave it to someone else to give a better detailed answer _________________ Mark |
|
Back to top |
|
|
i.dobson
Joined: 05 Jan 2006 Posts: 1570 Location: Basel, Switzerland
|
Posted: Tue Feb 14, 2012 2:34 pm Post subject: |
|
|
Hi,
Have a look at the CPU you want to use, if the cpu supports pwm then you'll have a pin called something like OC0A where 0 is the timer number used to generate the PWM signal and A is the output (Some chips support several PWM outputs from one TIMER so OC0A,OC0B etc).
Then have a look at what other timers are available.
Unless your looking at a huge production (Several K chips/boards) use a larger chip than you think you need.
I usually start with a mega8, then mega162, then mega32. The price difference between a tiny chip and a mega chip is so small that it doesn't make sense to try and save afew dollars. Also when you start a project do you know exactly what the final result (In terms of code/functionallity) should be? I'm currently working on a project for my company, the first version of the software was about 1K lines and 10Kb in size. After the salesman saw what was possible they came up with new ideas/improvements which after afew "discussions" I've implemented, and now the code is 1.5K lines and 14Kb in size.
Regards
Ian Dobson _________________ Walking on water and writing software to specification is easy if they're frozen. |
|
Back to top |
|
|
educasoft
Joined: 02 Feb 2009 Posts: 82
|
Posted: Mon Feb 20, 2012 12:12 am Post subject: |
|
|
Hi again,
I am a little further now in my code and until now I got an external intrerrupt working on INT0 + Timer1 also helps me to generate a very precisely timed ON time for an output pin.
Using serial communication I can set this timer1 value, so that all works.
The only thing which seems not to work yet is the fact that I want to use timer0 (or timer2 if timer0 can't do it) to generate a pwm output signal on a pin of the mcu.
I do understand that since I allready use my timer1 for something else, timer0 and timer 2 are only 8 bits , so only 256 possible pwm values, but I have no problem at all with that since it will be more then enough. The purpose of this pwm signal is to input the signal into the analog input of a laser tube power supply to determine the power with which the laser will shoot.
So I need to make a 0->5V signal for that ant thats why I need PWM
Here is my code until now
Code: |
'-----------------------------------------------------------------------------------------
'name : PPI_CHIP.bas
'micro : Mega328
'-----------------------------------------------------------------------------------------
$regfile = "m328def.dat" ' specify the used micro
$crystal = 11059200 ' used crystal frequency
$baud = 115200 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
'Config Serialin = Buffered , Size = 20
Dim Reload As Word
Dim Commando As Byte
Dim Par1 As Byte
Dim Par2 As Byte
Reload = 187
Config Portc = Output
Config Portd.6 = Output
Config Int0 = Falling
Config Timer1 = Timer , Prescale = 64
Ocr1ah = High(reload)
Ocr1al = Low(reload)
On Int0 React_on_external_pulse Nosave
On Compare1a Stop_3ms_pulse Nosave
Portc = 0
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
Pwm0a = 128
Enable Interrupts
Enable Int0
Enable Timer1
Enable Timer0
Enable Compare1a
Do
Inputbin Commando
If Commando = 0 Then
Inputbin Par1 , Par2
Reload = 256 * Par1
Reload = Reload + Par2
Ocr1ah = High(reload)
Ocr1al = Low(reload)
Print "Timer SET";
End If
If Commando = 1 Then
Print "Command 2 accepted"; 'still have to fill in code here of course
End If
Loop
End
React_on_external_pulse:
Portc = 255
Timer1 = 0
Enable Timer1
Return
Stop_3ms_pulse:
Disable Timer1
Portc = 0
Return
|
I read a lot on the forum and tested out. I even googled a lot (but it looks like a lot of code out there doesn't even compile anymore with latest bascom version 2.0.7.3.001)
I have a config for the timer0, I set pwm0a to 127 (so I was hoping to see a 50% signal at the logic analyser or around 2.5V on the voltmeter?)
On the atmega328 OC0A seems to be on portd.6
Is there anything I am doing terribly wrong here to get a pwm signal on my output pin ? I really tried sooo many combinations of stuff I found online and still nothing seems to offer me a pwm signal.
Maybe its not as simple as I thought it would be ? I thought that you could just set the pwm value to a byte value and automatically the timer would begin using that value for the pwm timing from then on ?
I hope somebody can see what I do wrong here.
Thanks in advance allready for being willing to read my post.
I can't find my error
Bart |
|
Back to top |
|
|
educasoft
Joined: 02 Feb 2009 Posts: 82
|
Posted: Tue Feb 21, 2012 12:51 am Post subject: |
|
|
Is there anybody who could help me a little bit with this one.
Today I struggled another 5+ hours trying to solve this but somehow I must be missing something crucial ?
The chip I want to let this work on is a ATMEGA328-PU
Timer1 and INT0 in my code all work flawlessly, but I cannot seem to get any pwm response at all with this code on an atmega328-PU PDIP chip
If it isn't possible with timer0 then timer2 is also not used at the moment so can also be used. This is the only function left which should get into my code so it doesn't matter if the pwm output is done with timer0 or timer2 as long as I have 1 working 8bit settable pwm output on the chip.
Kind regards,
Bart |
|
Back to top |
|
|
educasoft
Joined: 02 Feb 2009 Posts: 82
|
Posted: Wed Feb 22, 2012 3:56 pm Post subject: |
|
|
Yes!!!!!!!! I found a solution to my problem
By taking the source code above and removing all code related to timer0, I then added only these 3 lines of code
Tccr0a = &HA1
Tccr0b = &H02
Ocr0a = &H7F
And suddenly PWM output became available on the atmega328. I don't know why it didn't work with CONFIG TIMER0 ?
So it does work now, but if somebody knows why my other code didn't work then this could be nice to know for other people searching this forum with similar problems.
Kind regards,
Bart |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Wed Feb 22, 2012 4:30 pm Post subject: |
|
|
Your timer0 config:
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
Pwm0a = 128
Maybe it is because there is no port config for "B-output" and no compare value set for B but declared in the timer config.
(did not test it)
Hubert |
|
Back to top |
|
|
|