' ========================================================================= ' ' File...... PWM16.SXB ' Compiler.. SX/B Version 1.51.03 ' Purpose... 16 Channels of PWM (Duty cycle type okay for motor control) ' Author.... Hitt Consulting ' E-mail.... terry@hittconsulting.com ' Started... May 13, 2005 ' Updated... May 17, 2005 ' ' ========================================================================= ' ------------------------------------------------------------------------- ' Program Description ' ------------------------------------------------------------------------- ' Accepts serial data at 2400 baud and provides 16 channels of duty cycle modulated PWM ' Serial data is sent with a header of "!PWM" then 16 bytes of data (0=full off, 255=full on) ' ' OSC1&2 = 20Mhz resonator ' Port RA.3 = Serial input ' Port RB = Channels 0 to 7 ' Port RC = Channels 8 to 15 ' ' 10K ' /MCLR -/\/\/\----- Vdd Pin ' ' 10K ' RA.3 -/\/\/\-----< Serial Input (2400 baud 8N1 Inverted) ' ' 220 Ohm ' RB.0 -/\/\/\-----> PWM Output 0 ' ' 220 Ohm ' RB.1 -/\/\/\-----> PWM Output 1 ' ' 220 Ohm ' RB.2 -/\/\/\-----> PWM Output 2 ' ' 220 Ohm ' RB.3 -/\/\/\-----> PWM Output 3 ' ' 220 Ohm ' RB.4 -/\/\/\-----> PWM Output 4 ' ' 220 Ohm ' RB.5 -/\/\/\-----> PWM Output 5 ' ' 220 Ohm ' RB.6 -/\/\/\-----> PWM Output 6 ' ' 220 Ohm ' RB.7 -/\/\/\-----> PWM Output 7 ' ' 220 Ohm ' RC.0 -/\/\/\-----> PWM Output 8 ' ' 220 Ohm ' RC.1 -/\/\/\-----> PWM Output 9 ' ' 220 Ohm ' RC.2 -/\/\/\-----> PWM Output 10 ' ' 220 Ohm ' RC.3 -/\/\/\-----> PWM Output 11 ' ' 220 Ohm ' RC.4 -/\/\/\-----> PWM Output 12 ' ' 220 Ohm ' RC.5 -/\/\/\-----> PWM Output 13 ' ' 220 Ohm ' RC.6 -/\/\/\-----> PWM Output 14 ' ' 220 Ohm ' RC.7 -/\/\/\-----> PWM Output 15 ' ------------------------------------------------------------------------- ' Device Settings ' ------------------------------------------------------------------------- DEVICE SX28, OSCHS1, TURBO, STACKX, OPTIONX, BOR26 FREQ 20_000_000 ' ------------------------------------------------------------------------- ' IO Pins ' ------------------------------------------------------------------------- UnsedRA PIN RA OUTPUT SerialInPin PIN RA.3 INPUT PWMs PIN RBC OUTPUT ' ------------------------------------------------------------------------- ' Constants ' ------------------------------------------------------------------------- Baud CON "N3409" ' This adjustment is need because the interrupt uses ' 148 cycles every 500 clocks. So the main code only ' gets 352 cycles of every 500 clocks. ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- ' Variables for PWM pwm_Count VAR BYTE pwm_Values VAR BYTE (16) ' Variables for main code temp VAR BYTE serialData VAR BYTE ' Set by subroutine "GetSerialChar" ' ------------------------------------------------------------------------- INTERRUPT NOCODE 40_000 ' 148 CYCLES = 5,920,000 cycles every second = 29.6% @ 20MHz ' ------------------------------------------------------------------------- ASM MOV FSR,#__INTPARAMFSR ' (2) Prepare to save __PARAM1 MOV IND,__PARAM1 ' (2) Save __PARAM1 BANK $00 ' (1) Set bank to access PWM_Count INC pwm_Count ' (1) Adjust the PWM count ' If the PWM value for each channel is less than ' PWM_Count then it should be high, othewise it ' should be low. MOV __PARAM1,pwm_Count ' (2) Make copy of PWM_Count in global memory MOV FSR,#pwm_Values ' (2) Set FSR to address of 1st element of PWM values MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.0 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.0 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.1 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.1 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.2 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.2 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.3 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.3 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.4 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.4 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.5 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.5 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.6 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.6 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RB.7 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RB.7 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.0 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.0 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.1 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.1 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.2 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.2 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.3 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.3 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.4 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.4 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.5 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.5 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.6 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.6 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV W,IND ' (1) Get value for this channel MOV W,__PARAM1-W ' (1) Set carry if output bit should be cleared, clear carry if bit should be set SNC ' (1) Only clear output bit if carry is set CLRB RC.7 ' (1) Clear output bit SC ' (1) Only set output bit if carry is clear SETB RC.7 ' (1) Set output bit INC FSR ' (1) Point to next PWM channel MOV FSR,#__INTPARAMFSR ' (2) Prepare to restore __PARAM1 MOV __PARAM1,IND ' (2) Restore __PARAM1 ENDASM RETURNINT ' ========================================================================= PROGRAM Start NOSTARTUP ' ========================================================================= ' ------------------------------------------------------------------------- ' Subroutine Declarations ' ------------------------------------------------------------------------- GetSerialChar FUNC 1,0 ' ------------------------------------------------------------------------- ' Program Code ' ------------------------------------------------------------------------- Start: ' Set all channels to zero FOR temp=0 TO 15 pwm_Values(temp)=0 NEXT DO ' Wait for "!PWM" header GetSerialChar IF SerialData = "!" THEN GetSerialChar IF SerialData = "P" THEN GetSerialChar IF SerialData = "W" THEN GetSerialChar IF SerialData = "M" THEN ' Get Data for 16 PWM channels FOR temp=0 TO 15 pwm_Values(temp) = GetSerialChar NEXT ENDIF ENDIF ENDIF ENDIF LOOP END ' ------------------------------------------------------------------------- ' Subroutine Code ' ------------------------------------------------------------------------- FUNC GetSerialChar SERIN SerialInPin,Baud,serialData RETURN serialData ENDFUNC