Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Temperature sensor with RS232 communication interface problem

Status
Not open for further replies.

Cantafford

Member
Hey,

I'm trying to simulate a temperature sensor connected to a PC via RS232 protocol controlled with a PIC18f2550 microcontroller.

The program is supposed to do the simple task of reading an analog value(the temperature) and display it on a virtual terminal when I press a button.

I wrote the following code:

Code:
/*
* File:   main.c
* Author: Paul
*
* Created on August 30, 2016, 11:34 AM
*/

#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#include <plib/usart.h>

void configureADC();
void configureUSART();

void main()
{
    OSCCON = 0x7F; // 8Mhz internal oscillator
    TRISCbits.RC0 = 1;
    configureADC();
    float temperature = 0;
    unsigned char buf[20];
    unsigned char Txdata1[] = "Temperature sensor with RS232 communication";
    unsigned char Txdata2[] = "Temperature is: ";
    configureUSART();

    while(BusyUSART()); //Check if Usart is busy or not
    putsUSART(Txdata2); //transmit the string2

    START:
      GODONE = 1; // start conversion
      for(int delay=0; delay<=10; delay++) __delay_ms(5);
      while(GODONE); // wait for conversion to finish
      temperature = (ADRES*5) / 1024; // 10 bit ADC(voltage reference 5V)
      sprintf(buf, "%.3g", temperature); // Convert temperature float value to string
      while(BusyUSART());
      putsUSART(buf);
  
    while(1) // when button is pressed display new temperature
    {
        if (PORTCbits.RC0 == 0)
        {
            for(int delay=0; delay<=30; delay++) __delay_ms(5);
            goto START;
        }
    }
}

void configureADC()
{
    TRISAbits.TRISA0 = 1;
    ADCON0 = 0x01; // channel 0 selected / enable ADC
    ADCON1 = 0x0E; // references selected
    ADCON2 = 0b10001000; // right justified,TAD, FOSC/2
}

void configureUSART()
{
    OpenUSART( USART_TX_INT_OFF &
    USART_RX_INT_OFF &
    USART_ASYNCH_MODE &
    USART_EIGHT_BIT &
    USART_CONT_RX &
    USART_BRGH_HIGH &
    USART_ADDEN_OFF,
    52);
}

And the header.h:
Code:
// PIC18F2550 Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = INTOSCIO_EC// Oscillator Selection bits (Internal oscillator, port function on RA6, EC used by USB (INTIO))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF      // MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

#define _XTAL_FREQ 8000000


This is the schematic:
10gyyq1.png


I have the following problem: The temperature is displayed as a binary value not as a decimal one. For temperature range: 1-100 it displays 0 and for temperature 100-150 it displays 1 on the virtual terminal. Please help me correct this issue. Thank you.

Also: I would like to delete one character from the terminal's screen. In my case the temperature value(not clear the entire screen just delete something as if I would do with backspace on a keyboard). Is that possible? Is there such a command?

Thank you for reading.
 
Hi Canafford,
Here is a design to convert the output from a DH22 temperature and humidity sensor to a serial string. It uses a PIC12F1822 but it should not be too difficult to modify it to run on your PIC182550.
Here is the schematic. You would need to add a level converter to feed it into a real serial port. It could also feed directly into a serial to USB converter. I have used it with a pair of HC-12 RF serial link modules.
DHT22 reader.png

Here is the code.
Code:
;   This is for reading the output from a DH22 temp / humidity sensor and outputing data as serial data.
;******************************************************************************************

;

;******************************************************************************************
;
;  OSC  : Internal OSC 4 MHz
;
;******************************************************************************************
  LIST  P=PIC12F1822,ST=OFF,R=DEC
  INCLUDE  "P12F1822.inc"

  __CONFIG _CONFIG1,  _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF &  _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF


  __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_HI & _LVP_OFF

;*******************************************************************************
; Constants
;*******************************************************************************


RAM_START  equ  0x20


; The periods are timed with timer1 which is set to run at the internal clock
; rate (4 Mhz) of Fosc/4 or 1.0MHz which is equal to a 1 uS period.




