Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] coding in MicroC for PIC16F628

Status
Not open for further replies.

Jay23

Newbie level 6
Newbie level 6
Joined
Oct 14, 2013
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,488
I have build a 30 min,3 hours and 8 hours timer with PIC16F628A chip.
Mine should work like this:
3 tact switches:
30 min, 3 hr, 8 hr switch.
When I press 30 min : the counter loads this value into the counter and starts counting down when the Start/Stop button is pressed.
Similar function when the 3 hour or the 8 hour switch button is pressed.

A LCD display is connected and the value of the pressed switch is displayed on the display.
The code is added here below:
This is to set a value from 1 -99 minutes with the 2 switches: 0-1 or 10-99.
Then the counter starts counting down.
I want to preset the counter with the value of 30 minutes or 3 hours or 8 hours by pressing the respective tact switch.
Has someone some idea how to fix this?
//regards, Jay


==========================================================================

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// LCD DISPLAY module connections
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_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 TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_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
 
// Tact switches
sbit SS_Select at RB1_bit;    // Start Stop Timer Select
sbit Unit_Button at RB2_bit;  // Set unit min
sbit Ten_Button at RB3_bit;   // Set ten min
sbit Eighthr_Button at RB0_bit;   // Set 8hr
//Relays and Buzzer
//sbit Relay1 at RB0_bit;
//sbit Relay2 at RB0_bit;
//sbit Relay3 at RB0_bit;
sbit SND at RA7_bit;
// LEDs
sbit Led_RED at RA6_bit;
sbit Led_GREEN at RA3_bit;
sbit Led_YELLOW at RA4_bit;
 
// Messages
char Message1[]="30min-8hr: Timer";
char Message2[]="Timer ON";
char Message3[]="Timer OFF";
char Message4[]="Set Time:    min";
char Message5[]="Time Left:   min";
unsigned short i, j, unit=0, ten=0, ON_OFF=0, index=0, clear, time;
char *digit = "00";
// 300ms Delay
void Delay_300(){
 Delay_ms(300);
}
 
void Display_Digits(){
 digit[1]=unit+48;
 digit[0]=ten+48;
 Lcd_Out(2,11,digit);
}
 
 void play_sound(){
  Sound_Play(2500, 500);
 }
 
 void debounce(){
  Delay_ms(250);
 }
 
void start_timer(unsigned short MinVal){
 unsigned short temp1, temp2;
 //Led_RED = 0;
 //Led_GREEN = 0;
 //Led_YELLOW = 0;
 //Relay1 = 1;
  play_sound();
 ON_OFF = 1;
 Lcd_Cmd(_LCD_CLEAR);
 Lcd_Out(1,1,Message2);
 Lcd_Out(2,1,Message5);
 OPTION_REG = 0x80 ;
 INTCON = 0x90;
 for (i=0; i<MinVal; i++){
  temp1 = (MinVal-i)%10 ;
  temp2 = (MinVal-i)/10 ;
  Lcd_Chr(2, 12, temp2+48);
  Lcd_Chr(2, 13, temp1+48);
  j=1;
  do {
  Delay_ms(1000);
  j++;
  } while(((j<=60) && (Clear ==0)));
  if (Clear) {
   //Relay1 = 0;
   Delay_ms(500);
   Lcd_Out(1,1,Message3);
   INTCON = 0x00;
   goto stop;
   }
 }
 stop: 
 //Relay1 = 0;
 Led_RED = 0;
 Led_GREEN = 0;
 Led_YELLOW = 0;
 ON_OFF = 0;
 unit = 0;
 ten = 0;
 clear = 1;
 play_sound();
 
}
 
 
void interrupt(void){
  if (INTCON.INTF == 1)   // Check if INTF flag is set
   {
    Clear = 1;
    INTCON.INTF = 0;       // Clear interrupt flag before exiting ISR
   }
  }
 
