Estoy escribiendo un código de lenguaje C para PIC16f877a para un reloj de alarma. En resumen, el reloj de alarma muestra Hora, Configurar alarma y una temperatura & Lectura de humedad en una pantalla LCD.
He escrito interrupciones para actualizar la hora, para activar y desactivar la alarma y algunas otras que planeo escribir.
El problema es que estoy en medio punto de mi código y el problema de desbordamiento de pila ha aumentado en la simulación de proteus. He identificado la parte del código que causa el problema. Pero parece que no entiendo cómo debo cambiarlo para evitar el desbordamiento de pila.
¿Puede alguien ayudarme a depurar este código? ¿Y anote las malas prácticas en la programación del microcontrolador C que causan errores similares? Parece que no puedo encontrar esa lista de malas prácticas en Internet.
Aquí está el código que he escrito para configurar la alarma / hora en el reloj. El desbordamiento comienza a ocurrir una vez que selecciono la opción de configurar el tiempo. Luego sigue sucediendo hasta que el PIC se bloquea incluso cuando salgo de la rutina setTime.
#define UP RD0 // Push buttons active high
#define DOWN RD1
#define SELECT RD2
#define BACK RD3
#define SNOOZE RD4
void UpdateSetTimeScreen() {
if (ptr > 1)
LCD_cursor(ptr + 1, 1);
else
LCD_cursor(ptr, 1);
if (set[ptr] == 0)
LCD_puts("_");
else
LCD_display_value(set[ptr]);
}
void SetTime() {
LCD_clear();
LCD_puts("Set Time");
LCD_cursor(0, 1);
LCD_puts("__:__");
LCD_cursor(0, 1);
set[0] = 0;
set[1] = 0;
set[2] = 0;
set[3] = 0;
ptr = 0;
unsigned int i =1;
while (i) {
if (UP == 1) {
while (UP);
switch (ptr) {
case 0:
{
if (set[ptr] < 2) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 1:
{
if (set[ptr] < 3) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 2:
{
if (set[ptr] < 5) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 3:
{
if (set[ptr] < 9) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
}
}
if (DOWN == 1) {
while (DOWN);
if (set[ptr] > 0) {
set[ptr]--;
UpdateSetTimeScreen();
}
} else if (BACK == 1) {
while (BACK);
ptr--;
} else if (SELECT == 1) {
while (SELECT);
if (ptr == 3)
i=0;
else
ptr++;
}
}
hour = (set[0]*10) + set[1];
minute = (set[2]*10) + set[3];
}
void SetAlarm() {
LCD_clear();
LCD_puts("Set Alarm Time");
LCD_cursor(0, 1);
LCD_puts("__:__");
LCD_cursor(0, 1);
set[0] = 0;
set[1] = 0;
set[2] = 0;
set[3] = 0;
ptr = 0;
unsigned int j = 1;
while (j) {
if (UP == 1) {
while (UP);
switch (ptr) {
case 0:
{
if (set[ptr] < 2) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 1:
{
if (set[ptr] < 3) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 2:
{
if (set[ptr] < 5) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
case 3:
{
if (set[ptr] < 9) {
set[ptr]++;
UpdateSetTimeScreen();
}
break;
}
}
}
if (DOWN == 1) {
while (DOWN);
if (set[ptr] > 0) {
set[ptr]--;
UpdateSetTimeScreen(ptr);
}
} else if (BACK == 1) {
while (BACK);
if(ptr > 0)
ptr--;
} else if (SELECT == 1) {
while (SELECT);
if (ptr == 3)
j=0;
else
ptr++;
}
}
AlarmHr = (set[0]*10) + set[1];
AlarmMin = (set[2]*10) + set[3];
}
void SetTemp() {
}
void print_configuration_screen() {
LCD_clear();
switch (scr) {
case 1:
{
LCD_puts("* Set Time");
LCD_cursor(0, 1);
LCD_puts(" Set Alarm");
break;
}
case 2:
{
LCD_puts(" Set Time");
LCD_cursor(0, 1);
LCD_puts("* Set Alarm");
break;
}
case 3:
{
LCD_puts(" Set Alarm");
LCD_cursor(0, 1);
LCD_puts("* Temp Mode");
break;
}
case 4:
{
LCD_puts("* Set Alarm");
LCD_cursor(0, 1);
LCD_puts(" Temp Mode");
break;
}
}
}
void ConfigurationMode() {
scr = 1;
print_configuration_screen();
while (mode == 2) {
if (BACK == 1) {
while (BACK);
mode = 1;
} else if (UP == 1) {
while (UP);
if (scr > 1) {
if (scr == 3)
scr = 4;
else if (scr == 4)
scr = 1;
else
scr--;
}
print_configuration_screen();
} else if (DOWN == 1) {
while (DOWN);
if (scr == 4)
scr == 3;
else if (scr < 3)
scr++;
print_configuration_screen();
} else if (SELECT == 1) {
while (SELECT);
switch (scr) {
case 1: SetTime(); // Set time
break;
case 2:
{
SetAlarm(); // Set Alarm
mode = 1;
break;
}
case 3: SetTemp();
break;
case 4:
{
SetAlarm();
mode = 1;
break;
}
}
scr = 1;
print_configuration_screen();
}
}
}
Adjunto capturas de pantalla para ayudarles a comprender mejor el momento en que surge el problema:
TodoestábienhastaqueentroenlarutinaSetTimeoSetAlarm.
AlpresionarARRIBA/ABAJOparaajustarlahora,encadapulsación,seproducenunos7a8desbordamientosdepila.
DespuésdesalirdeConfigurationMode()usandoBACK,laMCUsedescomponeylosdesbordamientosdepilacomienzanaocurrirenmileshastaquesebloquea.