DELAY_18MS   equ   D'2993'    ;Value to give delay of 6 mS

;*******************************************************************************
; Pin Assignments
;*******************************************************************************
;
;   PIC signals
;
   #DEFINE     TX_Data     PORTA, 0     ;
   #DEFINE     RX_Data     PORTA, 1     ;
;
   #DEFINE     DHT22_Pin   PORTA, 2     ;
   #DEFINE     Button     PORTA, 3     ; Push button to trigger a DHT22 read


; I/O pin use
;   RA0   TX      (Pin 7)  (To pin 4 on programmer connection)
;   RA1   RX      (Pin 6)  (To pin 5 on programmer connection)
;   RA2   DHR22 data       (Pin 5)
;   RA3   Trigger button     (Pin 4)   NOTE THIS PIN CAN ONLY BE USED AS AN INPUT.  Use for push button to trigger a read of the DHT22
;            (This is VPP for programming This could be connected to pin 3 or 5 of the header to program the chip on header.)
;   RA4   Not used       (Pin 3)
;   RA5       (Pin 2)




;  Define GENERAL PURPOSE RAM AREA (80 bytes maximum)

;*******************************************************************************
; File Register Variables
;*******************************************************************************
  cblock  RAM_START

param1:   1  ; parameter 1  (Used in delay cycles routine)
param2:   1  ; parameter 2  (Used in delay cycles routine)
Temp_1:   1     ;Used in 2 second delay

tmpData:   1     ; Used in output_hexbyte routine

; delay counters
Del_Count:  1
   
DHT_Data0:   1  ; 40 bit value from DHT  (Most significant byte)
DHT_Data1:   1   ; 0 & 1 Humidity
DHT_Data2:   1   ; 2 & 3 Temperature Bit 7 of byte 2 is sign bit (Set for negative.)
DHT_Data3:   1
DHT_Data4:   1   ; Byte 4 is the checksum

; bit counter
  bitcnt:  1
; byte counter
  bytcnt:  1

ESEVN:   1     ; 10 000,000 (digit 8)
ESIX:   1     ; 1000,000s (digit 7 )
EFIVE:   1     ; 100,000s digit 6 store
EFOUR:   1     ; 10,000s digit 5 store
ETHREE:   1     ; 1000s digit 4 store (kHz)
ETWO:   1     ; 100s digit 3 store
EONE:   1     ; 10s digit 2 store
EZERO:   1     ; 1's digit 1 store (Hz)



COUNT:   1

BCD1:   1     ; overrange
BCD2:   1     ; MS decimal value
BCD3:   1     ;
BCD4:   1     ; decimal value
BCD5:   1     ; ls decimal value
   
BIN1:   1     ; LS binary value
BIN2:   1     ;
BIN3:   1     ;
BIN4:   1     ; MS binary value

TEMP:   1


  endc
;*******************************************************************************
; Common RAM (0x70 to 0x7F)
;*******************************************************************************

TX_temp     EQU 0x70     ;Temporary storage for character to be transmitted.

;*******************************************************************************
;  Define Macro  Takes 2 uS
;*******************************************************************************
SELBANK MACRO  #BANK_NO
  MOVLW  #BANK_NO   ;1 cycle - 1 uS
  MOVWF  BSR     ;1 cycle - 1 uS
  ENDM


; *****************************

  ORG  0h
  GOTO  START
  ORG  4h
  GOTO  START
START
; *****************************
;  Initialized Segment
; *****************************
; Initialise OSC (4MHz, IntOSC)
  SELBANK 1  ; SET BANK1
  MOVLW  B'11101010'   
  MOVWF  OSCCON

   BCF   INTCON,GIE

; Initialise I/O port
  SELBANK 1  ; SET BANK1
  MOVLW  B'00011010'     ; Bits 0, output Bit 1, 3, 4 input. Bit 2 Initialy an output but changed during DHT data read.
  MOVWF  TRISA

