So the problem I'm having now is blocking code on two different timers that I'm experimenting with.
Timer0 uses @DaveAlfa's continuous overflowing timer that increments 1.024ms and Timer1 uses an interrupt that triggers every 1ms. They both are working but the problem occurs once I try to refresh the LCD. It takes 24.96ms to do a complete refresh because of the __delay_us() function in the LCD library functions. This adds time to the delay constants (led_off/on_time) that I am using in both Handle_LED functions. How much time is added depends on where the timer is when it exceeds the test conditions
if ((getTime() - last_time) < led_off_time1) or if (led_count < led_off_time2)
I have tried to trim out all the delay time I can in the LCD library functions but this is about as close as I can trim in on this slow of device.
/*****************************************
Main application
*****************************************/
void main (void){
//Initialize functions
SYSTEM_Initialize(); // Timer0 Internal_clock, prescaler_32768, postscaler_1);
Lcd4_Init();
configTimer0();
configTimer1();
while(1) {
Handle_LED1();
Handle_LED2();
//Handle_ADC();
//Handle_LCD();
}
}
void Handle_LED1(void)
{
static uint16_t last_time = 0;
static uint8_t status = 0;
// Check the application's current state.
switch (status)
{
// Application's initial state.
case led_init:
{
status = led_wait;
break;
}
case led_wait:
{
if ((getTime() - last_time) < led_off_time1)
{
return;
}
last_time = getTime();
led6_Toggle();//Toggle LED
status = led_blink;
break;
}
case led_blink:
{
if ((getTime() - last_time) < led_on_time1)
{
return;
}
last_time = getTime();
led6_Toggle(); //Toggle LED
status = led_wait; // return to Wait state
break;
}
default:
{
break;
}
}
}
void Handle_LED2(void)
{
static uint8_t led_status = led_init;
switch (led_status)
{
// Application's initial state.
case led_init:
{
led_count = 0;
led_status = led_wait;
break;
}
case led_wait:
{
if (led_count < led_off_time2)
{
return;
}
led_count = 0;
led5_Toggle();//Toggle LED
led_status = led_blink;
break;
}
case led_blink:
{
if (led_count < led_on_time2)
{
return;
}
led_count = 0;
led5_Toggle(); //Toggle LED
led_status = led_wait; // return to Wait state
break;
}
default:
{
break;
}
}
}
/*
void Handle_LED(void){
if ( elapsed < led_time){
return;
}
last_time = now;
// Do LED stuff
// Everytime you get here you know "led_time" time has passed
}
*/
void Handle_ADC(void){
static uint32_t last_time = 0;
static uint8_t channel = 0;
static uint8_t adc_status = adc_idle;
static uint32_t voltage[4];
// Do ADC stuff
switch (adc_status)
{
case adc_idle:
adc_status++;
//ADPCH = 5 - channel;
// __delay_ms(10);
break;
case adc_sampling:
adc_status++;
ADCON0bits.ADGO = 1;
break;
case adc_converting:
for (uint8_t i = 0; i < 4; i++)
{
voltage[i] = GET_Voltage(resistorRatioCell[i], ADC_Read(5-i));
}
//Converts readings at the balance wires to individual cell voltage
for (uint8_t i = 0; i < 3; i++)
{
cell_voltages[i] = voltage[i] - voltage[i + 1];
}
cell_voltages[3] = voltage[3];
adc_status = adc_all_done;
break;
case adc_all_done:
adc_status = adc_idle;
break;
}
//
}
void Handle_LCD(void)
{
static uint8_t lcd_status = lcd_wait;
switch (lcd_status)
{
case lcd_wait:
if (lcd_count < lcd_delay_time)
{
return;
}
lcd_count = 0;
lcd_status = lcd_display;
break;
case lcd_display:
/* This contains 24.96 ms via __delay_us() function to refresh all four voltage readouts to LCD */
LCD_Display(cell_voltages[0], 1, 0);
LCD_Display(cell_voltages[1], 1, 8);
LCD_Display(cell_voltages[2], 2, 0);
LCD_Display(cell_voltages[3], 2, 8);
lcd_status = lcd_wait;
break;
}
}
void LCD_Display(uint32_t cell_voltages, uint8_t row, uint8_t column) {
volt_str[0] = digit[ ((cell_voltages / 100000) % 10) ];
volt_str[2] = digit[ ((cell_voltages / 10000) % 10) ];
volt_str[3] = digit[ ((cell_voltages / 1000) % 10) ];
Lcd4_Set_Cursor(row, column);
Lcd4_Write_String(volt_str);
}
/***************Relevant LCD functions*****************/
void Lcd4_Set_Cursor(unsigned char a, unsigned char b)
{
unsigned char temp, z, y;
if(a == 1)
{
temp = 0x80 + b;
z = temp >> 4;
y = (0x80 + b) & 0x0F;
Lcd4_Cmd(z);
Lcd4_Cmd(y);
}
else if(a == 2)
{
temp = 0xC0 + b;
z = temp >> 4;
y = (0xC0 + b) & 0x0F;
Lcd4_Cmd(z);
Lcd4_Cmd(y);
}
}
void Lcd4_Write_Char(char a)
{
char temp,y;
temp = a & 0x0F;
y = a & 0xF0;
RS = 1; // => RS = 1
Lcd4_Port(y >> 4); //Data transfer
EN = 1;
__delay_us(500);
EN = 0;
Lcd4_Port(temp);
EN = 1;
//__delay_ms(2);
__delay_us(40);
EN = 0;
}
void Lcd4_Write_String(char *a)
{
int i;
for(i=0; a[i] != '\0'; i++)
Lcd4_Write_Char(a[i]);
}
Any suggestions on how to avoid these blocking code delays?
Jerry