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!!
Code:'**************************************************************** '* 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




Bookmarks