;Set pullup on PORTA,3

   BCF   OPTION_REG,NOT_WPUEN

   MOVLW   B'00001000'
   MOVWF   WPUA

     SELBANK 3  ; SET BANK 3
   MOVLW   0x00
   MOVWF   ANSELA     ; All I/O set to digital

     SELBANK 2  ; SET BANK2
   MOVLW   B'00000000'
   MOVWF   APFCON

; Initialized Comparitor.
     MOVLW  B'00000000'     ; Comparator disabled.
   MOVWF   CM1CON0       ;In bank 2
     SELBANK 0  ; SET BANK0

   CLRF   PORTA     ;Set all outputs low
   BSF   DHT22_Pin   ;Initial condition high


; Initialized EUSART
     SELBANK 3  ; SET BANK 3
   MOVLW   B'00000000'
   MOVWF   BAUDCON

   BSF   TXSTA,BRGH   ; Set baud rate high bit
     BSF  TXSTA,TXEN  ;enable transmission  

   MOVLW   0x19     ; Decimal 25 for 9600 baud rate
   MOVWF   SPBRGL
   MOVLW   0x00
   MOVWF   SPBRGH

   BSF  RCSTA,SPEN  ;enable serial port

     SELBANK 0  ; SET BANK0

; Initialized Timer 1
     SELBANK 0  ; SET BANK0

   MOVLW   B'00010100'   ;Clock source FOSC, 1:2 prescale, Dedicated Timer1 oscillator circuit disabled,
  ;Do not synchronize external clock input, Timer off

   MOVWF   T1CON     ;With 4 Mhz clock timer will increment every 500 nS

   MOVLW   0x00     ;All bits clear (Gate control not used.)
   MOVWF   T1GCON



; *****************************
;  Program main
; *****************************
; Main loop

   CALL Delay_2_Sec

Wait_Pressed:
   BTFSC   PORTA,3     ; Trigger button
   GOTO   Wait_Pressed
   CALL    Delay_100mS
   BTFSC   PORTA,3     ;Still pressed ?
   GOTO   Wait_Pressed

Wait_released:
   BTFSS   PORTA,3     ;
   GOTO   Wait_released

MAIN:

   CALL   Read_DHT

   CALL   send_data     ;Output in raw HEX format

   MOVLW   0x0D     ;C/R
   CALL   SerialTransmit

   MOVLW   0x0A     ;L/F
   CALL   SerialTransmit

   CALL   Output_Decimal     ;Output in decimal

   MOVLW   0x0D     ;C/R
   CALL   SerialTransmit

   MOVLW   0x0A     ;L/F
   CALL   SerialTransmit

   CALL Delay_2_Sec

   GOTO   Wait_Pressed
;     --------------------------------------------------------------------------------------


; *****************************
;  Subroutines
; *****************************
           
;*****************************************************************************   
;
;  Function :  SerialTransmit
;  This function sends the byte in W over the RS232 port. The
;  function will wait until previous data has been sent
;
;  Input:  Byte in W
;
;  Output:   
;
;*****************************************************************************   
SerialTransmit:
   MOVWF   TX_temp
     btfss  PIR1,TXIF  ;check that buffer is empty
     goto  $-1
     SELBANK 3  ; SET BANK 3
   MOVF   TX_temp,W   
     movwf  TXREG  ;transmit byte
     SELBANK 0  ; SET BANK 0
     return
;*****************************************************************************   
;*Read DHT22
;* Result in DHT_Data  (5 bytes.)
;*
;*****************************************************************************  
;
   
Read_DHT:

; make data pin  output

     SELBANK 1  ; SET BANK 1     2 uS
   BCF   TRISA,2     ; Set DHT_Pin as output  1 uS
     SELBANK 0  ; SET BANK 0     2 uS

   BCF   DHT22_Pin       ; set it low for 18ms

; delay 18 ms
  movlw  LOW DELAY_18MS  ; Delay for 18 milliseconds  Normal value used
  movwf  param1  ;
  movlw  HIGH DELAY_18MS     ;  Normal value used
  movwf  param2  ;
  call  delay_cycles  ;


; Set data line high for 30 us
   BSF   DHT22_Pin       ;

; delay for 30 us
   movlw 0x09       ; 1 uS
   movwf Del_Count       ; 1 uS