void main() {
  CMCON  |= 7;                       // Disable Comparators
  //TRISB = 0b00001111;
  TRISB = 0b01111111;
  //TRISA = 0b11110000;
  TRISA = 0b11000000;
  //Relay1 = 0;
  Sound_Init(&PORTB,0); // Initialize Buzzer o/p pin
 
 
  Lcd_Init();                        // Initialize LCD
 start:
  clear = 0;
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,1,Message1);
  Lcd_Out(2,1,Message4);
  Display_Digits()  ;
 do {
 
     if(!Unit_Button){
     Delay_300();
     unit ++;
     if(unit==10) unit=0;
     Display_Digits();
    } // If !Unit_Button
 
    if(!Ten_Button){
     Delay_300();
     ten ++;
     if(ten==10) ten=0;
     Display_Digits();
    } // If !Ten_Button
 
    if(!SS_Select){
     Delay_300();
     Led_RED = 1;
     time = ten*10+unit ;
     if(time > 0) start_timer(time);
    } // If !SS_Select
 
    if(clear){
     goto start;
    }
   } while(1);
}

 

Has someone some idea how to fix this?
You will never do it that way!

I do not use MikroC but the principle is this:

1. Use a variable that can count the number of seconds in the duration you want to time. 8hrs = 28,800 seconds so it will easily fit in an 'int'.
2 Set up a timer to generate an interrupt. Without knowing the clock speed I can't tell you what values to use. Aim for 1 second if that is the accuracy you need. Use this interrupt to maintain the count.
3. As each second elapses, check if the variable is > 0, if it is, deduct 1 from it then update your display.
4. In the 'main' loop, check the switches and pre-load the variable with 1,800 for 30 mins, 10,800 for 3 hrs or 28,800 for 8 hrs.
5. if the variable is zero, time is up so sound the buzzer.

Brian.
 

Dear,

Your PIC has very less RAM. Use it efficiently. Place all your strings in ROM and access it only when needed using CopyConst2Ram() function.
 

The program flow is wrong anyway but to save RAM, all Jay23 has to do is change:

Code:
char Message1[]="30min-8hr: Timer";
char Message2[]="Timer ON";
char Message3[]="Timer OFF";
char Message4[]="Set Time:    min";
char Message5[]="Time Left:   min";
to
Code:
const char Message1[]="30min-8hr: Timer";
const char Message2[]="Timer ON";
const char Message3[]="Timer OFF";
const char Message4[]="Set Time:    min";
const char Message5[]="Time Left:   min";
that should force to compiler to store the strings in program memory instead of RAM, no need to copy them to RAM before using them.

Brian.
 

Looks like Mikroe uses an 'unsigned char' pointer in the LCD_Out() function to locate the strings to be printed. That limits it's ability to handle large arrays and is potentially wasteful of RAM and could slow the program down. The more I hear about MikroC, the more I'm glad I don't use it!

To be fair, I often copy 'const' strings to RAM before displaying them but only because I usually pass the characters to the LCD using timed interrupts or by reading the 'ready' signal so I can push display routines into the background and carry on doing something else without waiting. I don't think MikroC does that though.

Brian.
 
I agree that handling of const strings is a popular problem with 8-bit PIC compilers, but it's not what the OP is asking for. Wasting 50 or 100 bytes of RAM for actually constant strings should be O.K. so far. I think it's misleading to discuss a fictive strings problem before the points mentioned in post #2 have been solved.

- - - Updated - - -

Looks like Mikroe uses an 'unsigned char' pointer in the LCD_Out() function to locate the strings to be printed. That limits it's ability to handle large arrays and is potentially wasteful of RAM and could slow the program down. The more I hear about MikroC, the more I'm glad I don't use it!
I also don't use MikroC or have plans to use it. I notice that the compiler is almost silent about how constant strings are handled and in which place they can be used. In so far I would be cautious to make suggestions how to "improve" the code in this regards.

- - - Updated - - -

In addition, said CopyConst2Ram() doesn't seem to be a MikroC standard function. It's apparently using an inbuilt (but undocumented according to the official manual) feature to implement char * = const char * as table read operation.
 
Yes, CopyConst2Ram() is not a mikroE standard function but it is provided by mikroE to use with LCD and UART routines.
 

//Hi all,
i got this code working the for 30 minutes timer but the 3 hour is not working.
I can only set the time to 99 minutes.
The LCD display show some strange numbers.
//Jay


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_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 TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_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
 
// LEDs and Relays and Sound Buzzers
sbit Relay_1 at RA7_bit;
sbit led_RED at RA2_bit;  //led red  for 30 mins
sbit led_BLUE at RA3_bit;  //led red  for 30 mins
sbit led_GREEN at RA4_bit;  //led green  for 3 hrs
//sbit led_YELLOW at RA4_bit;  //led yellow  for 8 hrs
sbit SND at RB0_bit;  //Buzzer
 
