ADC Channel 0 problem on dsPIC33FJ128GP804

Beta Testing discussion on mikroBasic PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
richcj10
Posts: 29
Joined: 15 Aug 2012 13:51

ADC Channel 0 problem on dsPIC33FJ128GP804

#1 Post by richcj10 » 09 Jan 2013 23:46

This code here works as expected on the ADC pins. this is for a analog T/C amplifier.

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.

This code dos not like the T/C amplifiers. ( same board / chip) ADC 0 is acting like it is being pulled low internally.
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.


User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: ADC Channel 0 problem on dsPIC33FJ128GP804

#2 Post by filip » 15 Jan 2013 14:17

Hi,

Please, can you isolate the issue by commenting out the blocks of code ?

Regards,
Filip.

Post Reply

Return to “mikroBasic PRO for dsPIC30/33 and PIC24 Beta Testing”