 |
 |
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 02, 2010 5:36 pm |
|
|
I don't know if this is applicable to your project or not, but I made a
program that ramps the PWM duty cycle up and down continuously.
Look at pin C2 with your oscilloscope and you will see it.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define MAX_DUTY 255
int8 duty_cycle;
#int_timer2
void timer2_isr(void)
{
static int8 increment = TRUE;
if(increment)
{
duty_cycle++;
if(duty_cycle == MAX_DUTY)
increment = FALSE;
}
else
{
duty_cycle--;
if(duty_cycle == 0)
increment = TRUE;
}
set_pwm1_duty(duty_cycle);
}
//======================================
void main()
{
duty_cycle = 0; // Start with 0 duty cycle
// Setup CCP1 for PWM at 245 Hz.
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 254, 8); // Interrupt at 1/8 PWM freq
set_pwm1_duty(duty_cycle);
clear_interrupt(INT_TIMER2);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(1);
}
|
|
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Tue Feb 02, 2010 5:56 pm |
|
|
Thanks PCM programmer, that's what I'm after, something that has been proven to work by someone else that is triggered by the interrupt. I'll give it a go tonight.
From what I can see, at first glance it looks very similar to stuff I've already tried, but if it works, great I can use it as a starting point, if it doesn't then it should prove that I've got issues with either the chip itself or my breadboard, so I can find the cause of the problem rather than beating my head against a brick wall when the code itself might actually be fine.
PS. I don't have an oscilloscope, I'm just using an LED and the old mk1 human eyeball, so trying to get the timing at a rate that's discernable to a human. |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Tue Feb 02, 2010 11:28 pm |
|
|
PS. I'm wondering what the difference/reasoning is for the two variables:
int8 duty_cycle; //outside the ISR
static int8 increment = TRUE; //inside the ISR
Why the different declaration styles in different locations? They both seem to be accessed the same way in the same function? Does it make "increment" only available within the ISR whereas "duty_cycle" is available anywhere perhaps?
I think I need to do some research on variable scope... |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Wed Feb 03, 2010 7:10 am |
|
|
OK this is bizarre; had no luck whatsoever with the above code, I've just spent a few hours experimenting, just decided to strip it right back and disable the interrupts, just testing a set_pwm1_duty by itself, and I came across the following behavior:
with
duty_cycle = 0;
and
set_pwm1_duty(duty_cycle);
I am getting a lit LED! Maybe about 50% brightness.
but if I say
set_pwm1_duty(0);
the LED doesn't light!!
So what the %@#& is going on here??!
If I set the variable "duty_cycle" to 0, or set it to 255, I'm still getting the same apparent brightness??
Clock is 20MHz, timer2 setup is
setup_timer_2(T2_DIV_BY_16,255,2);
Any thoughts would be greatly appreciated, as I've spent hours on this and haven't gotten anywhere, then find that even the most basic function isn't working as it should be!
PS. I've also swapped out the chips, so hardware doesn't appear to be part of the issue. |
|
 |
Ttelmah Guest
|
|
Posted: Wed Feb 03, 2010 11:07 am |
|
|
What PIC?.
What compiler version?.
Have you actually tested that the output PWM frequency _is_ what you expect?.
You could get the symptoms being described, if timer2, was not being setup correctly.
Best Wishes |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Thu Feb 04, 2010 7:35 am |
|
|
Seems at least part of the problem was a compiler issue. I was using 4.028, running a PIC18F2620. Have now tried 4.057, and the PWM works! I'm even getting "noise" out of my sound routine, definitely not the audio I'm after but it's definetely trying to do something that isn't just a tone, sounds like it's trying to use the sound array to some degree or other.
As I said, when setting duty cycle with a variable it didn't matter what the variable value was it would give the same result, but if I put actual numbers directly into the set_pwm1_duty() function then it would work. Now with 4.057 the variables are working as they should be, and seems that most of my failed attempts of code were actually correct, or near enough. Just wasn't compiling properly
Well it's now nearly midnight so I'm off to bed, I'll see if I can get this sucker operational over the weekend! |
|
 |
