Rev 85 Rev 96
1 STANDARD STRING FUNCTIONS --> 1 STANDARD STRING FUNCTIONS -->
2   2  
3 ATOF() 3 ATOF()
4 ATOI() 4 ATOI()
5 ATOL() 5 ATOL()
6 ATOI32() 6 ATOI32()
7   7  
8 CALLOC() 8 CALLOC()
9 REALLOC() 9 REALLOC()
10 MALLOC() 10 MALLOC()
11 FREE() 11 FREE()
12 MALLOC() 12 MALLOC()
13 MEMCPY() 13 MEMCPY()
14 MEMMOVE() 14 MEMMOVE()
15 MEMSET() 15 MEMSET()
16   16  
17 FGETC() 17 FGETC()
18 GETC() 18 GETC()
19 GETCH() 19 GETCH()
20 CH() 20 CH()
21 GETCHAR() 21 GETCHAR()
22 GETS() 22 GETS()
23 FGETS() 23 FGETS()
24 GETENV() 24 GETENV()
25   25  
26 PUTC() 26 PUTC()
27 PUTCHAR() 27 PUTCHAR()
28 PUTS() 28 PUTS()
29 FPUTS() 29 FPUTS()
30 FPUTC() 30 FPUTC()
31   31  
32 PRINTF() 32 PRINTF()
33 FPRINTF() 33 FPRINTF()
34 SPRINTF() 34 SPRINTF()
35   35  
36 Goto 36 Goto
37   37  
38 ISALNUM(char) 38 ISALNUM(char)
39 ISALPHA(char) 39 ISALPHA(char)
40 ISDIGIT(char) 40 ISDIGIT(char)
41 ISLOWER(char) 41 ISLOWER(char)
42 ISSPACE(char) 42 ISSPACE(char)
43 ISUPPER(char) 43 ISUPPER(char)
44 ISXDIGIT(char) 44 ISXDIGIT(char)
45 ISCNTRL(x) 45 ISCNTRL(x)
46 ISGRAPH(x) 46 ISGRAPH(x)
47 ISPRINT(x) 47 ISPRINT(x)
48 ISPUNCT(x) 48 ISPUNCT(x)
49 TOLOWER() 49 TOLOWER()
50 TOUPPER() 50 TOUPPER()
51   51  
52   52  
53   53  
54   54  
55   55  
56   56  
57 STATEMENT 57 STATEMENT
58 EXAMPLE 58 EXAMPLE
59 59
60 if (expr) stmt; [else stmt;] 60 if (expr) stmt; [else stmt;]
61 if (x==25) 61 if (x==25)
62   62  
63 x=1; 63 x=1;
64   64  
65 else 65 else
66   66  
67 x=x+1; 67 x=x+1;
68 68
69 while (expr) stmt; 69 while (expr) stmt;
70 while (get_rtcc()!=0) 70 while (get_rtcc()!=0)
71   71  
72 putc(‘n’); 72 putc(‘n’);
73 73
74 do stmt while (expr); 74 do stmt while (expr);
75 do { 75 do {
76   76  
77 putc(c=getc()); 77 putc(c=getc());
78   78  
79 } while (c!=0); 79 } while (c!=0);
80 80
81 for (expr1;expr2;expr3) stmt; 81 for (expr1;expr2;expr3) stmt;
82 for (i=1;i<=10;++i) 82 for (i=1;i<=10;++i)
83   83  
84 printf(“%u\r\n”,i); 84 printf(“%u\r\n”,i);
85 85
86 switch (expr) { 86 switch (expr) {
87   87  
88 case cexpr: stmt; //one or more case [default:stmt] 88 case cexpr: stmt; //one or more case [default:stmt]
89   89  
90 ... } 90 ... }
91 switch (cmd) { 91 switch (cmd) {
92   92  
93 case 0: printf(“cmd 0”); 93 case 0: printf(“cmd 0”);
94   94  
95 break; 95 break;
96   96  
97 case 1: printf(“cmd 1”); 97 case 1: printf(“cmd 1”);
98   98  
99 break; 99 break;
100   100  
101 default: printf(“bad cmd”); 101 default: printf(“bad cmd”);
102   102  
103 break; } 103 break; }
104 104
105 return [expr]; 105 return [expr];
106 return (5); 106 return (5);
107 107
108 goto label; 108 goto label;
109 goto loop; 109 goto loop;
110 110
111 label: stmt; 111 label: stmt;
112 loop: I++; 112 loop: I++;
113 113
114 break; 114 break;
115 break; 115 break;
116 116
117 continue; 117 continue;
118 continue; 118 continue;
119 119
120 expr; 120 expr;
121 i=1; 121 i=1;
122 122
123 ; 123 ;
124 ; 124 ;
125 125
126 {[stmt]} 126 {[stmt]}
127   127  
128 Zero or more 128 Zero or more
129 {a=1; 129 {a=1;
130 b=1;} 130 b=1;}
131 131
132 How can a constant data table be placed in ROM? 132 How can a constant data table be placed in ROM?
133 ----------------------------------------------- 133 -----------------------------------------------
134   134  
135 The compiler has support for placing any data structure into the device ROM as a constant read-only element. Since the ROM and RAM data paths are separate in the PIC®, there are restrictions on how the data is accessed. For example, to place a 10 element BYTE array in ROM use: 135 The compiler has support for placing any data structure into the device ROM as a constant read-only element. Since the ROM and RAM data paths are separate in the PIC®, there are restrictions on how the data is accessed. For example, to place a 10 element BYTE array in ROM use:
136   136  
137 BYTE CONST TABLE [10]= {9,8,7,6,5,4,3,2,1,0}; 137 BYTE CONST TABLE [10]= {9,8,7,6,5,4,3,2,1,0};
138   138  
139 and to access the table use: 139 and to access the table use:
140   140  
141 x = TABLE [i]; 141 x = TABLE [i];
142   142  
143 OR 143 OR
144   144  
145 x = TABLE [5]; 145 x = TABLE [5];
146   146  
147 BUT NOT 147 BUT NOT
148   148  
149 ptr = &TABLE [i]; 149 ptr = &TABLE [i];
150   150  
151 In this case, a pointer to the table cannot be constructed. 151 In this case, a pointer to the table cannot be constructed.
152   152  
153 Similar constructs using CONST may be used with any data type including structures, longs and floats. 153 Similar constructs using CONST may be used with any data type including structures, longs and floats.
154   154  
155 Note that in the implementation of the above table, a function call is made when a table is accessed with a subscript that cannot be evaluated at compile time. 155 Note that in the implementation of the above table, a function call is made when a table is accessed with a subscript that cannot be evaluated at compile time.
156   156  
157 =-=----=--=-=-=- 157 =-=----=--=-=-=-
158 How are type conversions handled? 158 How are type conversions handled?
159   159  
160 The compiler provides automatic type conversions when an assignment is performed. Some information may be lost if the destination can not properly represent the source. For example: int8var = int16var; Causes the top byte of int16var to be lost. 160 The compiler provides automatic type conversions when an assignment is performed. Some information may be lost if the destination can not properly represent the source. For example: int8var = int16var; Causes the top byte of int16var to be lost.
161   161  
162 Assigning a smaller signed expression to a larger signed variable will result in the sign being maintained. For example, a signed 8 bit int that is -1 when assigned to a 16 bit signed variable is still -1. 162 Assigning a smaller signed expression to a larger signed variable will result in the sign being maintained. For example, a signed 8 bit int that is -1 when assigned to a 16 bit signed variable is still -1.
163   163  
164 Signed numbers that are negative when assigned to a unsigned number will cause the 2's complement value to be assigned. For example, assigning -1 to a int8 will result in the int8 being 255. In this case the sign bit is not extended (conversion to unsigned is done before conversion to more bits). This means the -1 assigned to a 16 bit unsigned is still 255. 164 Signed numbers that are negative when assigned to a unsigned number will cause the 2's complement value to be assigned. For example, assigning -1 to a int8 will result in the int8 being 255. In this case the sign bit is not extended (conversion to unsigned is done before conversion to more bits). This means the -1 assigned to a 16 bit unsigned is still 255.
165   165  
166 Likewise assigning a large unsigned number to a signed variable of the same size or smaller will result in the value being distorted. For example, assigning 255 to a signed int8 will result in -1. 166 Likewise assigning a large unsigned number to a signed variable of the same size or smaller will result in the value being distorted. For example, assigning 255 to a signed int8 will result in -1.
167   167  
168 The above assignment rules also apply to parameters passed to functions. 168 The above assignment rules also apply to parameters passed to functions.
169   169  
170 When a binary operator has operands of differing types then the lower order operand is converted (using the above rules) to the higher. The order is as follows: 170 When a binary operator has operands of differing types then the lower order operand is converted (using the above rules) to the higher. The order is as follows:
171   171  
172 Float 172 Float
173   173  
174 Signed 32 bit 174 Signed 32 bit
175   175  
176 Unsigned 32 bit 176 Unsigned 32 bit
177   177  
178 Signed 16 bit 178 Signed 16 bit
179   179  
180 Unsigned 16 bit 180 Unsigned 16 bit
181   181  
182 Signed 8 bit 182 Signed 8 bit
183   183  
184 Unsigned 8 bit 184 Unsigned 8 bit
185   185  
186 1 bit 186 1 bit
187   187  
188 The result is then the same as the operands. Each operator in an expression is evaluated independently. For example: 188 The result is then the same as the operands. Each operator in an expression is evaluated independently. For example:
189   189  
190 i32 = i16 - (i8 + i8) 190 i32 = i16 - (i8 + i8)
191   191  
192 The + operator is 8 bit, the result is converted to 16 bit after the addition and the - is 16 bit, that result is converted to 32 bit and the assignment is done. Note that if i8 is 200 and i16 is 400 then the result in i32 is 256. (200 plus 200 is 144 with a 8 bit +) 192 The + operator is 8 bit, the result is converted to 16 bit after the addition and the - is 16 bit, that result is converted to 32 bit and the assignment is done. Note that if i8 is 200 and i16 is 400 then the result in i32 is 256. (200 plus 200 is 144 with a 8 bit +)
193   193  
194 Explicit conversion may be done at any point with (type) inserted before the expression to be converted. For example in the above the perhaps desired effect may be achieved by doing: 194 Explicit conversion may be done at any point with (type) inserted before the expression to be converted. For example in the above the perhaps desired effect may be achieved by doing:
195   195  
196 i32 = i16 - ((long)i8 + i8) 196 i32 = i16 - ((long)i8 + i8)
197   197  
198 In this case the first i8 is converted to 16 bit, then the add is a 16 bit add and the second i8 is forced to 16 bit. 198 In this case the first i8 is converted to 16 bit, then the add is a 16 bit add and the second i8 is forced to 16 bit.
199   199  
200 A common C programming error is to do something like: 200 A common C programming error is to do something like:
201   201  
202 i16 = i8 * 100; 202 i16 = i8 * 100;
203   203  
204 When the intent was: 204 When the intent was:
205   205  
206 i16 = (long) i8 * 100; 206 i16 = (long) i8 * 100;
207   207  
208 Remember that with unsigned ints (the default for this compiler) the values are never negative. For example 2-4 is 254 (in 8 bit). This means the following is an endless loop since i is never less than 0: 208 Remember that with unsigned ints (the default for this compiler) the values are never negative. For example 2-4 is 254 (in 8 bit). This means the following is an endless loop since i is never less than 0:
209   209  
210 int i; 210 int i;
211   211  
212 for( i=100; i>=0; i--) 212 for( i=100; i>=0; i--)
213   213  
214 =--=-=-- monitor =-=-=- 214 =--=-=-- monitor =-=-=-
215 Debugger - Monitor 215 Debugger - Monitor
216   216  
217 The monitor window shows data from the target and allows entry of data to be sent to the target. This is done on the target like this: 217 The monitor window shows data from the target and allows entry of data to be sent to the target. This is done on the target like this:
218   218  
219 #use RS232(DEBUGGER) 219 #use RS232(DEBUGGER)
220   220  
221 ... 221 ...
222   222  
223 printf(“Test to run? “); 223 printf(“Test to run? “);
224   224  
225 test=getc(); 225 test=getc();
226   226  
227 227
228   228  
229 For the PIC16 ICD the B3 pin is used on the target to implement this capability. The normal ICD cable is already set up correctly for this. 229 For the PIC16 ICD the B3 pin is used on the target to implement this capability. The normal ICD cable is already set up correctly for this.
230   230  
231 -=-=-=-= rs232-=-=-=- 231 -=-=-=-= rs232-=-=-=-
232 How can I use two or more RS-232 ports on one PIC®? 232 How can I use two or more RS-232 ports on one PIC®?
233   233  
234 The #USE RS232 (and I2C for that matter) is in effect for GETC, PUTC, PRINTF and KBHIT functions encountered until another #USE RS232 is found. 234 The #USE RS232 (and I2C for that matter) is in effect for GETC, PUTC, PRINTF and KBHIT functions encountered until another #USE RS232 is found.
235   235  
236 The #USE RS232 is not an executable line. It works much like a #DEFINE. 236 The #USE RS232 is not an executable line. It works much like a #DEFINE.
237   237  
238 The following is an example program to read from one RS-232 port (A) and echo the data to both the first RS-232 port (A) and a second RS-232 port (B). 238 The following is an example program to read from one RS-232 port (A) and echo the data to both the first RS-232 port (A) and a second RS-232 port (B).
239   239  
240 #USE RS232(BAUD=9600, XMIT=PIN_B0, RCV=PIN_B1) 240 #USE RS232(BAUD=9600, XMIT=PIN_B0, RCV=PIN_B1)
241 void put_to_a( char c ) { 241 void put_to_a( char c ) {
242 put(c); 242 put(c);
243 } 243 }
244   244  
245 char get_from_a( ) { 245 char get_from_a( ) {
246 return(getc()); } 246 return(getc()); }
247   247  
248 #USE RS232(BAUD=9600, XMIT=PIN_B2,RCV=PIN_B3) 248 #USE RS232(BAUD=9600, XMIT=PIN_B2,RCV=PIN_B3)
249 void put_to_b( char b ) { 249 void put_to_b( char b ) {
250 putc(c); 250 putc(c);
251 } 251 }
252   252  
253 main() { 253 main() {
254 char c; 254 char c;
255 put_to_a("Online\n\r"); 255 put_to_a("Online\n\r");
256 put_to_b("Online\n\r"); 256 put_to_b("Online\n\r");
257 while(TRUE) { 257 while(TRUE) {
258 c=get_from_a(); 258 c=get_from_a();
259 put_to_b(c); 259 put_to_b(c);
260 put_to_a(c); 260 put_to_a(c);
261 } 261 }
262 } 262 }
263   263  
264 The following will do the same thing but is less readable: 264 The following will do the same thing but is less readable:
265   265  
266 #USE RS232(BAUD=9600, XMIT=PIN_B0, RCV=PIN_B1, STREAM=COM_A) 266 #USE RS232(BAUD=9600, XMIT=PIN_B0, RCV=PIN_B1, STREAM=COM_A)
267 #USE RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B3, STREAM=COM_B) 267 #USE RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B3, STREAM=COM_B)
268   268  
269 main() { 269 main() {
270 char c; 270 char c;
271 fprintf(COM_A,"Online\n\r"); 271 fprintf(COM_A,"Online\n\r");
272 fprintf(COM_B,"Online\n\r"); 272 fprintf(COM_B,"Online\n\r");
273 while(TRUE) { 273 while(TRUE) {
274 c = fgetc(COM_A); 274 c = fgetc(COM_A);
275 fputc(c, COM_A); 275 fputc(c, COM_A);
276 fputc(c, COM_B); 276 fputc(c, COM_B);
277 } 277 }
278 } 278 }
279 -=-=--=-ICD-=-=-= 279 -=-=--=-ICD-=-=-=
280 How do I put a NOP at location 0 for the ICD? 280 How do I put a NOP at location 0 for the ICD?
281   281  
282 The CCS compilers are fully compatible with Microchips ICD debugger using MPLAB. In order to prepare a program for ICD debugging (NOP at location 0 and so on) you need to add a #DEVICE ICD=TRUE after your normal #DEVICE. 282 The CCS compilers are fully compatible with Microchips ICD debugger using MPLAB. In order to prepare a program for ICD debugging (NOP at location 0 and so on) you need to add a #DEVICE ICD=TRUE after your normal #DEVICE.
283   283  
284 For example: 284 For example:
285   285  
286 #INCLUDE <16F877.h> 286 #INCLUDE <16F877.h>
287 #DEVICE ICD=TRUE 287 #DEVICE ICD=TRUE