//Tact Switches
sbit StartStop at RB1_bit;    // Start Stop Timer Select
sbit Min30_Button at RB2_bit;  // Set unit min
sbit Hour3_Button at RB3_bit;   // Set ten min
//sbit Hour8_Button at RB3_bit;   // Set ten min
 
#define seconds *1000
#define minutes *60000
#define hours *3600000
 
//const long int 30min, 3hours, 8hours;
const int min30 = 30 minutes;
const int hr3 = 3 hours;
const int hr8 = 8 hours;
 
 
// Messages
char Message1[]="30min-8hr: Timer";
char Message2[]="Device ON";
char Message3[]="Device OFF";
char Message4[]="Set Time:     ";
char Message5[]="Time Left:   min";
char Message6[] = "HH:MM";
 
unsigned short i, j, unit=30, ten=0, ON_OFF=0, index=0, clear, time;
char *digit = "000";
 
// 300ms Delay
void Delay_300(){
 Delay_ms(300);
}
 
//Display digits functions
void Display_Digits(){
 digit[1]=unit+48;   //unit
 digit[0]=ten+48;
 Lcd_Out(2,11,digit);
}
 
// Buzzer sound
void play_sound(){
  Sound_Play(2500, 500);
 }
 
void debounce(){
  Delay_ms(300);
 }
 
//Timer function
void start_timer(unsigned short MinVal){
 unsigned short temp1, temp2;
 play_sound();
 Relay_1 = 1 ;
 led_BLUE = 1;
 led_RED = 1;
 led_GREEN = 1;
 ON_OFF = 1;
 Lcd_Cmd(_LCD_CLEAR);         //Clear LCD
 Lcd_Out(1,1,Message2);       //Show message 1 on LCD
 Lcd_Out(2,1,Message5);       //Show message 2 on LCD
 OPTION_REG = 0x80 ;          //Enable PORTB Pull UP
 INTCON = 0x90;               //Enable Global Interupt
 
 for (i=0; i<MinVal; i++){
  temp1 = (MinVal-i)%10 ;   //10
  temp2 = (MinVal-i)/10 ;
  Lcd_Chr(2, 12, temp2+48);
  Lcd_Chr(2, 13, temp1+48);
  j=1;
  do {
  Delay_ms(1000);
  j++;
  } while(((j<=60) && (Clear ==0)));
  if (Clear) {
   led_RED = 0;
   led_BLUE = 0;
   led_GREEN = 0;
   Delay_ms(500);
   Lcd_Out(1,1,Message3);
   INTCON = 0x00;
   goto stop;
   }
 }
 stop:
 Relay_1 = 0;
 led_BLUE = 0;
 led_RED = 1;
 led_GREEN = 0;
 //led_YELLOW = 0;
 ON_OFF = 0;
 unit = 0;       //unit
 ten = 0;
 clear = 1;
 play_sound();
}
 
 //Interupt
void interrupt(void){
  if (INTCON.INTF == 1)   // Check if INTF flag is set
   {
    Clear = 1;
    INTCON.INTF = 0;       // Clear interrupt flag before exiting ISR
   }
  }
 
void main() {
  CMCON  |= 7;
  TRISA = 0b00110000;  //TRISA = 0b11110000; // Disable Comparators
  TRISB = 0b00001111;  //TRISB = 0b00001111;
  Relay_1 = 0;
  led_BLUE = 0;
  led_RED = 0;
  led_GREEN = 0;
  //led_YELLOW = 0;
  Sound_Init(&PORTB,0); // Initialize Buzzer o/p pin
 
 
 
  Lcd_Init();                        // Initialize LCD
 start:
  clear = 0;
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,1,Message1);
  Lcd_Out(2,1,Message4);
  Display_Digits()  ;
 do {
 
     if(!Min30_Button){       //Unit
     Delay_300();
     unit=30;       //unit
     //unit ++;
     //if(unit=30) unit=0;
     Display_Digits();
    } // If !Unit_Button
 
    if(!Hour3_Button){
     Delay_300();
     unit=199;
     //ten ++;
     //if(ten==10) ten=0;
     Display_Digits();
    } // If !Ten_Button
 
    if(!StartStop){
     Delay_300();
     time = ten*500+unit ;    //unit
     if(time > 0) start_timer(time);
    } // If !SS_Select
 
    if(clear){
     goto start;
    }
   } while(1);
}

 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top