![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
PWM in title
How would i go about making a PWM signal using software alone.. 38khz of course i know this much: Code:
/* * PWM registers configuration * Fosc = 8000000 Hz * Fpwm = 37735.85 Hz (Requested : 38000 Hz) * Duty Cycle = 50 % * Resolution is 7 bits * Prescaler is 1 * Ensure that your PWM pin is configured as digital output * see more details on http://www.micro-examples.com/ * this source code is provided 'as is', * use it at your own risks */ PR2 = 0b00110100 ; T2CON = 0b00000100 ; CCPR1L = 0b00011010 ; CCP1CON = 0b00011100 ; But that just sets the registers... Now what? Do i just do a high/low with delays? Or would that be just a software PWM by itself? Last edited by AtomSoft; 7th April 2008 at 11:40 PM. Reason: Topic Typo |
|
|
|
|
|
|
(permalink) |
|
See Krumlinks' Thread.
http://www.electro-tech-online.com/m...e-pic13xx.html Done correctly, you let the hardware do it all for you. Read the Capture/Compare/PWM module doc till your eyes fall out. It is there.
__________________
August Treubig AG5AT Last edited by August Treubig; 7th April 2008 at 11:40 PM. |
|
|
|
|
|
|
(permalink) |
|
Thx.. Not sure i understand but ..
Code:
// speed up the clock to 8MHz
OSCCONbits.IRCF0=1; OSCCONbits.IRCF1=1;
OSCCONbits.IRCF1=1;
OSCCONbits.IRCF2=1;
OSCCONbits.SCS0=0;
OSCCONbits.SCS1=0;
//18F1330 Speed clock up to 32MHz using PLL
OSCTUNEbits.PLLEN=1;
ADCON1 = 0; // make RA0 digital
TRISA = 0xFE;
while(1)
{
PORTA = 0xFF;
delay_us(13);
PORTA = 0x00;
delay_us(13);
}
So to send 0000001 i would send Low Delay Low Delay Low Delay Low Delay Low Delay Low Delay Low Delay High ? Like that? or High Delay(small) High Delay(small) High Delay(small) High Delay(small) High Delay(small) High Delay(small) High Delay(small) High Delay(longer) |
|
|
|
|
|
|
(permalink) |
|
Its for a IR Remote....
|
|
|
|
|
|
|
(permalink) |
|
I understand what it is for. Please look at the code first code that I posted in the other thread.
While it isn't for Sony or the more popular stuff. It is for my Panasonic HD TV. It will turn it on and off every time. The key here is that it uses PWM hardware to generate the 38khz signal. The second example came first and is a working (at 4mhz) section of code that used to be in the first program. With the PWM hardware, you tell it the length of the pulse and then in another place the duty cycle. In our case 50%. Then you turn it on and the hardware does it all.
__________________
August Treubig AG5AT |
|
|
|
|
|
|
(permalink) |
|
Not sure how it works tho....
Um can you comment some of it like um... You said ... You tell it the length of the pulse and the duty cycle... Is the duty cycle what is sending the actual code? How would i send 2 bytes? like 0x0D and then 0x00 ? |
|
|
|
|
|
|
(permalink) |
|
"The SIRC protocol uses a pulse width encoding of the bits. The pulse representing a logical "1" is a 1.2ms long burst of the 40kHz carrier, while the burst width for a logical "0" is 0.6ms long. All bursts are separated by a 0.6ms long space interval. The recommended carrier duty-cycle is 1/4 or 1/3."
so to send a 0x00 i have to send : start (high) for 2.4ms .6ms delay "high' for .6ms delay .6ms "high' for .6ms something like that? Just setting that 1 pin high and low for periods of time? Im confused because you use PORTA = 0xFF that sets all of PORTA bits. Even the ones not on the IR led.... right |
|
|
|
|
|
|
(permalink) |
|
Please look at Krumlink's thread. I have posted the code in pieces there.
Ok here is the whole thing for 18F1320 Code:
#include <system.h>
//Target PIC18F1320 configuration word
//#pragma DATA _CONFIG, _CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT
#pragma DATA _CONFIG1H, _INTIO2_OSC_1H & _FSCM_OFF_1H
#pragma DATA _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_27_2L
#pragma DATA _CONFIG2H, _WDT_OFF_2H & _WDTPS_32K_2H
#pragma DATA _CONFIG3H, _MCLRE_ON_3H
#pragma DATA _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_ON_4L
#pragma DATA _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
#pragma DATA _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
#pragma DATA _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
#pragma DATA _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
#pragma DATA _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
#pragma DATA _CONFIG7H, _EBTRB_OFF_7H
//Set clock frequency
#pragma CLOCK_FREQ 8000000
// 38 khz
#define CCP1Period 12
#define CCP1DutyCy 25
bit running = 0;
unsigned char turnon[6] = { 0x40, 4, 1, 0, 0xbc, 0xbd};
void interrupt( void )
{
// Handle timer1 interrupt
// Used to time the length of pulses
if( pir1.TMR1IF )
{
running = 0;
t1con.TMR1ON = 0; // Turn TIMER1 off
pir1.TMR1IF = 0; //clear timer 1 interrupt bit
}
}
void xmit_pulse(short micro_pulse)
{
static short clock_count;
clock_count = 65536 - micro_pulse;
LOBYTE( tmr1l, clock_count);
HIBYTE( tmr1h, clock_count);
pir1.TMR1IF = 0; // Reset overflow bit
t1con.TMR1ON = 1; // Turn TIMER1 on
running = 1;
trisb.3 = 0;
t2con.TMR2ON = 1;
while (running) ; // Wait for pulse time to end
t2con.TMR2ON = 0;
tmr2 = 0;
portb.3 = 0;
trisb.3 = 1;
}
void send_on(void) {
static char i;
static char j;
static char t;
static unsigned char *ovalue;
static unsigned char k;
// Send it 3 times
for (k = 0; k < 3; k++) {
ovalue = &turnon;
xmit_pulse(3550); // 4 ms header
delay_100us(10); // 1 ms
delay_10us(6); // .6 ms
for (i = 0; i < 6; i++) {
for (j = 8; j > 0; j--) {
t = j - 1;
if (test_bit(*ovalue, t)) {
// A one
xmit_pulse(512); // 400 micro s
delay_100us(10); // 1 ms
delay_10us(2); // .2 ms
}
else {
// A zero
xmit_pulse(512); // 400 micro s
delay_100us(3); // 400 micro s
}
}
ovalue++;
}
// End bit
xmit_pulse(400);
delay_ms(70);
}
}
void main( void )
{
static unsigned char Low;
static unsigned char High;
static unsigned int Duty = CCP1DutyCy;
// Set speed to 8 mhz
set_bit(osccon, IRCF2);
set_bit(osccon, IRCF1);
set_bit(osccon, IRCF0);
ccp1con = 0; // CCP Module off
tmr2 = 0; // Clear Timer 2
//Configure port B
trisb = 0x00;
trisb.3 = 1;
intcon2.NOT_RBPU = 0;
//Initialize port B
portb = 0;
//Set timer 1
//prescaler rate 1:1
//Internal clock (FOSC/4)
t1con = 00001000b;
// Configure Capture/Compare/PWM for PWM
// at 38khz.
//Set timer 2 prescaler rate
// T2CPS = 1:4
t2con = 00000001b;
//t2con = 0;
pr2 = CCP1Period;
Low = Duty & 3;
High = Duty >> 2;
ccpr1l = High;
ccp1con = 00001100b;
ccp1con.5 = Low.1;
ccp1con.4 = Low.0;
intcon.PEIE = 1; // Enable peripheral interrupts
intcon.GIE = 1; // Enable global interrupt
pie1.TMR1IE = 1; // Enable Timer 1 interrupts
// test
trisb.3 = 0;
t2con.TMR2ON = 1;
while (1) ;
// test
// Main Loop
send_on();
while (1) {
}
}
Code:
// 38 khz
#define CCP1Period 12
#define CCP1DutyCy 25
static unsigned char Low;
static unsigned char High;
static unsigned int Duty = CCP1DutyCy;
// Configure Capture/Compare/PWM for PWM
// at 38khz.
//Set timer 2 prescaler rate
// T2CPS = 1:4
t2con = 00000001b;
//t2con = 0;
pr2 = CCP1Period;
Low = Duty & 3;
High = Duty >> 2;
ccpr1l = High;
ccp1con = 00001100b;
ccp1con.5 = Low.1;
ccp1con.4 = Low.0;
Code:
trisb.3 = 0;
t2con.TMR2ON = 1;
__________________
August Treubig AG5AT |
|
|
|
|
|
|
(permalink) |
|
That seems like way too much code just to send a pulse....
And just telling me to look at the code doesnt really help... I thank you for trying to point me to the right direction but this doesnt answer my question. which was: HIGH(4ms) - would be start bit LOW(1ms) - a space HIGH(1ms) - a 0 LOW(1ms) - a space HIGH(2ms) - a 1 would it be something like that to send a start then 0 and 1 bit? Maybe its me or this code isnt commented well enough. Remember im a nooB still and well... this seems too much for something that seems so simple to achieve. |
|
|
|
|
|
|
(permalink) |
|
This code starts the PWM on Junebugs RB3, you can watch RB3 using MPLABS simulator / logic analyzer.
Code:
// 37.7kHZ PWM IR carrier signal
#include <p18f1320.h>
#pragma config WDT = OFF,OSC = INTIO2,LVP = OFF
void main(void) {
OSCCON=0x72; // speed up the clock to 8MHz
ADCON1 = 0;
TRISBbits.TRISB3 = 0;
PR2 = 0b00110100 ;
T2CON = 0b00000100 ;
CCPR1L = 0b00011010 ;
CCP1CON = 0b00011100 ;
while(1) {
}
}
|
|
|
|
|
|
|
(permalink) |
|
ok i can see how it starts it ...
To turn it off i do... T2CON = 0b00000000 ; i assume... But how do i send out the data still? To send data does it require me to set RB3 HIGH? If so : When i set it high do i have to make a delay for the amount of time it has to be high to represent a logical 1, 0 and space. (also start) |
|
|
|
|
|
|
(permalink) |
|
I would set the duty to 0% for a zero; then to 50% for a 1. The 38KHz is a carrier (envelope) for the data, as long as the data timing is correct the IR decoder will strip away the carrier automatically and pass the raw data to the PIC.
http://www.sixca.com/eng/articles/remote/index.html Also read this for the data format for Sony RC5 http://www.sbprojects.com/knowledge/ir/sirc.htm ![]() Those black squares are actually a 38KHz square wave! (the carrier) Last edited by blueroomelectronics; 8th April 2008 at 05:11 AM. |
|
|
|
|
|
|
(permalink) |
|
ok ok ok that kinda made more send let me fiddle lol
|
|
|
|
|
|
|
(permalink) |
|
OK ok ok i think im getting it but still confusing just a little maybe lol
CCPR1L = 157 ;//Would this be high? or good enough CCPR1L = 0; // I guess good enough for low Now all i have to do is make a delay of 600uS and for a 2.4ms i can call it 4 times? while at 50% then drop to 0% and call the delay 1 time for a space.. Does that sound about right so far? |
|
|
|
|
|
|
(permalink) |
|
CCPR1L = 0b00011010 ; // this should set it to 50%
I've got to sleep but will look tomorrow, sounds like you've got the right idea. If you have an older Sony TV or VCR they may have a SIRCs jack on the (1/8" stereo phone plug). You can send unmodulated TTL level RC5/SIRC (0-5V) data to that connector. Search for SONY+ RC5 or SIRC Last edited by blueroomelectronics; 8th April 2008 at 05:42 AM. |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Quik PIC Programming kit | Krumlink | General Electronics Chat | 5 | 27th January 2008 11:27 PM |
| Am I USING PIC UART CORRECTLY?? | cyprio7 | Micro Controllers | 46 | 15th January 2008 06:02 PM |
| Capturing and reproducing audio with a PIC | Fred.Amoson | Micro Controllers | 14 | 14th December 2007 08:21 PM |
| Problems switchin relay with PIC | Andy1845c | General Electronics Chat | 5 | 17th November 2007 06:13 PM |
| High ADC sampling rate PIC, 18F needed? | bananasiong | Micro Controllers | 24 | 28th October 2007 12:13 PM |