ADGAN
Full Member level 5
- Joined
- Oct 9, 2013
- Messages
- 295
- Helped
- 4
- Reputation
- 8
- Reaction score
- 4
- Trophy points
- 18
- Activity points
- 1,837
Hello everybody! I want to count TMR1L and TMR1H value with timer1 interrupts to a single variable. So that I can know the total no of pulses. This is how I tried:
But when the timer1 overflow, the total no of pulses are displayed as 0. And also it seems to be that timer1 overflows. What is the mistake I have done? This is my source code.
Code:
Monthly_consumption = ((count*65535)+(TMR1H<<8 | TMR1L));
But when the timer1 overflow, the total no of pulses are displayed as 0. And also it seems to be that timer1 overflows. What is the mistake I have done? This is my source code.
Code:
#define Lo(param) ((char *)¶m)[0]
#define Hi(param) ((char *)¶m)[1]
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
unsigned char txt1[] = "ENERGY CONSUMPTION";
unsigned char txt2[] = "FROM";
unsigned char txt3[] = "TO";
unsigned char txt4[] = "20";
unsigned char txt5[] = "KWh";
unsigned char txt[14],txt6[14];
unsigned char SMS[14];
unsigned int count = 0; //No of tmr1 overflow interrupts
unsigned short count_low = 0,count_high = 0;
unsigned long monthly_consumption = 0; //Total no of pulses that accumulated for a month
double Meter_reading = 0; //Energy consumption in KWh
const double Meter_Constant = 1000; //Meter constant, indicates how many pulses required for a KWh
unsigned char *FloattoAscii (float x, unsigned char *str,char precision)
{
/* converts a floating point number to an ascii string */
/* x is stored into str, which should be at least 30 chars long */
unsigned char *adpt;
int ie, i, k, ndig;
double y;
adpt=str;
ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
ie = 0;
/* if x negative, write minus and reverse */
if ( x < 0)
{
*str++ = '-';
x = -x;
}
/* put x in range 1 <= x < 10 */
if (x > 0.0) while (x < 1.0)
{
x *= 10.0; // the place of = *
ie--;
}
while (x >= 10.0)
{
x = x/10.0; ie++;
}
// in f format, number of digits is related to size
ndig += ie; // the place of =+
//round. x is between 1 and 10 and ndig will be printed to
// right of decimal point so rounding is ...
for (y = i = 1; i < ndig; i++)
y = y/10.;
x += y/2.;
if (x >= 10.0) {x = 1.0; ie++;}
if (ie<0)
{
*str++ = '0'; *str++ = '.';
if (ndig < 0) ie = ie-ndig;
for (i = -1; i > ie; i--) *str++ = '0';
}
for (i=0; i < ndig; i++)
{
k = x;
*str++ = k + '0';
if (i == ie ) *str++ = '.';
x -= (y=k);
x *= 10.0;
}
*str = '\0';
return (adpt);
}
/**************************************************************************************************
* Interrupt service routine
**************************************************************************************************/
void interrupt(){
if (PIR1.TMR1IF == 1)
{
count++; //increment the count variable
PIR1.TMR1IF = 0; //Clear the TMR1 interrupt flag
T1CON.TMR1ON = 0;
TMR1L = 0;
TMR1H = 0;
T1CON.TMR1ON = 1;
}
}
/**************************************************************************************************
* Main function
**************************************************************************************************/
void main()
{
ANSEL = 0; //All ports are digital
ANSELH = 0; //
TRISA = 0; //PortA configured as output
PORTA = 0; //Reset port A
PORTA.RA0 = 1; //Switch ON the Power indicator LED
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
TRISB = 0; //PortB confgured as output
PORTB = 0; //Reset PORTB
PORTC = 0; //Reset PORTC
TRISC = 0x99;
INTCON = 0xC0; //Enable global and peripheral interrupts
PIE1.TMR1IE = 1; //Enable TMR1 interrupt
PIR1.TMR1IF = 0; //Clear the TMR1 interrupt flag
TMR1L = 0; //Reset TMR1L
TMR1H = 0; //Reset TMR1H
count = 0; //Reset
T1CON = 0x07; //Configure timer1 as an asynchronous counter
Lcd_Init(); //Initialize the LCD
Delay_ms(100); // Delay 100ms
Lcd_Cmd(_LCD_CURSOR_OFF); //Cursor off
Lcd_Cmd(_LCD_CLEAR); //Clear the LCD
I2C1_Init(100000); //Initialize I2C to 100KHz
LCD_Out(1,2,txt1);
LCD_Out(2,1,txt2);
LCD_Out(3,1,txt3);
LCD_Out(2,14,txt4);
LCD_Out(3,14,txt4);
LCD_Out(4,14,txt5);
UART1_Init(9600); //Initialize UART to 9600bps
Delay_ms (100); //Delay 100ms
T1CON.TMR1ON = 0; //Switch OFF TMR1
TMR1L = EEPROM_Read(0x00); //Write previous value to TMR1L
TMR1H = EEPROM_Read(0x01); //Write previous value to TMR1H
T1CON.TMR1ON = 1; //Switch ON TMR1
Lo(count) = EEPROM_Read(0x02); //Write previous value to count
Hi(count) = EEPROM_Read(0x03);
Delay_ms(20);
while(1){
Monthly_consumption = ((count*65535)+(TMR1H<<8 | TMR1L)); //Load TMR1 value and interrupt values to one variable
//Clear the energy consumptinon at the beginning of a new month
if((day == 1) && (hours == 0) && (minutes == 0) && (seconds == 4))
{
T1CON.TMR1ON = 0; //Switch OFF TMR1
TMR1L = 0; //Reset TMR1L register
TMR1H = 0; //Reset TMR1H register
T1CON.TMR1ON = 1; //Switch ON TMR1
Count = 0; //Reset count variable
Monthly_consumption = 0; //Reset monthly consumption variable
}
Meter_reading = Monthly_consumption/Meter_Constant; //Calculate KWh
FloattoAscii(Meter_reading,txt6,3);
Lcd_Out(4,7,txt6);
EEPROM_Write(0x00,TMR1L); //Write TMR1L value to EEPROM
EEPROM_Write(0x01,TMR1H); //Write TMR1H value to EEPROM
EEPROM_Write(0x02,Lo(count)); //Write count value to EEPROM
EEPROM_Write(0x03,Hi(count)); //
Delay_ms(20);
}
}