Ttelmah Guest
|
|
Posted: Thu Feb 04, 2010 9:59 am |
|
|
Aargh!.
There for several years was a 'sticky thread' at the top of this forum, about V4. It is still on the forum, but has been allowed to move from the priority 'spot'.
Basically, V4, hardly worked for most chips, up to the late 03X versions.
This is particularly why several posters always ask for 'PIC', and 'Compiler version', when threads start.
Best Wishes |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Fri Feb 05, 2010 7:07 am |
|
|
Just a quick update, I now have recognisable audio output, the frequency needs a little bit of tuning but the system is now proven to definitely work. My initial code for the system seems like it was pretty-much spot-on, it was just because of the variable-to-pwm issue that it seemed like it was bad.
Now to figure out how to generate my own sample files and optimise the interrupt frequencies to suit...  |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Wed Feb 10, 2010 11:10 pm |
|
|
Possibly (probably?) a stupid question, but the original soundfile examples that I downloaded had the format of
Code: | #ifndef OK_H
#define OK_H
const char okay[5399]={0x39, 0x26, 0x26, 0x26, 0x26, 0x51, 0x77, 0x8C, 0x7C, 0x85, 0xB2, 0xDA, ...
};
#endif |
Question being, is this correct for such a long array, or should it be const int16 okay[5399] etc?
Reason being I'm getting my sounds cut off much sooner than they should be, but then again it seems like it would quite definitely be more than 256 samples that have played before they cut off...
Or do I need to maybe split up the array and buffer it somehow, ie. might the mcu be struggling to read in the info in time for some reason? Obviously I don't have a clue as to how the mcu actually retrieves the data, I just kinda assumed it could go to the memory and access each element of the array as it was needed, but maybe it actually tried to store the entire thing somewhere first and is having issues...?
PS. The new sounds I'm using are around 13,000 samples long, and seem to be cutting out at around halfway through playback. |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 10, 2010 11:35 pm |
|
|
What PIC are you using ?
Is this being done in real hardware ?
What is your compiler version ? |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Thu Feb 11, 2010 12:07 am |
|
|
It's actually a few posts back; PIC18F2620
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010284
64kB program memory, 4kB RAM, 1kB data eeprom.
4.057 compiler.
Real hardware, 20MHz crystal (no PLL, might change to 10MHz with PLL), hardware PWM with timer2 set to (div_by_1, 255, 1) (~19.5kHz? Highest setting I could figure out that kept 8bit resolution)
Sound is 16kHz mono 8bit, so timer0 set to interrupt @ ~32kHz, with routine being called every 2nd interrupt. Closest method/settings I could figure out to get close to 16kHz system.
I'll do some more tests tonight with it stripped back to just playing one soundfile in a loop, but from my last few experiments it appeared that the looping was occuring at the right time, but the last half of the time was empty of sound. Would then make a "glitch" sound and restart the loop, seemingly with different lengths of audible sound each time. |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 11, 2010 12:28 am |
|
|
Make a test program similar to this, and see if you can display the
first and last elements in the array.
Code: |
#include <18F2620.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
const char okay[5399]={
0x39, 0x26, 0x26, 0x26, 0x26, 0x51, 0x77, 0x8C, 0x7C, 0x85, 0xB2, 0xDA, ...
.
.
.
};
//======================================
void main(void)
{
int16 i;
int8 c;
// Display first element.
i = 0;
c = okay[i];
printf("%X ", c);
// Display last element.
i = 5398;
c = okay[i];
printf("%X ", c);
while(1);
}
|
|
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Thu Feb 11, 2010 12:43 am |
|
|
I don't actually have a working rs232 setup yet, so can't trace out anything, hoping to get one operational over the weekend. |
|
 |