Del_30us
   decfsz Del_Count, f     ; 1 uS while looping, 2 uS on exit
   goto Del_30us       ; 2 uS
   NOP

; Init bit counter
     MOVLW  D'40'
     MOVWF  bitcnt



; DHT22 now outputs data
; set data line for input
; Wait until it is low

     SELBANK 1  ; SET BANK 1     2 uS
   BSF   TRISA,2     ; Set DHT_Pin as input  1 uS
     SELBANK 0  ; SET BANK 0     2 uS

wait_responce_low:
     btfsc  DHT22_Pin  ; skip next inst if it is already low
     goto  wait_responce_low


; the DHT should next set the data line high for 80us
wait_responce_high
     btfss  DHT22_Pin
     goto  wait_responce_high


; now wait for it to go low again, marking the begining of the start bit
wait_bit_start:
     btfsc  DHT22_Pin
     goto  wait_bit_start
; start of bit -  50us low on the data line followed
; by 26-28 us high if is a "0" or a 70 us high if is a "1"
; So half way between is 49 uS

start_bit
; wait for the start bit to end
wait_high
     btfss  DHT22_Pin
     goto  wait_high

; delay for 49 us
   movlw 0x09     ; (1uS)                 1 uS
   movwf Del_Count     ;(1uS)                 2 uS
     bcf  STATUS, C   ;(1uS)   Set to 1 initially           3 uS

Del_49us:
   decfsz Del_Count, f   ;(1uS) (2 uS on skip)             4 uS  (Loop is 5 uS)
   goto No_timeout     ;(2 uS)                 6 uS
     bsf  STATUS, C   ; More than 40 uS have elapsed so clear carry bit. (1 uS)
No_timeout:
; Has data line gone low ? (End of bit.)

     btfsc  DHT22_Pin   ;(1uS) (2 uS on skip) Test for end of bit       7 uS
   goto    Del_49us     ;(2 uS)               9 uS


;Shift carry bit into Bit 0  (We have 50 uS before start of next bit)
Shift_bit:
   RLF   DHT_Data4
   RLF   DHT_Data3
   RLF   DHT_Data2
   RLF   DHT_Data1
   RLF   DHT_Data0

dec_bit
     decfsz  bitcnt,f
     goto  wait_high    ;For next bit of frame.

Frame_End:
   RETURN

;     -----------------------------------------------------------------------------

;Output the data in HEX format
send_data:
; initialize the FSR0
     movlw  DHT_Data0
     movwf  FSR0L
   CLRF   FSR0H
; set byte counter
     movlw  0x5
     movwf  bytcnt

sendloop:
     movf  INDF0,w  ; get a byte of data

   CALL   output_hexbyte
; point to the next byte
     incf  FSR0L
     decfsz  bytcnt,f
     goto  sendloop
; All 5 bytes of data outputted
   RETURN
;

;*****************************************************************************   
;
;  Function :  output_hexbyte
;  Outputs the byte W to serial port
;  Input:  data in W
;
;  Output:  Data displayed
;
;*****************************************************************************   
output_hexbyte:
   MOVWF   tmpData
     swapf  tmpData,W
     sublw  0x09
     swapf  tmpData,W
     andlw  0x0F
     btfss  STATUS,DC
     addlw  'A' - .10 - '0'
     addlw  '0'
     call  SerialTransmit
     movfw  tmpData
     sublw  0x09
     movfw  tmpData
     andlw  0x0F
     btfss  STATUS,DC
     addlw  'A' - .10 - '0'
     addlw  '0'
     call  SerialTransmit
     return


Delay_100mS:
   MOVLW   0xC3
   MOVWF   param2
   MOVLW   0x49
   MOVWF   param1
   GOTO   delay_cycles
   
Delay_2_Sec:
   MOVLW   D'20'
   MOVWF   Temp_1
D2_Loop:
   CALL   Delay_100mS
   DECFSZ   Temp_1
   GOTO   D2_Loop
   RETURN

