When that count exceeds 1000 you subtract 1000 ( don't zero it) and add 1 to a millisecond counter. If your interrupt is firing every 13µs then add 13 to a global counter - that counter is then the number of microseconds that have passed. Instead create your own timing functions that are controlled by your own interrupt that does the pin IO - instead of relying on a system provided tick you create your own. So the answer to that is don't use millis() and delay(). But fidding with timers breaks things like millis() and delay(). So a much better solution would be to use a timer, since that is what they are there for. Of course, anything else you want to happen repeatedly would have to be inside that while loop, and most likely would impact your output timing somewhat. There is quite a large overhead in using the auto-repeating of loop() that can be avoided by looping within it with a while (1) like that. Note the use of while (1) there rather than relying on the loop() function repeating itself. Something like: uint32_t start = micros() You will still need high speed direct port access rather than using digitalWrite() since digitalWrite() adds way too much overhead to be able to do that kind of timing reliably. If you don't need absolutely reliable timing anyway it might be easier (though far less accurate) to use the micros() function to find when 13µs have elapsed and do it all in C instead of assembly. However all that is pretty much academic, because the loop will keep being interrupted by your timer 0 interrupt and cause jitter in your output as the interrupt routine is being run instead of your IO pin driving loop. That means even more careful instruction counting to get that loop to equal the 104 or 102 clock cycles needed for the precise timing. You could compress all the NOP instructions down into a tight loop themselves by setting a register to a pre-defined loop count value, decrement it each pass - repeat if it's not 0. The simplest (though most long winded) loop would be an OUT or SBR (depending on port) instruction (1 clock) to set the IO pin HIGH, then 104 NOPs (1 clock each), then an OUT or CBR to set it LOW (1 clock), then 102 NOPs (1 clock each), then an RJMP to go back to the start (2 clocks). of the data sheet details the clock cycles used for each instruction. For that you need to do some careful instruction cycle counting and work in assembly language. So now you need to create a tight loop that is exactly 105 clock cycles long including the toggling of the IO pin and the comparisons and branches for the loop. That can't happen, so the closest you would get is 105 clock cycles, which would be 13125ns, or 76.190kHz, or an end frequency of 38.095kHz. so 13156ns would equate to 105.248 clock cycles. I assume you are running it at 8Mhz (internal calibrated RC oscillator) - that means each clock tick is 1/8000000=125ns long. That's quite a high accuracy to try and achieve with delays on a small chip like the 84A. If A is not possible can somebody give me a hint how to "bit bang" the IR LED with delay? (I guess that is a silly question but I can't figure it out at the moment :()Ī 38kHz square wave at 50% duty cycle would be a transition running at 38x2=76kHz. Maybe some of the gurus around here could help? I would prefer A but Google didn't give me a solution. I tried to change the code in wiring.c to use a prescaler of 1 instead of 64 by changing the defines but that didn't work out.Ī: somehow modify timer0 to generate my 38 KHz signal and still provide correct functionality for the timing functions.ī: let timer0 be initialized the way the Arduino wants it and utilize the delay functions to blink the IR LED. The delay functions ( micros(), millis() etc.) stopped working and prevented me from using my serial communication. So what I have tried so far is setting up timer0 for my PWM stuff and everything worked IR LED-wise. I only want to use it as a light barrier (Iknow there are better ICs for that but I am stuck with the ones I already have). I don't want to transmit actual data to the TSOP4838. Timer1 can not be used because it is already used by other features. I know the real thing would be to utilize a timer but the ATtiny only has 2 Timers (T0 and T1). I am currently trying to generate a 38 KHz signal for my TSOP4838 ( ) with an ATtiny84A.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |