Code: Select all
program ADC_Test
dim pot1 as float
dim pot2 as float
dim hold as byte
dim hold2 as byte
dim i as byte
txt as char[23]
'****************************************************
'* Remember to edit Peripheral Pin select config *
'****************************************************
main:
' Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; ((25MHz/5)*14) = 40MHz
' refer the pic33 family datasheet for more details
CLKDIV = CLKDIV and 0xFFE5 ' CLKDIVbits.PLLPRE = 5
PLLFBD = 12 ' PLLFBDbits.PLLDIV = 14-2
ADC1_Init_Advanced(_ADC_12bit, _ADC_INTERNAL_REF) ' Setup ADC
Unlock_IOLOCK()
PPS_Mapping(23, _OUTPUT, _U1TX) ' mapping RPx pin as uart1 tx
PPS_Mapping(22, _INPUT, _U1RX) ' mapping RPx as uart1 rx
Lock_IOLOCK()
UART1_Init(9600) ' Initialize UART communication
Delay_ms(100)
TRISB.8 = 0
TRISB.10 = 0
TRISB.11 = 0
SetBit(PORTB, 8)
PORTB.10 = 1
PORTB.11 = 1
while TRUE
PORTB.8 = NOT PORTB.8
pot1 = (((ADC1_Get_Sample(0)/4095.0)*3.30)/0.005)
FloattoStr(pot1, txt) ' convert its value to string
UART1_Write_Text(txt)
UART1_Write_Text(" ")
pot2 = (((ADC1_Get_Sample(1)/4095.0)*3.30)/0.005)
FloattoStr(pot2, txt) ' convert its value to string
UART1_Write_Text(txt)
UART1_Write(0x0A)
UART1_Write(0x0D)
Delay_ms(500)
wend
end.
Any ideas? All other ADC channels work OK.
Code: Select all
program stuff
' V2.3
include ECAN_Defs ' needed for ECAN
const ID_1st as longint = 1 ' Product ID for ECAN - CAN ID
const ID_2nd as longint = 1 ' node ID for filter
const LEDLooptime = 250 ' Time in mills on how often you want the CA LED tro bink / debug
const SendLooptime = 50 ' how often the data will be sent out
const SerialLooptime = 2000
const PIDLooptime = 1000 ' how often the PID loop will run
const Tempsetfilter = 250.0 ' Temp the PID loop will reach
const Tempsetsensor = 350.0 ' Temp the PID loop will reach
const kp = 60 ' PID values
const ki = 0.02
const kd = 1
const kps = 30 ' PID values
const kis = 0.02
const kds = 1
dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags as word ' can flags
Rx_Data_Len as word ' received data length in bytes
RxTx_Data as byte[8] ' can rx/tx data buffer
Msg_Rcvd as word ' reception flag
Rx_ID as longint
count as word ' Program time counter
count2 as word ' Duty cycle time counter
dutycount as integer ' counter to convert 1 mill to 10 mils for duty cycle
prevcount as word ' this holds prev counter value for led function
prevcount1 as word ' this holds prev counter value for CAN function
prevcount2 as word ' this holds prev counter value for PID function
prevcount3 as word
last as word ' this holds lst value for duty cycle
last2 as word ' this holds lst value for duty cycle
PID1o as float ' PID output - filter
PID2o as float ' PID output - sensor
TC_1 as float [6] ' analog vlaue aray for TC
TC_2 as float [6]
Crnt_1 as integer [6] ' analog vlaue aray for current
Crnt_2 as integer [6]
i as byte
errorf as float
errors as float
intigf as float
intigs as float
derivf as float
derivs as float
prev_errorf as float
prev_errors as float
hold as byte
hold2 as byte
txt as char [23] ' debug converson aray
sub procedure C1Interrupt() org 0x005A ' ECAN event iterrupt
IFS2.C1IF = 0 ' clear ECAN interrupt flag
if(C1INTF.TBIF <> 0) then ' was it tx interrupt?
C1INTF.TBIF = 0 ' if yes clear tx interrupt flag
end if
if(C1INTF.RBIF <> 0) then ' was it rx interrupt?
C1INTF.RBIF = 0 ' if yes clear rx interrupt flag
end if
end sub
' This sets up the clocks for the duty cycle and program timing!!!!!!
sub procedure Timer1Int org $1A ' Timer1 address in the interrupt table
count = count + 1 ' clock for program
dutycount = dutycount + 1 '
if dutycount >= 10 then ' converts 1ms timming to 10ms timming
count2 = count2 + 1 ' clock for duty cycle
dutycount = 0
end if
'PortB.8 = NOT PortB.8 ' clock time check
IFS0 = IFS0 and $FFF7 ' Interrupt flag reset
end sub
sub function TC1() as float ' Read TC 1 Sensor first one to edge
TC_1[0] = TC_1[1] ' Box car avg.
TC_1[1] = TC_1[2]
TC_1[2] = TC_1[3]
TC_1[3] = TC_1[4]
TC_1[4] = ADC1_Get_Sample(1)
TC_1[5] = (TC_1[0] + TC_1[1] + TC_1[2] + TC_1[3] + TC_1[4] )/5
result = (3.3*(TC_1[5])/4095.0)/0.005 ' calculate temp.
end sub
sub function TC2() as float ' Read TC 2 Sensor cosest to pic
TC_2[0] = TC_2[1] ' Box car avg.
TC_2[1] = TC_2[2]
TC_2[2] = TC_2[3]
TC_2[3] = TC_2[4]
TC_2[4] = ADC1_Get_Sample(0)
TC_2[5] = (TC_2[0] + TC_2[1] + TC_2[2] + TC_2[3] + TC_2[4] )/5
result = (3.3*(TC_2[5])/4095.0)/0.005 ' calculate temp.
end sub
sub function Current1() as float ' Read Current sensor
Crnt_1[0] = Crnt_1[1]
Crnt_1[1] = Crnt_1[2]
Crnt_1[2] = Crnt_1[3]
Crnt_1[3] = Crnt_1[4]
Crnt_1[4] = ADC1_Get_Sample(6)
Crnt_1[5] = (Crnt_1[0] + Crnt_1[1] + Crnt_1[2] + Crnt_1[3] + Crnt_1[4] )/5
result = (3.3*(Crnt_1[5])/4095.0)-0.7 ' calculate current for heater 1
end sub
sub function Current2() as float ' Read Current sensor
Crnt_2[0] = Crnt_2[1]
Crnt_2[1] = Crnt_2[2]
Crnt_2[2] = Crnt_2[3]
Crnt_2[3] = Crnt_2[4]
Crnt_2[4] = ADC1_Get_Sample(6)
Crnt_2[5] = (Crnt_2[0] + Crnt_2[1] + Crnt_2[2] + Crnt_2[3] + Crnt_2[4] )/5
result = (3.3*(Crnt_2[5])/4095.0)-0.7 ' calculate current for heater 2
end sub
main:
Unlock_IOLOCK()
PPS_Mapping_NoLock(24, _INPUT, _CIRX) ' Sets pin 4 of PIC as CAN RX input
PPS_Mapping_NoLock(25, _OUTPUT, _C1TX) ' Sets pin 5 of PIC as CAN TX output
PPS_Mapping_NoLock(22, _INPUT, _U1RX) ' Sets pin 2 of PIC as RS232 RX input
PPS_Mapping_NoLock(23, _OUTPUT, _U1TX) ' Sets pin 3 of PIC as RS232 TX output
Lock_IOLOCK()
' Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; ((25MHz/5)*14) = 40MHz
' refer the pic33 family datasheet for more details
CLKDIV = CLKDIV and 0xFFE5 ' CLKDIVbits.PLLPRE = 5
PLLFBD = 12 ' PLLFBDbits.PLLDIV = 14-2
IPC0 = IPC0 or $1000 ' Priority level is 1
IEC0 = IEC0 or $0008 ' Timer1 interrupt enabled
PR1 = 84 ' Interrupt period is 1000 clocks
T1CON = $8030 ' Timer1 enabled (internal clock divided by 256)
' Clear Interrupt Flags
IFS0 = 0
IFS1 = 0
IFS2 = 0
IFS3 = 0
IFS4 = 0
' Enable ECAN1 Interrupt
IEC2.C1IE = 1 ' enable ECAN1 interrupts
C1INTE.TBIE = 1 ' enable ECAN1 tx interrupt
C1INTE.RBIE = 1 ' enable ECAN1 rx interrupt
PORTB = 0 ' clear PORTB
TRISB = 0 ' set PORTB as output,
TRISB.10 = 0
TRISB.11 = 0
TRISC.4 = 1
TRISC.3 = 1
Can_Init_Flags = 0 '
Can_Send_Flags = 0 ' clear flags
Can_Rcv_Flags = 0 '
Can_Send_Flags = _ECAN_TX_PRIORITY_0 and ' form value to be used
_ECAN_TX_XTD_FRAME and ' with CANSendMessage
_ECAN_TX_NO_RTR_FRAME
Can_Init_Flags = _ECAN_CONFIG_SAMPLE_ONCE and ' form value to be used
_ECAN_CONFIG_PHSEG2_PRG_ON and ' with CANInitialize
_ECAN_CONFIG_XTD_MSG and
_ECAN_CONFIG_MATCH_MSG_TYPE and
_ECAN_CONFIG_LINE_FILTER_OFF
RxTx_Data[0] = 9 ' set initial data to be sent
ECAN1DmaChannelInit(0, 1, @ECAN1RxTxRAMBuffer) ' init dma channel 0 for
' dma to ECAN peripheral transfer
ECAN1DmaChannelInit(2, 0, @ECAN1RxTxRAMBuffer) ' init dma channel 2 for
' ECAN peripheral to dma transfer
ECAN1Initialize(1, 2, 7, 6, 8, Can_Init_Flags) ' initialize ECAN
ECAN1SetBufferSize(ECAN1RAMBUFFERSIZE) ' set number of rx+tx buffers in DMA RAM
ECAN1SelectTxBuffers(0x000F) ' select transmit buffers
' 0x000F = buffers 0:3 are transmit buffers
ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode
' set all mask1 bits to ones
ECAN1SetMask(_ECAN_MASK_0, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG)
' set all mask2 bits to ones
ECAN1SetMask(_ECAN_MASK_1, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG)
' set all mask3 bits to ones
ECAN1SetMask(_ECAN_MASK_2, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG)
' set id of filter10 to 2nd node ID
' assign mask2 to filter10
' assign buffer7 to filter10
ECAN1SetFilter(_ECAN_FILTER_10, ID_2nd, _ECAN_MASK_2, _ECAN_RX_BUFFER_7, _ECAN_CONFIG_XTD_MSG)
ECAN1SetOperationMode(_ECAN_MODE_NORMAL, 0xFF) ' set NORMAL mode
count = 0
count2 = 0
dutycount = 0
last = 0
last2 = 0
errorf = 0
intigf = 0
errors = 0
intigs = 0
derivs = 0
derivf = 0
intigf = 0.0
intigf = 1.0
ADC1_Init_Advanced(_ADC_12bit, _ADC_INTERNAL_REF) ' Setup ADC setup for 12 bit - internal ref
UART1_Init(9600) ' Initialize UART module at 19200 bps
Delay_ms(100) ' Stabilize UART
UART1_Write(0x0D)
UART1_Write_Text("OK ") ' check uart
while TRUE ' endless loop
if (count - prevcount > LEDLooptime) then ' Rtn 1 - LED blink / debug
prevcount = count
PortB.8 = NOT PortB.8
end if
if (count - prevcount1 > SendLooptime) then ' Rtn 2 - send loop
prevcount1 = count
ECAN1Write(ID_1st, RxTx_Data, 8, Can_Send_Flags) ' send data over CAN!
end if
if (count - prevcount3 > SerialLooptime) then ' Rtn 2 - Serial loop
prevcount3 = count
UART1_Write_Text(" Tc1: ")
floatToStr(TC1(), txt)
for i = 0 to 4 step 1
UART1_Write(txt[i])
next i
UART1_Write_Text(" PID 1: Out: ")
floatToStr(PID1o, txt)
for i = 0 to 6 step 1
UART1_Write(txt[i])
next i
UART1_Write_Text(" Tc2: ")
floatToStr(TC2(), txt)
for i = 0 to 4 step 1
UART1_Write(txt[i])
next i
UART1_Write_Text(" PID 2: Out: ")
floatToStr(PID2o, txt)
for i = 0 to 6 step 1
UART1_Write(txt[i])
next i
UART1_Write(0x0A)
UART1_Write(0x0D)
end if
if (count - prevcount2 > PIDLooptime) then ' Rtn 3 - PID loop 2
prevcount2 = count
'PID1o = 0
errorf = TempSetfilter - TC1()
intigf = intigf + (errorf*(PIDLooptime)/1000)
'derivf = (errorf - prev_errorf)/PIDLooptime
PID1o = PID1o + (kp*errorf) '+ (ki*intigf) '+ (kd*derivf)
'prev_errorf = errorf
if PID1o > 100.0 then
PID1o = 100
end if
if PID1o < 0.0 then
PID1o = 0.0
end if
'PID2o = 0
errors = Tempsetsensor - TC2()
intigs = intigs + (errors*(PIDLooptime)/1000)
'derivs = (errors - prev_errors)/PIDLooptime
PID2o = PID2o + (kps*errors) '+ (kis*intigs) '+ (kds*derivs)
'prev_errors = errors
if PID2o < 0.0 then
PID2o = 0.0
end if
if PID2o > 100.0 then
PID2o = 100.0
end if
end if
if(count2 - Last >= 100) then ' H1 Duty cycle
PORTB.10 = 1
Last = count2
end if
if(count2 - Last2 >= 100) then ' H2 Duty cycle
PORTB.11 = 1
Last2 = count2
end if
if(count2 - Last >= PID1o) then
PORTB.10 = 0
end if
if(count2 - Last2 >= PID2o) then
PORTB.11 = 0
end if
' format data to be sent over CAN / RS232 etc.
RxTx_Data[0] = 0xF1
RxTx_Data[1] = 0xF2
RxTx_Data[2] = 0xF3
RxTx_Data[3] = 0xF4
RxTx_Data[4] = 0
RxTx_Data[5] = 0
RxTx_Data[6] = 0
RxTx_Data[7] = 0
wend
end.