Rev Author Line No. Line
2444 kaklik 1 #include <16F887.h>
2 #device *=16
3 #device adc=8
4 #device PASS_STRINGS=IN_RAM
5 #zero_ram
6 #FUSES NOWDT //No Watch Dog Timer
7 #FUSES INTRC_IO //Internal RC Osc, no CLKOUT
8 #FUSES PUT //Power Up Timer
9 #FUSES MCLR //Master Clear pin enabled
10 #FUSES NOPROTECT //Code protected from reads
11 #FUSES NOCPD //No EE protection
12 #FUSES BROWNOUT //Reset when brownout detected
13 #FUSES NOIESO //Internal External Switch Over mode disabled
14 #FUSES NOFCMEN //Fail-safe clock monitor disabled
15 #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
16 #FUSES NODEBUG //No Debug mode for ICD
17 #FUSES NOWRT //Program memory not write protected
18 #FUSES BORV21 //Brownout reset at 2.1V
19 #use delay(clock=8000000,RESTART_WDT)
20 //#use rs232(baud=9600,parity=N,xmit=TXD,rcv=RXD,bits=8,errors)
21 #use rs232(baud=9600,parity=N,xmit=PIN_B7,rcv=PIN_B6,bits=8)
22  
23  
24 /*$F*************************************************************************
25 *
26 * Copyright (C)pa 2004 Mark Norton
27 *
28 * Permission is hereby granted, free of charge, to any person obtaining
29 * a copy of this software and associated documentation files (the
30 * "Software"), to deal in the Software without restriction, including
31 * without limitation the rights to use, copy, modify, merge, publish,
32 * distribute, sublicense, and/or sell copies of the Software, and to
33 * permit persons to whom the Software is furnished to do so, subject to
34 * the following conditions:
35 *
36 * The above copyright notice and this permission notice shall be included
37 * in all copies or substantial portions of the Software.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
43 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 *
47 * Functional
48 * Description: Implementation of sscanf() function for the CCS compiler
49 *
50 *****************************************************************************/
51 #include <string.h>
52 #include <stdlib.h>
53  
54 /* Uncomment any of these to reduce the code size
55 Note that the HEX is a big hog
56 */
57 #define NO_FLOAT
58 // #define NO_INT
59 // #define NO_SIGNED_INT
60 // #define NO_STRING
61 // #define NO_HEX
62  
63 /* *************************************************************************
64 DESCRIPTION: Converts string pointed to by s to an unsigned long (16 bit)
65 RETURN: result of the conversion
66 ALGORITHM: none
67 NOTES: the next position in the string is returned in endptr
68 *************************************************************************** */
69 long my_atoul(char *s, char *endptr, int base)
70 {
71 signed long result;
72 int index;
73 char c;
74  
75 index = 0;
76 result = 0;
77 *endptr = s;
78  
79 if (( !s ) || ( !*s ))
80 return ( 0 );
81  
82 c = *s;
83  
84 // increase index if positive sign is detected
85 if (c == '+')
86 {
87 c = *(++s);
88 }
89  
90 // The number is a decimal number
91 if (base == 10)
92 {
93 while (c >= '0' && c <= '9')
94 {
95 result = 10*result + (c - '0');
96 c = *(++s);
97 }
98 }
99 else if (base == 16) // The number is a hexa number
100 {
101 if (c == '0' && (*(s+1) == 'x' || *(s+1) == 'X'))
102 {
103 s += 2;
104 c = *s;
105 }
106  
107 c = toupper(c);
108 while (true)
109 {
110 if (c >= '0' && c <= '9')
111 result = (result << 4) + (c - '0');
112 else if (c >= 'A' && c <='F')
113 result = (result << 4) + (c - 'A' + 10);
114 else
115 break;
116 c = toupper(*(++s));
117 }
118 }
119 *endptr = s;
120 return(result);
121 }
122  
123 /* *************************************************************************
124 DESCRIPTION: Converts string pointed to by s to a float
125 RETURN: result of the conversion
126 ALGORITHM: none
127 NOTES: the next position in the string is returned in endptr
128 *************************************************************************** */
129 float my_atof(char * s, char *endptr)
130 {
131 float pow10 = 1.0;
132 float result = 0.0;
133 int sign = 0;
134 char c;
135  
136 c = *s;
137  
138 if(c == '-')
139 {
140 sign = 1;
141 c = *(++s);
142 }
143 else if(c == '+')
144 c = *(++s);
145  
146  
147 while((c >= '0' && c <= '9'))
148 {
149 result = 10*result + c - '0';
150 c = *(++s);
151 }
152  
153 if (c == '.')
154 {
155 c = *(++s);
156 while((c >= '0' && c <= '9'))
157 {
158 pow10 = pow10*10;
159 result += (c - '0')/pow10;
160 c = *(++s);
161 }
162 }
163  
164 if (sign == 1)
165 result = -1*result;
166  
167 *endptr = s;
168 return(result);
169 }
170  
171  
172 /* *************************************************************************
173 DESCRIPTION: Implementation of scanf() using CCS C compiler
174 RETURN: total number of arguments read
175 ALGORITHM: none
176 NOTES: none
177 *************************************************************************** */
178 int8 sscanf(
179 char *buf, /* pointer to the buffer that we are scanning */
180 char *fmt, /* pointer to the format string */
181 char *pArgs) /* pointer to array of arguments */
182 {
183  
184 int8 count = 0;
185 char *p;
186 int1 size_long;
187 int1 sign;
188 char *endptr;
189  
190 while (true)
191 {
192 /* Look to see if we are out of arguments */
193 if ( !pArgs )
194 return( count );
195  
196 /* Gobble up the fmt string */
197 while (*buf == *fmt)
198 {
199 if ((*buf == 0) || (*fmt == 0))
200 return (count);
201 buf++;
202 fmt++;
203 }
204  
205 /* Check for the % */
206 if (*fmt != '%')
207 break;
208  
209 /* fmt should be '%' go to the next character */
210 fmt++;
211  
212 /* get the size modifier */
213 switch (*fmt)
214 {
215 case 'l':
216 case 'L':
217 fmt++;
218 size_long = TRUE;
219 break;
220 default:
221 size_long = FALSE;
222 break;
223 }
224  
225 /* fmt should point to our first conversion letter at this point */
226 switch (*fmt)
227 {
228 #ifndef NO_FLOAT
229 case 'f':
230 case 'F':
231 /* Get a pointer to this argument */
232 p = (float *)(*pArgs);
233  
234 /* convert to a number */
235 *(float *)p = (float)my_atof(buf, &endptr);
236  
237 /* Make sure that we succeeded */
238 if ( buf == endptr )
239 return ( count );
240 buf = endptr;
241  
242 /* count this one */
243 count++;
244 break;
245 #endif
246 #ifndef NO_SIGNED_INT
247 case 'd':
248 case 'D':
249 /* Get a pointer to this argument */
250 p = (signed int8 *)(*pArgs);
251 if (*buf == '-')
252 {
253 buf++;
254 sign = TRUE;
255 }
256 else
257 sign = FALSE;
258  
259 /* convert to a number */
260 if ( size_long )
261 {
262 *(signed int16 *)p = (signed int16)my_atoul(buf, &endptr, 10);
263 if (sign)
264 *(signed int16 *)p = -(*(signed int16 *)p);
265 }
266 else
267 {
268 *(signed int8 *)p = (signed int8)my_atoul(buf, &endptr, 10);
269 if (sign)
270 *(signed int8 *)p = -(*(signed int8 *)p);
271 }
272 /* Make sure that we succeeded */
273 if ( buf == endptr )
274 return ( count );
275 buf = endptr;
276  
277 /* count this one */
278 count++;
279 break;
280 #endif
281 #ifndef NO_INT
282 case 'u':
283 case 'U':
284 /* Get a pointer to this argument */
285 p = (int8 *)(*pArgs);
286  
287 /* convert to a number */
288 if ( size_long )
289 *(int16 *)p = (int16) my_atoul(buf, &endptr, 10);
290 else
291 *(int8 *)p = (int8) my_atoul(buf, &endptr, 10);
292  
293 /* Make sure that we succeeded */
294 if ( buf == endptr )
295 return ( count );
296 buf = endptr;
297  
298 /* count this one */
299 count++;
300 break;
301 #endif
302 #ifndef NO_STRING
303 case 's':
304 /* Get a pointer to this argument */
305 p = (char *)(*pArgs);
306  
307 /* copy the chars */
308 while (true)
309 {
310 if ((isspace(*buf)) || (!*buf))
311 {
312 *p = 0;
313 break;
314 }
315 else
316 {
317 *p = *buf;
318 p++;
319 buf++;
320 }
321 }
322  
323 /* count this one */
324 count++;
325 break;
326 #endif
327 #ifndef NO_HEX
328 case 'x':
329 case 'X':
330 /* Get a pointer to this argument */
331 p = (int8 *)(*pArgs);
332  
333 /* convert to a number */
334 if ( size_long )
335 *(int16 *)p = (int16) my_atoul(buf, &endptr, 16);
336 else
337 *(int8 *)p = (int8) my_atoul(buf, &endptr, 16);
338  
339 /* Make sure that we succeeded */
340 if ( buf == endptr )
341 return ( count );
342 buf = endptr;
343  
344 /* count this one */
345 count++;
346 break;
347 #endif
348 /* unhandled format specifier */
349 default:
350 return (count);
351 }
352 /* Technically this is incorrect but since the size of all pointers
353 are the same, who cares ;)
354  
355 point to the next argument
356 */
357 pArgs += sizeof(char *);
358  
359 /* Move to the next format char */
360 fmt++;
361 }
362  
363 return (count);
364 }
365  
366  
367  
368 void main() {
369 char x;
370 char sbuffer[64];
371 char cmd=0,param=0;
372  
373 char arglist[2];
374 arglist[0] = &cmd;
375 arglist[1] = &param;
376  
377  
378 set_tris_a(0x80);
379 port_b_pullups(0xFF);
380 set_tris_b(0xFF);
381 set_tris_d(0);
382 set_tris_e(0x01);
383 setup_oscillator(OSC_8MHZ);
384 setup_adc_ports(sAN5|VSS_VDD);
385 setup_adc(ADC_CLOCK_INTERNAL);
386 set_adc_channel(5);
387 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
388 setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
389 setup_timer_2(T2_DIV_BY_16, 155, 1);
390 setup_ccp1(CCP_PWM);
391 set_pwm1_duty(75);
392 setup_comparator(NC_NC_NC_NC);
393  
394 sprintf(sbuffer,"/S 30\r\n");
395 x = sscanf(sbuffer,"/%C %d", arglist);
396 printf("\r\nsscanf sez: %u found, cmd %X param %X\r\n",x,cmd,param);
397  
398 }