I have created what according to me is correct but doesn't behave like it should. I have tried to find the problem but was unable to detect it can you please help me here.
// // Co-operative multitasking framework tutorial code // (c)Russell Bull 2010. Free for any use. // Code built for a Mega168 @ 16MHz #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <stdio.h> #include "I2C_Master_H_file.h" //for rtc #include "lcd.h" //for the lcd #include "debounce.h" //for button debounce void init_devices(void); void timer_0_init(void); void reset_task(char tsk); void set_task(char tsk); void task_dispatch(void); void task0(void); void task1(void); void task2(void); void task3(void); void task4(void); void task5(void); void task6(void); void task7(void); //-------------------------------------------------------------------------------------------------------------- #define DS1307_WRITE_ADDR 0xD0 /* Define RTC DS1307 slave write address */ #define DS1307_READ_ADDR 0xD1 /* Make LSB bit high of slave address for read */ int second,minute,hour,day,date,month,year; //-------------------------------------------------------------------------------------------------------------- #define DEGREE_SYMBOL 0xdf //-------------------------------------------------------------------------------------------------------------- #define NUM_TASKS 8 char task_bits = 0; /* lsb is hi priority task */ volatile char tick_flag = 0; /* if non-zero, a tick has elapsed */ unsigned int task_timers[NUM_TASKS]={0,0,0,0,0,0,0,0}; /* init the timers to 0 on startup */ static const PROGMEM char bit_mask[]={1,2,4,8,16,32,64,128}; /* value -> bit mask xlate table */ //--------------------------------------------------------------------------------------------------------------- void RTC_Read_Clock(char read_clock_address) { I2C_Start(DS1307_WRITE_ADDR);/* Start I2C communication with RTC */ I2C_Write(read_clock_address); /* Write address to read */ I2C_Repeated_Start(DS1307_READ_ADDR);/* Repeated start with device read address */ second = I2C_Read_Ack(); /* Read second */ minute = I2C_Read_Ack(); /* Read minute */ hour = I2C_Read_Nack(); /* Read hour with Nack */ I2C_Stop(); /* Stop i2C communication */ } void RTC_Read_Calendar(char read_calendar_address) { I2C_Start(DS1307_WRITE_ADDR); I2C_Write(read_calendar_address); I2C_Repeated_Start(DS1307_READ_ADDR); day = I2C_Read_Ack(); /* Read day */ date = I2C_Read_Ack(); /* Read date */ month = I2C_Read_Ack(); /* Read month */ year = I2C_Read_Nack(); /* Read the year with Nack */ I2C_Stop(); /* Stop i2C communication */ } void ADC_Init(){ DDRA = 0x00; /* Make ADC port as input */ ADCSRA = 0x87; /* Enable ADC, with freq/128 */ ADMUX = 0x40; /* Vref: Avcc, ADC channel: 0 */ } int ADC_Read(char channel) { ADMUX = 0x40 | (channel & 0x07); /* set input channel to read */ ADCSRA |= (1<<ADSC); /* Start ADC conversion */ while ((ADCSRA & (1<<ADSC))); /* Wait until end of conversion by polling ADC interrupt flag */ return ADCW; /* Return ADC word */ } int main(void) { init_devices(); //start at least one task here set_task(5); //set_task(7); //task7 runs //set_task(6); //task6 runs // main loop while(1) { if (tick_flag) { tick_flag = 0; task_dispatch(); // well.... } } return 0; } // // a task gets dispatched on every tick_flag tick (10ms) // void task_dispatch(void) { /* scan the task bits for an active task and execute it */ char task; /* take care of the task timers. if the value ==0 skip it else decrement it. If it decrements to zero, activate the task associated with it */ task=0; while (task < NUM_TASKS ) { if (task_timers[task]) { task_timers[task]--; /* dec the timer */ if (task_timers[task] == 0 ) { set_task(task); /* if ==0 activate the task bit */ } } task++; } task = 0; /* start at the most significant task */ while (task <= NUM_TASKS ) { if ((task_bits & pgm_read_byte(&bit_mask[task]))) { break; /* if activate task found..*/ } task++; /* else try the next one */ } switch(task) /* if task bit is active..execute the task */ { case 0: task0(); break; case 1: task1(); break; case 2: task2(); break; case 3: task3(); break; case 4: task4(); break; case 5: task5(); break; case 6: task6(); break; case 7: task7(); break; default: break; /* no task was active!! */ } } // enable a task for execution void set_task(char tsk) { task_bits |= pgm_read_byte(&bit_mask[tsk]); /* sets a task bit */ } // disable a task from executing void reset_task(char tsk) { task_bits &= (~pgm_read_byte(&bit_mask[tsk])); /* resets a task bit */ } void task0(void) { reset_task(0); } void task1(void) { if (button_down(BUTTON1_MASK)) { PORD ^= 1<<PD4; } reset_task(1); } void task2(void) { if (button_down(BUTTON2_MASK)) { PORTD ^= 1<<PD7; } reset_task(2); } void task3(void) { char Temperature[10]; float celsius; mylcd_string(1, 0,"TEMPERATURE"); celsius = (float)ADC_Read(0)*4.88 / 10.0; sprintf(Temperature,"%d%cC ", (int)celsius, DEGREE_SYMBOL); mylcd_string(1,12,Temperature); reset_task(3); } void task4(void) { reset_task(4); } void task5(void) { // Rtc time and date are displayed here char buffer[40]; RTC_Read_Clock(0); /* Read clock with second add. i.e location is 0 */ sprintf(buffer, "%02x:%02x:%02x ", (hour), minute, second); mylcd_string(0,0,buffer); RTC_Read_Calendar(3); /* Read calendar with day address i.e location is 3 */ sprintf(buffer, "%02x/%02x/%02x ", date,month, year); mylcd_string(0, 1, buffer); reset_task(5); task_timers[5] = 50; //run twice per second } void task6(void) { reset_task(6); } void task7(void) { reset_task(7); } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up cli(); //disable all interrupts DDRA = 0x00;//for temperature sensor DDRB = 0xff;//outputs for lcd PORTB = 0x00; PORTC = 0x00; // for rtc chip ds1307 DDRC = 0x00; PORTD = 0x0f; //pull-up enables for 3 pushbuttons DDRD = 0xf0; //2 o/p for relays, 1 o/p for LED, 1 o/p for TXD and 3 i/p for pushbuttons timer_0_init(); debounce_init(); sei(); //re-enable interrupts //all peripherals are now initialized } //TIMER0 initialize - prescale:1024 // WGM: CTC // desired value: 10mSec // actual value: 10.048mSec (-0.5%) void timer_0_init(void) { TCCR0 = 0x00; //stop TCNT0 = 0x00; //set count TCCR0 = 0x02; //CTC mode OCR0 = 0x9C; TCCR0 = 0x05; //start timer } ISR(TIMER0_COMP_vect) //make sure this is correct - the compiler will complain if it's not { //TIMER0 has overflowed tick_flag = 1; debounce(); }
I am using peter's fluery lcd library and danni's library for button debounce both of which great worked on my other projects and ofcourse Kartman's multitasking tutorial as the base of my project.