RoGuE_StreaK
Joined: 02 Feb 2010 Posts: 73
|
|
Posted: Thu Feb 11, 2010 6:50 am |
|
|
Hmm, just tried a different method of "tracing" and looks like the problem's uncovered, but I have no idea how to get around it;
Instead of outputing the array values via serial, I thought I'd check the values by lighting an LED if they were true; Code: | if(sndLoop1[0] == "0x86") output_bit(PIN_A1, 1);
if(sndLoop1[12088] == "0x73") output_bit(PIN_A3, 1);
|
(sndLoop1 being a new sound loop, with 12089 values, first being "0x86", last being "0x73")
But that didn't compile, came up with an error for the second line "Subscript out of range"
According to the help file, "A subscript to a RAM array must be at least 1 and not more than 128 elements. Note that large arrays might not fit in a bank. ROM arrays may not occupy more than 256 locations."
So, looks like I have to figure out a way of spliiting my arrays so that each sub-section has no more than 128 elements in them? I haven't seen any examples anywhere that have come across this issue, any tips on where to start looking for a solution?
[EDIT] just tried splitting a small section into a multidimensional array, const char sndLoop1[11][128], 11 elements with 128 variables in each, but got the errors "Too may subscripts". So now I'm more stumped than Stumpy McStump at a stumping convention  Code: | const char sndLoop1[11][128]={
{
0x86,0x93,0x9D,0xA7,0xAE,0xB4,0xB9,0xBE,0xC2,0xC6,0xCA,0xCE,0xD2,0xD5,0xD8,0xDB,
0xDE,0xE1,0xE4,0xE6,0xE8,0xEA,0xED,0xEE,0xF0,0xF2,0xF3,0xF4,0xF6,0xF7,0xF8,0xF8,
0xF9,0xFA,0xFA,0xFB,0xFC,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,
0xFD,0xFD,0xFC,0xFC,0xFC,0xFB,0xFB,0xFA,0xF9,0xF9,0xF8,0xF7,0xF6,0xF5,0xF3,0xF2,
0xF1,0xEF,0xED,0xEB,0xE9,0xE7,0xE4,0xE2,0xDF,0xDC,0xD9,0xD6,0xD2,0xCF,0xCB,0xC7,
0xC3,0xBF,0xBA,0xB5,0xAF,0xA8,0x9F,0x96,0x87,0x73,0x68,0x5E,0x56,0x4F,0x4A,0x45,
0x40,0x3C,0x38,0x34,0x30,0x2D,0x29,0x26,0x23,0x20,0x1E,0x1B,0x19,0x17,0x14,0x12,
0x11,0x0F,0x0D,0x0C,0x0B,0x09,0x09,0x08,0x07,0x06,0x05,0x05,0x04,0x04,0x04,0x03
},{
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x05,0x05,
0x06,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x11,0x13,0x15,0x17,0x19,0x1B,
0x1E,0x21,0x23,0x27,0x2A,0x2D,0x31,0x34,0x38,0x3C,0x41,0x45,0x4A,0x50,0x57,0x5F,
0x69,0x76,0x87,0x95,0x9F,0xA8,0xAF,0xB5,0xBA,0xBE,0xC3,0xC7,0xCB,0xCF,0xD2,0xD6,
0xD9,0xDC,0xDF,0xE2,0xE4,0xE7,0xE9,0xEB,0xED,0xEF,0xF1,0xF2,0xF4,0xF5,0xF6,0xF7,
0xF8,0xF9,0xF9,0xFA,0xFB,0xFB,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,
0xFD,0xFD,0xFD,0xFD,0xFC,0xFC,0xFC,0xFB,0xFB,0xFA,0xF9,0xF9,0xF8,0xF7,0xF6,0xF4,
0xF3,0xF2,0xF0,0xEE,0xEC,0xEA,0xE8,0xE6,0xE3,0xE1,0xDE,0xDB,0xD8,0xD5,0xD1,0xCE
},{
0xCA,0xC6,0xC2, etc... |
Any help or pointers would be greatly appreciated, none of the info on sound playback I've come across ever mentioned issues with large arrays, so I dunno what they were doing differently...
PS. I also tried changing the CONST to ROM in both forms of the array, but it appeared to make no difference at all. |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|