|
|
View previous topic :: View next topic |
Author |
Message |
vpowerrc
Joined: 28 Apr 2012 Posts: 10
|
alarm clock from 16f877a |
Posted: Sat Apr 28, 2012 12:45 pm |
|
|
PIC - 16F877A
Compiler - 4.013
I'm doing my first year project based on PIC. I need to make an alarm clock as part of that project using pic. I used this forum so many times for my project. I'm very grateful to this forum. Now this is where I'm stopped at:
I connected 16x2 lcd, ds1307 clock and a 4x4 keypad to the PIC.
My objectives are
set the time by user and write it to the eeprom
set 3 alarms by user and write it to the eeprom
read from eeprom and compare them to output a signal
At the main menu I'm setting two buttons to "set the time"(set factions) and "show the current time"(time function). I wrote two separate functions for them.
My question is after I set the time, how can I go back to the main menu or " time" function ?
Code is below:
Code: |
#include <16f877a.h> //PIC utilizado
#device adc=10
#FUSES NOWDT,HS, NOPROTECT,NOLVP, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)
#INCLUDE "lcd.c" //Incluyo LCD.C
#include "ds1307.c"
#define use_portb_kbd TRUE
#INCLUDE "kbd.c"
void set();
void settime(void);
void setalarm1(void);
void time();
char s;
char m;
char k;
char st[5];
int n=1;
char al1[5];
int n1=1;
char al2[5];
int n2=1;
char al3[5];
int n3=1;
byte sec;
byte min;
byte hrs;
byte day;
byte month;
byte year;
byte dow;
void main(){
lcd_init();
kbd_init();
port_b_pullups(TRUE); // Need to pull up the keypad row pins
lcd_putc("\Main Menu\n");
while(TRUE)
{
m=kbd_getc();
if(m!=0)
if(m=='A'){
time();
}
if(m=='B'){
set();
}
}
}
void time(){
lcd_init(); //initialize lcd
//initialize 1307
ds1307_init();
ds1307_set_date_time(0,0,0,0,23,59,55); //day, month,year,dow,hr,min.sec
while(1)
{
ds1307_get_date(day,month,year,dow);
ds1307_get_time(hrs,min,sec);
lcd_gotoxy(1,1);
printf(lcd_putc,"Time : %02d:%02d:%02d",hrs,min,sec);
//delay_ms(100);
}
}
void set(){
lcd_init();
kbd_init();
port_b_pullups(TRUE); // Need to pull up the keypad row pins
lcd_putc("\Menu\n");
while(TRUE)
{
m=kbd_getc();
if(m!=0)
if(m=='A'){
settime();
}
if(m=='B'){
setalarm1();
}
}
}
void settime(void){
lcd_putc("\fSet Time...\n");
while(TRUE)
{
k=kbd_getc();
if(k!=0)
if(k=='#')
{
lcd_putc('\f');
lcd_putc("Time Set\n");
lcd_putc(st[1]);
lcd_putc(st[2]);
lcd_putc('/');
lcd_putc(st[3]);
lcd_putc(st[4]);
}
else if(k=='*') {
lcd_putc('\f');
lcd_putc("\fSet Time...\n");
n=1;
}
else if(k=='A') {
lcd_putc('\f');
lcd_putc("\fSet Time...\n");
n=1;
}
else if(k=='B') {
break;
setalarm1();
}
// else if(k=='C') {
//setalarm2();
// break;
// else if(k=='D') {
//setalarm3();
//break;
else {
lcd_putc(k);
st[n]=k;
n++;
}
}
}
void setalarm1(void){
lcd_putc("\fSet Alarm 1...\n");
while(TRUE)
{
k=kbd_getc();
if(k!=0)
if(k=='#')
{
lcd_putc('\f');
lcd_putc("Alarm 1 Set\n");
lcd_putc(al1[1]);
lcd_putc(al1[2]);
lcd_putc('/');
lcd_putc(al1[3]);
lcd_putc(al1[4]);
}
else if(k=='*') {
lcd_putc('\f');
lcd_putc("\fSet Alarm 1...\n");
n1=1;
}
else if(k=='A') {
break;
//settime(); //I cant call this. It says recursive fuctions are not permitted. Is there any solution ??
}
else if(k=='B') {
lcd_putc('\f');
lcd_putc("\fSet Alarm 1...\n");
n1=1;
}
else {
lcd_putc(k);
al1[n1]=k;
n1++;
}
}
} |
|
|
|
vpowerrc
Joined: 28 Apr 2012 Posts: 10
|
|
Posted: Sat Apr 28, 2012 2:40 pm |
|
|
Someone please help me :( |
|
|
necati
Joined: 12 Sep 2003 Posts: 37 Location: istanbul
|
|
|
vpowerrc
Joined: 28 Apr 2012 Posts: 10
|
|
Posted: Sat Apr 28, 2012 9:06 pm |
|
|
That is not the exact answer I want. I want to know how to call the same function from other functions. It says recursive not permitted. Is there any solution ? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Apr 29, 2012 12:37 pm |
|
|
Quote: |
It says recursive not permitted.
|
Recursion is normally part of C. CCS and other PIC compilers don't allow recursion (it's a stack depth issue).
Recursion happens when a function calls itself.
Quote: |
that is not the exact answer I want. I want to know how to call the same function from other functions. Is there any solution ?
|
I don't understand your question. Please expand on what it is you are trying to do.
Mike |
|
|
vpowerrc
Joined: 28 Apr 2012 Posts: 10
|
|
Posted: Mon Apr 30, 2012 11:46 am |
|
|
Actually this is what I want to do:
I'm building a alarm clock. Actually I developed it to get inputs from keypad successfully without using interrupts (just using a while(true) condition in the main method). I coded it to get inputs from user to set the clock and 3 alarms. I managed to store them in the eeprom also. But problem arises when I want to compare the alarms and the real time.
because in the main method I need to check for a key press as well as comparing alarm time and the real time. When I put both codes there I won't detect the keypress as It did before.
My code
Code: |
#include <16f877a.h> //PIC utilizado
#device adc=10
#FUSES NOWDT,HS, NOPROTECT,NOLVP, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)
#INCLUDE "lcd.c" //Incluyo LCD.C
#include "ds1307.c"
#define use_portb_kbd TRUE
#INCLUDE "kbd.c"
void showtime();
void settime();
void setalarm1();
void setalarm2();
void setalarm3();
void mainmenu();
void mainmenud();
int h;
char s;
char m;
char k;
int ht;
int mt;
int ha1;
int ma1;
int ha2;
int ma2;
int ha3;
int ma3;
int d;
char st[6];
int n=1;
char al1[5];
int n1=1;
char al2[5];
int n2=1;
char al3[5];
int n3=1;
byte sec;
byte min;
byte hrs;
byte day;
void main(){
lcd_init();
kbd_init();
port_b_pullups(TRUE); // Need to pull up the keypad row pins
lcd_putc("\System Active\n");
while(TRUE) {
/*THis is the code for comparing alarms and real time
ds1307_init();
//reading alarm times from eeprom
ha1=(read_eeprom(5)-'0')*10+read_eeprom(6)-'0' ;
ma1=(read_eeprom(7)-'0')*10+read_eeprom(8)-'0' ;
ha2=(read_eeprom(9)-'0')*10+read_eeprom(10)-'0' ;
ma2=(read_eeprom(11)-'0')*10+read_eeprom(12)-'0' ;
ha3=(read_eeprom(13)-'0')*10+read_eeprom(14)-'0' ;
ma3=(read_eeprom(15)-'0')*10+read_eeprom(16)-'0' ;
//get real time from clock
ds1307_get_time(hrs,min,sec);
//comparing
if( ((hrs==ha1)&&(min==ma1))||((hrs==ha2)&&(min==ma2))||((hrs==ha3)&&(min==ma3)))
output_high(PIN_D3);
*/
m=kbd_getc();
if(m!=0) {
if(m=='A'){
lcd_putc('\f');
mainmenu();
}
}
}
}
void mainmenu(){
lcd_putc('\f');
lcd_putc("\Main Menu\n");
while(TRUE)
{
m=kbd_getc();
if(m!=0)
if(m=='A'){
showtime();
}
if(m=='B'){
settime();
}
if(m=='C'){
setalarm1();
}
}
} |
Can you please help me This is for my project. |
|
|
vpowerrc
Joined: 28 Apr 2012 Posts: 10
|
|
Posted: Tue May 01, 2012 10:19 am |
|
|
somebody please |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 02, 2012 2:21 am |
|
|
You could use either a state-machine or menu-driven system.
For a menu-driven:-
Suppose you have key-pad with three outputs only 1,2,RETURN
From main(); 1 takes you to function_1(), 2 to function_2().
From function_1(); 1 takes you to function_1_1(), 2 to function_1_2(), RETURN exits back to main().
Similar for function_2().
Menu depth continues to function_1_1_1(), function_1_1_2(), function_1_2_1(), function_1_2_2().... etc
Each function and sub_function can read the key-pad without running into recursion problems.
You have to be careful to ensure that each function has a proper exit mechanism to get back to the higher level.
(A good flow-chart should help you sort that one out).
Problems can arise if there is no key-pad response or alarm has to be operate whilst in a subfunction.
You can deal with no response by invoking a timeout.
You can operate alarm by making each function call your compare function (rather cumbersome), or do compare in an interrupt.
I'd be tempted to go the interrupt route, calling compare at say ~1s intervals.
Mike |
|
|
|
|
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
|