PDA

View Full Version : Help needed with source code



orangekitty
- 29th October 2010, 01:57
Hello,

I need help with writing the source code for PIC16F877A. I need it to generate PWM signal to the triac I would like to control. The PWM signal duty cycle are to be controlled using a potentiometer. I've tried to read through a lot but am still not sure. I've written only this so far and would need help. Pls.

DEFINE OSC 20
define ADC_BITS 8
VAR ani

TRISA = 255
ADCON1 = 0
ADCIN 0, ani



IF (PORTA.2==0) THEN PWM PORTB.3,0,1000
.
.
.

Ahmadabuomar
- 29th October 2010, 02:12
hi

i have a piece of code i wrote and examined in university. it takes two variable analog voltages and generate two pwm signals on portb.0 and portb.1 depending on the difference between voltages. pwm signals are software generated by tmr0 interrupt.

i hope this helps. if u have question about the code plz let me know.

i know alot of people her can help you better than me. but i m trying to do my best!!


'************************************************* ***************
'* Name : PWM_SIGNALS.BAS *
'* Author : [AHMAD ABU OMAR] *
'* Notice : Copyright (c) 2009 [AHMAD ABU OMAR] *
'* : All Rights Reserved *
'* Date : 15/12/2009 *
'* Version : 1.0 *
'* Notes : THIS PROGRAM GENERATES TWO PWM SIGNALS WITH A DUTY*
'* : RATIO DEPENDING ON AN EXTERNAL ANALOUGE FEEDBACK *
'* : ANALOGUE INPUTS ARE CONNECTED TO RA0 AND RA1 *
'* : PWM SIGNALS ARE GENERATED AT RB0 AND RB1 *
'************************************************* ***************
'************************************************* ***************
'* DIFINTIONS
'************************************************* ***************
DEFINE ADC_BITS 8 ' A/D MODULE BITS
DEFINE ADC_CLOCK 3 ' A/D MODULE CLOCK IS THE INTERNAL RC CLOCK
DEFINE ADC_SAMPLUS 50 ' A/D MODULE SAMPLING TIME

'************************************************* ***************
'* VARIABLES
'************************************************* ***************
RESULT1 VAR BYTE ' A VARIABLE TO STORE ANALOGUE INPUT 1
RESULT2 var BYTE ' A VARIABLE TO STORE ANALOGUE INPUT 2
RESULT3 VAR BYTE
OLD VAR BYTE ' A COUNTER VARIABLE

'************************************************* ***************
'* configurations
'************************************************* ***************
TRISA = $ff ' SET PORTA AS INPUT
TRISB = 0 ' SET PORTB AS OUTPUT
PAUSE 500 ' GIVE HALF A SECOND IDLE TIME

'************************************************* ***************
'* A/D MODULE INITIALIZATION
'************************************************* ***************

ADCON0 = %11000001 ' SET INTERNAL RC CLOCL, SELECT RA0 CHANNEL,
ADCON1 = 0 ' AND SWITCH ON THE A/D CONVERTER.
'************************************************* ***************
'* INTERRUPT INITIALIZTION
'************************************************* ***************

INTCON = %00100000 ' ENABLE TIMER0 OVERFLOW INTERRUPT
OPTION_REG = %00000100 ' SET A PRESCALAR OF 1:32 , THIS SUGGESTS THAT
' EVERY INCEMENT IN TMR0 IS 32 TIMES Tosc.
' OUR CRYSTAL IS 4MHz SO fosc = 1MHz
' Tosc = 1us
' THUS, TMR0 INCREMENTS EVERY 32us

TMR0 = 0 ' LOAD TMR0 VALUE
ON INTERRUPT GOTO ISR ' WHEN TMR0 OVERFLOWS, GOTO LABEL isr
INTCON = %10100000 ' ENABLE GLOPAL INTERRUPTS

'************************************************* ***************
'* MAIN PROGRAM
'************************************************* ***************
WHILE 1 ' ONLY AN INTERRUPT CAN BREAK THIS LOOP

PAUSEUS 1
gosub conv1 ' GO TO SUBROUTINE CONV1 AND DO A/D CONVERSION

WEND


'************************************************* ***************
'* ISR: INTERRUPT SERVICE ROUTINE
'************************************************* ***************
DISABLE ' DISABLE ALL OTHER INTERRUPTS
ISR:
PORTB = %11111111 ' START PWM SIGNAL ON PORTB, ON TIME

OLD = 0
'PAUSEus 1500 ' THIS INCREASES ON TIME FROM 8.1ms TO 8.6ms
TMR0 = 0

FOR OLD = 0 TO 255 ' MASKING ROUTINE WHICH GENERATES 2 PWM SIGNALS
' ON PORTB.0 AND PORTB.1, IT CAN BE MODIFIED TO
'GENERATE 8 PWM SIGNALS
' RESULT1 IS THE FIRST ANALOGUE INPUT VALUE.
' RESULT2 IS THE SECOND ANALOGUE INPUT VALUE
' DECREMENT RESULT1 EVERY ITERATION, WHEN IT REACH ZERO, PULL DOWN PORTB.0
' IF RESULT1 = 255, PWM SIGNAL ON PORTB.0 WILL BE 86% DUTY RATIO
'IF RESULT1 = 0 , PWM SIGNAL ON PORTB.0 WILL BE 0% DUTY RATION
' THE SAME APPLIES FOR RESULT2 AND PORTB.1

IF result1 <= 0 THEN PORTB.0 = 0 ' WHEN RESULT1 REACH 0, SWICH OFF FIRST PWM SIGNAL

IF result2 <= 0 THEN PORTB.1 = 0 ' WHEN RESULT2 REACH 0, SWITCH OFF SECOND PWM SIGNAL

IF RESULT3 <= 0 THEN PORTB.2 = 0

result1 = result1 - 1 ' DECREMENT RESULT1 EACH ITERATION
result2 = result2 - 1 ' DECREMENT RESULT2 EACH ITERATION
RESULT3 = RESULT3 - 1
WHILE TMR0 = OLD ' WAIT FOR TMR0 TO INCREMENT, THIS ASSURES
' THAT 255 LOOPS WILL GIVE US A MAXIMUM ON_TIME
' OF 255*32 = 8.16 + .5 = 8.6 ms
WEND

NEXT OLD

TMR0 = -5 ' LOAD TMR0 TO INTERRUPT AFTER 1.4ms
' THIS INSURES A FREQUENCY OF 100Hz
INTCON.2 = 0 ' ENABLE TMR0 INTERRUPTS
RESUME ' RESUME THE PROGRAM
ENABLE ' ENABLE GLOPAL INTERRUPT

'************************************************* ***************
'* A/D CONVERSION SUBROUTINE
'************************************************* ***************

CONV1:
ADCIN 0,RESULT1 ' READ ANALOGUE INPUT 1, STORE IN RESULT1

PAUSEUS 50 ' WAIT 50us TO INSURE A/D CAPACITOR DISCHARGE

ADCIN 1,RESULT2 ' READ ANALOGUE INPUT 2, STORE IN RESULT2
RESULT3 = (RESULT1-RESULT2)
'IF RESULT3 <=0 THEN RESULT3 = 1
return ' RETURN

END ' END OF MAIN PROGRAM

Acetronics2
- 30th October 2010, 10:06
Hi,

For the DIMMER function ...

begin by a look to this example, to see how it works ;)

http://melabs.com/resources/samples/submitted/dimmer.zip

you just need to replace Buttons input + counter by the pot reading value, once scaled.

Alain