;*******************************************************************************
; Function:  delay_cycles
; Description: Delay a specified number of instruction cycles including
;  interrupt cycles.  The function call overhead adds between
;  13 and 16 cycles of delay on top of the specified value.
; With 4 Mhz system clock and 1:2 prescale
;Delay will be  param * 2 uS + (13 * 1uS)  + 0 to 3 uS
;     = param * 2 uS + (13 to16.0 uS)  (Use 14 uS for calculation.)
;  So param = No. of uS/2 - 7
; Parameters:  param1 - least significant byte of 16 bit cycle delay
;  param2 - most significant byte of 16 bit cycle delay
; Returns:  None
;*******************************************************************************
delay_cycles:
  comf  param1,F  ; negate the delay by complementing the     (1 uS)    (1 cycle)
  comf  param2,F  ; low and high bytes         (1 uS)    (1 cycle)
  bcf  T1CON,TMR1ON  ; stop timer 1           (1 uS)    (1 cycle)
  movf  param1,W  ; move the low byte of the delay into     (1 uS)    (1 cycle)
  movwf  TMR1L  ; timer 1           (1 uS)    (1 cycle)
  movf  param2,W  ; move the high byte of the delay into     (1 uS)    (1 cycle)
  movwf  TMR1H  ; timer 1           (1 uS)    (1 cycle)
  bcf  PIR1,TMR1IF  ; clear the timer 1 rollover flag     (1 uS)    (1 cycle)
  bsf  T1CON,TMR1ON  ; turn on timer 1         (1 uS)    (1 cycle)
   
tmr1_check:   
  btfss  PIR1,TMR1IF  ; wait for the timer 1 rollover flag to     1 uS while looping    (2 uS) (2 cycle) on exit
  goto  tmr1_check  ; trigger
  return         ;             (2 uS)   (2 cycle)

;**********************************************************************************
; Subroutine BCD (to convert 28-bit binary to 8-digit BCD)
; Binary value is in BIN1, BIN2, BIN3 & BIN4. BIN1 is LSB, BIN4 is MSB
; Result in BCD is in BCD1, BCD2, BCD3, BCD4 & BCD5. BCD1 is for overrange,
; BCD2 is MSB, BCD5 is LSB
;**********************************************************************************

BIN_BCD:   
   bcf   STATUS,C   ; clear carry bit
   movlw   D'32'
   movwf   COUNT     ; 32 in count
   clrf   BCD1     ; set BCD registers to 0
   clrf   BCD2
   clrf   BCD3
   clrf   BCD4
   clrf   BCD5

LOOPBCD:
   rlf   BIN1,f     ; LSB shift left binary registers
   rlf   BIN2,f
   rlf    BIN3,f
   rlf   BIN4,f     ; MSB
   rlf   BCD5,f     ; LSB shift left BCD registers
   rlf   BCD4,f
   rlf   BCD3,f
   rlf   BCD2,f
   rlf   BCD1,f     ; MSB

   decfsz   COUNT,f     ; reduce count value return when 0
   goto   DECADJ     ; continue decimal adjust
   
; result in BCD1-5. (BCD1 overrange, BCD2 MS byte)

   swapf   BCD2,w     ; get ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   ESEVN     ; ms digit
   movf   BCD2,w     ; get 2nd ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   ESIX

   swapf   BCD3,w     ; get next nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   EFIVE     ; ms digit
   movf   BCD3,w     ; get next nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   EFOUR
   
   swapf   BCD4,w     ; get ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   ETHREE     ; ms digit
   movf   BCD4,w     ; get 2nd ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   ETWO

   swapf   BCD5,w     ; get ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   EONE     ; ms digit
   movf   BCD5,w     ; get 2nd ms nibble
   andlw   0x0F
   iorlw   0x30     ; convert to ASCII
   movwf   EZERO
   return       ; completed decimal to BCD operation

; subroutine decimal adjust

DECADJ   movlw   BCD5     ; BCD LSB address
   movwf   FSR1L     ; pointer for BCD5
   CLRF   FSR1H
   call   ADJBCD     ; subroutine to adjust BCD
   movlw   BCD4
   movwf   FSR1L
   CLRF   FSR1H
   call    ADJBCD
   movlw   BCD3
   movwf   FSR1L
   CLRF   FSR1H
   call    ADJBCD
   movlw   BCD2
   movwf   FSR1L
   CLRF   FSR1H
   call    ADJBCD
   movlw   BCD1
   movwf   FSR1L
   CLRF   FSR1H
   call    ADJBCD
   goto   LOOPBCD

