Extracting 10 bits from word variable and writing them into two separate registers?
Hello.
I want more precise and fine control of built-in PWM module of 16F1939, Since HPWM statement allows only 8 bit setting, and on each launch it re-starts the HPWM module, which makes not so good sound, when HPWM is used as sound generator. So for this, I need to directly write to two registers, in my case, LSB bits 0 and 1 go into CCP2CON bit 4 and bit 5, and remaining 8 bits go to CCPR2L register.
So as I understand, I need to do the following
CCP2CON.4=X DIG 0
CCP2CON.5=X DIG 1
CCPR2L.0=X DIG 3
CCPR2L.1=X DIG 4
CCPR2L.2=X DIG 5
and so on.
But I guess, there should be some simpler way of doing this?
Re: Extracting 10 bits from word variable and writing them into two separate register
The usual way of doing it is:
Code:
CCP2CON.4 = X.0
CCP2CON.5 = X.1
CCPR2L = X>>2
PS. The DIG operator does not work like you seem to think.
Re: Extracting 10 bits from word variable and writing them into two separate register
Yes might be :)
Anyways, your method works, and now I have quite primitive, but still usable control over ADSR envelope, so my PICs can have some iconic 80s synth sounds :D
btw, if anyone wants simple way to play two musical notes together with PBP, there's a simple trick to do it, with built in PWM generator. All you need to do, is start hardware PWM with frequency/duty cycle of 1st note, and restart it with frequency of 2nd note. Something like this:
Code:
ASDF:
HPWM 1,127,440 'frequency of 1st note
pauseus 110 'period of 2nd note frequency
goto ASDF
The exact numbers had to be adjusted according to actual frequencies, but general idea is this, and it works. I'm making a "tetris" music playback this way, and will post video later.
Re: Extracting 10 bits from word variable and writing them into two separate register
Strange issue - sound duration changes with register status update.
These registers somehow interfere with PAUSEUS statement?
Code:
z=0
takra:
hpwm 2,127,880+Z
for x=1 to 1000 step 2
CCP2CON.4 = X.0
CCP2CON.5 = X.1
CCPR2L = X>>2
pauseus 1800
next
pause 300
Z=Z+60
goto takra
Some sounds here sound 2-3 times longer than others!
Re: Extracting 10 bits from word variable and writing them into two separate register
Not sure what you're trying to do there. Why are you using HPWM and setting the dutycycle manually at the same time?
The inner loop will change the dutycycle (not the frequency) of the PWM signal but depending on the specific configuration of the CCP module that the HPWM command produces for the specific frequency you're requesting you might not HAVE ~10bits of resolution which is what you need since you're trying to get to a dutycycle value of 1000 meaning you might write an invalid duty cycle value to the duty cycle register.
Re: Extracting 10 bits from word variable and writing them into two separate register
HPWM statement is used once to set the frequency.
Duty cycle is varied in attempt to recreate ADSR Envelope, for audio synthesis.
https://en.wikipedia.org/wiki/ADSR
Re: Extracting 10 bits from word variable and writing them into two separate register
I suggest you look at this article by Michael Melkonian for inspiration of what is possible on PIC. https://www.embedded.com/get-by-without-an-rtos/
Re: Extracting 10 bits from word variable and writing them into two separate register
I'm sorry, that article does not carry the link to his work. I cannot find the bundle called PIC_OSA which showed his implementation of a polyphonic piano(I think) using a PIC processor with MP3s to hear the results achieved. If I find it again, I will post the link.
Re: Extracting 10 bits from word variable and writing them into two separate register
Re: Extracting 10 bits from word variable and writing them into two separate register
Yeah I have seen that 10+ years ago.
But for obvious reasons, I'm going my way :)