|
|
View previous topic :: View next topic |
Author |
Message |
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
PIC18F4550 & HTF3223 |
Posted: Sun Jul 07, 2013 6:42 am |
|
|
Hello everyone,
It's my first topic in the forum. I have a problem with communication between my PIC18f4550 and the sensor HTF3223. I use the example program by PICC after I made some changes, but my microcontroller doesn't read the frequency from the sensor.
The sensor is ok. I measured the frequency and the measurements were normal. Can anyone help me??? Below i have the program that i have created.
EX_HUMDITY.C:
Code: |
/////////////////////////////////////////////////////////////////////////
//// EX_HUMIDITY.C ////
//// ////
//// This program displays the relative humity, in percent (RH%), ////
//// read by a Humirel HT3223/HTF3223 Humidity Module. ////
//// ////
//// Configure the CCS prototype card as follows: ////
//// Insert jumpers from output of POT to pin A0 ////
//// ////
//// This example will work with the PCM and PCH compilers. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for each compiler. Change the device, clock and ////
//// RS232 pins for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2005 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#if defined(__PCM__)
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#elif defined(__PCH__)
#include <main.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
#include <ht3223.c>
void main(void) {
int8 rh;
printf("\r\n\nRelative Humidity:\r\n");
humidity_init();
enable_interrupts(TRUE);
while (!humidity_ready()) {}
while(TRUE) {
humidity_read();
printf("\r\n%U%%",rh);
delay_ms(1000);
}
}
|
main.h:
Code: |
#include <18F4550.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT32768 //Watch Dog Timer uses 1:128 Postscale
#FUSES HSPLL //High Speed Crystal/Resonator with PLL enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN ///PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL5 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV1 //System Clock by 2
#FUSES USBDIV //USB clock source comes from PLL divide by 2
#FUSES VREGEN //USB voltage regulator enabled
#FUSES ICPRT //ICPRT enabled
#FUSES WRTB
#FUSES NOICPRT
#FUSES LPT1OSC //NO
#FUSES CCP2B3
#FUSES NOCPB
#FUSES NOCPD
#FUSES NOWRTC
#FUSES NOWRTD
#FUSES NOEBTR
#FUSES NOEBTRB
/* systm clock is 48 MHz */
#use delay(clock=48000000,RESTART_WDT)
/* --- BEGIN: changes required for bootloader ------------------------------ */
/* ------------------------------------------------------------------------- */
/* map reset vector and interrupt vector */
/* 0x000-0x7FF is used by the bootloader. The bootloader maps the original */
/* reset vecotr (0x000) to 0x800 and the reset vector (0x008) to 0x800. */
/* ------------------------------------------------------------------------- */
#build (reset=0x800, interrupt=0x808)
/* ------------------------------------------------------------------------- */
/* reserve boot block area */
/* This memory range is used by the bootloader, so the application must not */
/* use this area. */
/* ------------------------------------------------------------------------- */
#org 0, 0x7FF {}
/* --- END: changes required for bootloader -------------------------------- */
|
HF3223.h:
Code: |
//////////////////////////////////////////////////////////////////////////////
//// ////
//// HT3223.C - Driver for Humirel HT3223/HTF3223 Humidity Module ////
//// ////
//// HT3223 has 3 pins: Power, Ground and Output. The Output pin is ////
//// a square wave with the frequency denoting the RH% (relative ////
//// humidty, in percent). ////
//// ////
//// The math equation is: Fout = 9740 - 18*RH ////
//// or: RH = (9740 - Fout)/18 ////
//// ////
//// Connect the HT3223 output pin to the CCP1 pin of the PIC. This ////
//// library will configure the CCP1 to act as a capture, and calculate ////
//// the frequency of Fout based upon the last two captures. ////
//// NOTE: Some PICs let you change the CCP1 timer to TIMER3. Do not ////
//// change this setting, leave the CCP1 timer to TIMER1. ////
//// ////
//////////////////////////////////////////////////////////////////////////////
//// ////
//// HT3223.C Functions: ////
//// ////
//// humidity_init() - Must be called before other humidity functions ////
//// are called. Configures the CCP1 and TIMER1, and ////
//// enables the CCP1 interrupt. ////
//// NOTE: You must enable global_interrupts() in your ////
//// application. ////
//// ////
//// humidity_read() - Returns the RH%, an int8 ranging from 0 to 100. ////
//// ////
//// humidity_ready() - The driver keeps the last 15 frequency counts in ////
//// memory. This function returns TRUE if we have read 15 ////
//// counts. If it returns FALSE wait a little bit longer. ////
//// ////
//////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2005 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
//////////////////////////////////////////////////////////////////////////////
#define HUMIDITY_NUM_SAMPLES 15
int16 humidity_samples[HUMIDITY_NUM_SAMPLES];
int8 humidity_sample_index=0;
int1 __humidity_ready=FALSE;
#define humidity_ready() __humidity_ready
void humidity_init(void) {
setup_ccp1(CCP_CAPTURE_FE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
}
int8 humidity_read(void) {
int8 i;
int8 num=0;
int32 freq;
int32 freq_sum=0;
int16 ticks;
for (i=0;i<HUMIDITY_NUM_SAMPLES;i++) {
freq=getenv("CLOCK")/4;
freq/=humidity_samples[i];
if ((freq < 9741) && (freq > 7800)) {
num++;
freq_sum+=freq;
}
}
if (num)
freq=freq_sum / num;
else
freq=9740;
i = ((9740 - freq) / 18);
return(i);
}
#define TickGetDiff(a, b) ((int16)(a < b) ? (((int16)0xffff - b) + a + 1) : (a - b))
#int_ccp1
void humidity_isr(void) {
static int8 first=1;
static int16 last;
if (!first) {
humidity_samples[humidity_sample_index++]=TickGetDiff(CCP_1,last);
if (humidity_sample_index >= HUMIDITY_NUM_SAMPLES) {
humidity_sample_index=0;
__humidity_ready=TRUE;
}
}
else
first=0;
last=CCP_1;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 07, 2013 10:34 am |
|
|
Quote: | void main(void) {
int8 rh;
printf("\r\n\nRelative Humidity:\r\n");
humidity_init();
enable_interrupts(TRUE);
|
'TRUE' is not a valid parameter for that function. Look at any CCS
example program that uses interrupts. Besides enabling the specific
interrupt, what parameter is used to globally enable interrupts ?
You can look at this one:
Quote: | c:\program files\picc\examples\ex_ccpmp.c |
|
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Sun Jul 07, 2013 11:13 am |
|
|
So, first i have to enable GLOBAL interrupts and then interrupts in CCP1, right??? But it didn't work again. My sensor has only one pin for the frequency. So, i connect only this pin to CCP1. Have i to connect the CCP2 to ground??? I 'm sorry that I can't understand the Interrupts. I am beginner with this function... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 07, 2013 12:32 pm |
|
|
I just realized that this code, is actually CCS code. For a while I thought
that you just copied the CCS copyright stuff into your own code. That's
because you said "the program that i have created".
But it's CCS code. This line is CCS's bug in ex_humidty.c:
Code: | enable_interrupts(TRUE); |
To me, that puts their whole driver into question.
I'll look at it some more, later this afternoon. I have to go out now. |
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Sun Jul 07, 2013 2:00 pm |
|
|
I 've changed the default example from CCS, so i can use my microcontroller. It is strange, but i don't know either many things about interrupts and that makes it more difficult to me. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 07, 2013 7:30 pm |
|
|
Try this program, which displays the frequency of the HTF3223 signal
that is connected to the CCP1 input (pin 17) of the 18F4550.
I don't have an HTF3223, so I used the CCP2 module in PWM mode to
generate a test signal of 9375 Hz. For testing I connected the CCP2
pin to the CCP1 pin with a jumper wire. I got this output on the
TeraTerm window from the program below.
Code: |
Start
9375 Hz
9375 Hz
9375 Hz
9375 Hz
9375 Hz
9375 Hz
9375 Hz
9375 Hz
9375 Hz
|
The program is correctly measuring the input frequency. I used 9375 Hz
as the test signal, because it corresponds to 20% humidity for the HTF3223.
It's a reasonable test value to use.
Run this program on your board, and see if you get a frequency in the
correct range for the humidity in your room:
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,BROWNOUT,PUT,PLL5,CPUDIV1
#use delay(clock=48M)
#use rs232(baud=9600, UART1, ERRORS)
// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
int16 isr_ccp_delta;
#int_ccp1
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;
// Read the 16-bit hardware CCP1 register
current_ccp = CCP_1; // From the PIC's .h file
// Calculate the time interval between the
// previous rising edge of the input waveform
// and the current rising edge. Put the result
// in a global variable, which can be read by
// code in main().
isr_ccp_delta = current_ccp - old_ccp;
// Save the current ccp value for the next pass.
old_ccp = current_ccp;
}
//=======================
void main()
{
int16 current_ccp_delta;
int16 frequency;
printf("Start \n\r");
/*
// This section of code below (3 lines) is for testing only.
// Do not use it with a real HT3223 chip.
// The CCP2 will be used in PWM mode to output a test
// signal that can be connected to the CCP1 pin.
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 79, 1); // 9.375 KHz PWM freq @ 48MHz osc
set_pwm2_duty(40); // 50% duty cycle on pin C1 (CCP2)
*/
// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from the CCP2 pin, which
// is connected to the CCP1 pin with a wire.
set_timer1(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp1(CCP_CAPTURE_RE);
// Clear the CCP1 interrupt flag before we enable
// CCP1 interrupts, so that we don't get an unwanted
// immediate interrupt (which might happen).
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
// Get a local copy of the latest ccp delta from the isr.
// We have to disable interrupts when we read a global
// isr variable that is larger than a single byte.
disable_interrupts(GLOBAL);
current_ccp_delta = isr_ccp_delta;
enable_interrupts(GLOBAL);
frequency = (int16)((12000000L + (current_ccp_delta >> 1)) / current_ccp_delta);
// Display the calculated frequency.
printf("%lu Hz\n\r", frequency);
delay_ms(500);
}
} |
|
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Mon Jul 08, 2013 2:59 pm |
|
|
Thanks a lot...
The program worked. I tried in the kitchen and the frequency is 8843Hz, so it has about 50% humidity according to the htf 3223 datasheet. The outside humidity according to the weather report, Koeln has 42% of humidity, so i believe that measure is correct. It may have a deflection from -5 to +5% but it is ok. I will study carefully the code and then, If i have any questions, I won't hesitate to make them. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|