; subroutine adjust BCD

ADJBCD   movlw   0x03     ; w has 03
   addwf   INDF1,w     ; add 03 to BCDx register (x is 1-5)
   movwf   TEMP     ; store w
   btfsc   TEMP,3     ; test if >7
   movwf   INDF1     ; save as LS digit
   movlw   0x30     ; 3 for MSbyte
   addwf   INDF1,w     ; add 30 to BCDx register
   movwf   TEMP     ; store w
   btfsc   TEMP,7     ; test if >7
   movwf   INDF1     ; save as MS digit
   return       ; end subroutine



;**********************************************************************************
;
;
Output_Decimal:

   CLRF   BIN4     ;Clear top 3 bytes (Not used.)
   CLRF   BIN3
   CLRF   BIN2
   
   MOVF   DHT_Data0,W   ;Humidity high byte
   MOVWF   BIN2   

   MOVF   DHT_Data1,W   ;Humidity low byte
   MOVWF   BIN1   

   CALL   BIN_BCD

Output_Humidity:
   MOVLW   'H'
     CALL  SerialTransmit

   MOVLW   ' '
     CALL  SerialTransmit
   

   MOVF   ETWO, W
     CALL  SerialTransmit

   MOVF   EONE, W
     CALL  SerialTransmit

   MOVLW   '.'
     CALL  SerialTransmit

   MOVF   EZERO, W
     CALL  SerialTransmit

   MOVLW   '%'
     CALL  SerialTransmit

   MOVLW   ' '
     CALL  SerialTransmit

Output_Temp:

   CLRF   BIN4     ;Clear top 2 bytes (Not used.)
   CLRF   BIN3
   CLRF   BIN2
   
   MOVF   DHT_Data2,W   ;Temp high byte
   MOVWF   BIN2   

   MOVF   DHT_Data3,W   ;Temp low byte
   MOVWF   BIN1   

   CALL   BIN_BCD



   MOVLW   'T'
     CALL  SerialTransmit
   MOVLW   'e'
     CALL  SerialTransmit
   MOVLW   'm'
     CALL  SerialTransmit
   MOVLW   'p'
     CALL  SerialTransmit
   MOVLW   ' '
     CALL  SerialTransmit
   MOVLW   '+'
   
   BTFSC   DHT_Data2,7     ;Test sign bit
   MOVLW   '-'

     CALL  SerialTransmit

   MOVF   ETWO, W
     CALL  SerialTransmit

   MOVF   EONE, W
     CALL  SerialTransmit

   MOVLW   '.'
     CALL  SerialTransmit

   MOVF   EZERO, W
     CALL  SerialTransmit

   MOVLW   ' '
     CALL  SerialTransmit
   MOVLW   'C'
     CALL  SerialTransmit


   RETURN



   end

Les.
 
Hello Les Jones thank you for your answer. Unfortunately I'm very bad in assembly so I can't understand that code very well. I tried implementing in C by reading the comments next to the instructions but to no avail. I think the solution to my problem is a very simple one, something basic which I'm missing :(.
 
Hi Canafford,
I struggle to make any sense of "C" programs so I have no chance of working out what's wrong with your program. I can supply you with the hex file to program the PIC12F1822 if that is any help. (A PIC12F1822 is only £1.00 + VAT from Farnell.)

Les
 
I'd look at sprintf.... I don't think %g is available... It tells you to use %e or %f BUT!! I think there are additional parameters for %f -m and -n..

Page 383 of the XC8 documentation

I wouldn't use sprintf with floats as it takes most of your memory... I have a specific printFloat routine.

If you are struggling there is a basic ftoa() so. sprintf(buffer, "%s", ftoa(fpnumber, &stat));

The parameter stat is a pointer to an int... Any int just declare... int stat;
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top