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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 /* * Project Name: enc28j60Demo (Ethernet Library demo for ENC28J60 mcu) * Target Platform: PIC * Copyright: (c) MikroElektronika, 2012. * Revision History: 20060810: - Initial release. Author: Bruno Gavand. * * V1.0 : first release * V1.1 : bad MIME type for / path request, changed to HTML instead of SCRIPT (thanks Srdjan !) * * description : * this code shows how to use the Spi_Ethernet mini library : * the board will reply to ARP & ICMP echo requests * the board will reply to UDP requests on any port : * returns the request in upper char with a header made of remote host IP & port number * the board will reply to HTTP requests on port 80, GET method with pathnames : * / will return the HTML main page * /s will return board status as text string * /t0 ... /t7 will toggle RD0 to RD7 bit and return HTML main page * all other requests return also HTML main page * * target devices : * any PIC with integrated SPI and more than 4 Kb ROM memory * 32 to 40 MHz clock is recommended to get from 8 to 10 Mhz SPI clock, * otherwise PIC should be clocked by ENC clock output due to ENC silicon bug in SPI hardware * if you try lower PIC clock speed, don't be surprised if the board hang or miss some requests ! * * EP settings : * AN2 & AN3 pots jumper on Potentiometer Board : closed * PORTB : pull-down (place jumper J2 to lower position) (board specific) * * RC0 : !RESET to ENC reset input pin * RC1 : !CS to ENC chip select input pin * the ENC28J60 SPI bus CLK, SO, SI must be connected to the corresponding SPI pins of the PIC * the INT and WOL signals from the ENC are not used * * Test configuration: MCU: PIC16F887 [url]https://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf[/url] Dev.Board: EasyPIC7 [url]https://www.mikroe.com/easypic/[/url] Oscillator: HS, 08.000MHz Ext. Modules: ac:Serial_Ethernet_Board ac:Potentiometer_Board SW: mikroC PRO for PIC [url]https://www.mikroe.com/mikroc/pic/[/url] * NOTES: - Make sure that you use right compiler version with this project (v6.2 and older). Spi ethernet library routines are renamed from (v6.0)ENC28j60... to (v6.2)Spi_Ethernet... - Since the ENC28J60 doesn't support auto-negotiation, full-duplex mode is not compatible with most switches/routers. If a dedicated network is used where the duplex of the remote node can be manually configured, you may change this configuration. Otherwise, half duplex should always be used. - External power supply should be used due to Serial Ethernet Board power consumption. */ #include "__EthEnc28j60.h" // duplex config flags #define Spi_Ethernet_HALFDUPLEX 0x00 // half duplex #define Spi_Ethernet_FULLDUPLEX 0x01 // full duplex // mE ehternet NIC pinout sfr sbit SPI_Ethernet_Rst at RC0_bit; sfr sbit SPI_Ethernet_CS at RC1_bit; sfr sbit SPI_Ethernet_Rst_Direction at TRISC0_bit; sfr sbit SPI_Ethernet_CS_Direction at TRISC1_bit; // end ethernet NIC definitions /************************************************************ * ROM constant strings */ const unsigned char httpHeader[] = "HTTP/1.1 200 OK\nContent-type: " ; // HTTP header const unsigned char httpMimeTypeHTML[] = "text/html\n\n" ; // HTML MIME type const unsigned char httpMimeTypeScript[] = "text/plain\n\n" ; // TEXT MIME type unsigned char httpMethod[] = "GET /"; /* * web page, splited into 2 parts : * when coming short of ROM, fragmented data is handled more efficiently by linker * * this HTML page calls the boards to get its status, and builds itself with javascript */ const char *indexPage = // Change the IP address of the page to be refreshed "<meta http-equiv="refresh" content="3;url=http://10.101.14.52">\ <HTML><HEAD></HEAD><BODY>\ <h1>PIC + ENC28J60 Mini Web Server</h1>\ <a href=/>Reload</a>\ <script src=/s></script>\ <table><tr><td valign=top><table border=1 style="font-size:20px ;font-family: terminal ;">\ <tr><th colspan=2>ADC</th></tr>\ <tr><td>AN2</td><td><script>document.write(AN2)</script></td></tr>\ <tr><td>AN3</td><td><script>document.write(AN3)</script></td></tr>\ </table></td><td><table border=1 style="font-size:20px ;font-family: terminal ;">\ <tr><th colspan=2>PORTB</th></tr>\ <script>\ var str,i;\ str="";\ for(i=0;i<8;i++)\ {str+="<tr><td bgcolor=pink>BUTTON #"+i+"</td>";\ if(PORTB&(1<<i)){str+="<td bgcolor=red>ON";}\ else {str+="<td bgcolor=#cccccc>OFF";}\ str+="</td></tr>";}\ document.write(str) ;\ </script>\ " ; const char *indexPage2 = "</table></td><td>\ <table border=1 style="font-size:20px ;font-family: terminal ;">\ <tr><th colspan=3>PORTD</th></tr>\ <script>\ var str,i;\ str="";\ for(i=0;i<8;i++)\ {str+="<tr><td bgcolor=yellow>LED #"+i+"</td>";\ if(PORTD&(1<<i)){str+="<td bgcolor=red>ON";}\ else {str+="<td bgcolor=#cccccc>OFF";}\ str+="</td><td><a href=/t"+i+">Toggle</a></td></tr>";}\ document.write(str) ;\ </script>\ </table></td></tr></table>\ This is HTTP request #<script>document.write(REQ)</script></BODY></HTML>\ " ; /*********************************** * RAM variables */ unsigned char myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f} ; // my MAC address unsigned char myIpAddr[4] = {10, 101, 14, 52} ; // my IP address unsigned char getRequest[15] ; // HTTP request buffer unsigned char dyna[30] ; // buffer for dynamic response unsigned long httpCounter = 0 ; // counter of HTTP requests /******************************************* * functions */ /* * put the constant string pointed to by s to the ENC transmit buffer. */ /*unsigned int putConstString(const char *s) { unsigned int ctr = 0 ; while(*s) { Spi_Ethernet_putByte(*s++) ; ctr++ ; } return(ctr) ; }*/ /* * it will be much faster to use library Spi_Ethernet_putConstString routine * instead of putConstString routine above. However, the code will be a little * bit bigger. User should choose between size and speed and pick the implementation that * suites him best. If you choose to go with the putConstString definition above * the #define line below should be commented out. * */ #define putConstString SPI_Ethernet_putConstString /* * put the string pointed to by s to the ENC transmit buffer */ /*unsigned int putString(char *s) { unsigned int ctr = 0 ; while(*s) { Spi_Ethernet_putByte(*s++) ; ctr++ ; } return(ctr) ; }*/ /* * it will be much faster to use library Spi_Ethernet_putString routine * instead of putString routine above. However, the code will be a little * bit bigger. User should choose between size and speed and pick the implementation that * suites him best. If you choose to go with the putString definition above * the #define line below should be commented out. * */ #define putString SPI_Ethernet_putString /* * this function is called by the library * the user accesses to the HTTP request by successive calls to Spi_Ethernet_getByte() * the user puts data in the transmit buffer by successive calls to Spi_Ethernet_putByte() * the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit * * if you don't need to reply to HTTP requests, * just define this function with a return(0) as single statement * */ unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags) { unsigned int len = 0 ; // my reply length unsigned int i ; // general purpose integer // should we close tcp socket after response is sent? // library closes tcp socket by default if canClose flag is not reset here // flags->canClose = 0; // 0 - do not close socket // otherwise - close socket if(localPort != 80) // I listen only to web request on port 80 { return(0) ; } // get 10 first bytes only of the request, the rest does not matter here for(i = 0 ; i < 10 ; i++) { getRequest[i] = SPI_Ethernet_getByte() ; } getRequest[i] = 0 ; if(memcmp(getRequest, httpMethod, 5)) // only GET method is supported here { return(0) ; } httpCounter++ ; // one more request done if(getRequest[5] == 's') // if request path name starts with s, store dynamic data in transmit buffer { // the text string replied by this request can be interpreted as javascript statements // by browsers len = putConstString(httpHeader) ; // HTTP header len += putConstString(httpMimeTypeScript) ; // with text MIME type // add AN2 value to reply IntToStr(ADC_Read(2), dyna) ; len += putConstString("var AN2=") ; len += putString(dyna) ; len += putConstString(";") ; // add AN3 value to reply IntToStr(ADC_Read(3), dyna) ; len += putConstString("var AN3=") ; len += putString(dyna) ; len += putConstString(";") ; // add PORTB value (buttons) to reply len += putConstString("var PORTB=") ; IntToStr(PORTB, dyna) ; len += putString(dyna) ; len += putConstString(";") ; // add PORTD value (LEDs) to reply len += putConstString("var PORTD=") ; IntToStr(PORTD, dyna) ; len += putString(dyna) ; len += putConstString(";") ; // add HTTP requests counter to reply IntToStr(httpCounter, dyna) ; len += putConstString("var REQ=") ; len += putString(dyna) ; len += putConstString(";") ; } else if(getRequest[5] == 't') // if request path name starts with t, toggle PORTD (LED) bit number that comes after { unsigned char bitMask = 0 ; // for bit mask if(isdigit(getRequest[6])) // if 0 <= bit number <= 9, bits 8 & 9 does not exist but does not matter { bitMask = getRequest[6] - '0' ; // convert ASCII to integer bitMask = 1 << bitMask ; // create bit mask PORTD ^= bitMask ; // toggle PORTD with xor operator } } if(len == 0) // what do to by default { len = putConstString(httpHeader) ; // HTTP header len += putConstString(httpMimeTypeHTML) ; // with HTML MIME type len += putConstString(indexPage) ; // HTML page first part len += putConstString(indexPage2) ; // HTML page second part } return(len) ; // return to the library with the number of bytes to transmit } /* * this function is called by the library * the user accesses to the UDP request by successive calls to Spi_Ethernet_getByte() * the user puts data in the transmit buffer by successive calls to Spi_Ethernet_putByte() * the function must return the length in bytes of the UDP reply, or 0 if nothing to transmit * * if you don't need to reply to UDP requests, * just define this function with a return(0) as single statement * */ unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags) { unsigned int len ; // my reply length // reply is made of the remote host IP address in human readable format ByteToStr(remoteHost[0], dyna) ; // first IP address byte dyna[3] = '.' ; ByteToStr(remoteHost[1], dyna + 4) ; // second dyna[7] = '.' ; ByteToStr(remoteHost[2], dyna + 8) ; // third dyna[11] = '.' ; ByteToStr(remoteHost[3], dyna + 12) ; // fourth dyna[15] = ':' ; // add separator // then remote host port number WordToStr(remotePort, dyna + 16) ; dyna[21] = '[' ; WordToStr(destPort, dyna + 22) ; dyna[27] = ']' ; dyna[28] = 0 ; // the total length of the request is the length of the dynamic string plus the text of the request len = 28 + reqLength; // puts the dynamic string into the transmit buffer SPI_Ethernet_putBytes(dyna, 28) ; // then puts the request string converted into upper char into the transmit buffer while(reqLength--) { SPI_Ethernet_putByte(toupper(SPI_Ethernet_getByte())) ; } return(len) ; // back to the library with the length of the UDP reply } /* * main entry */ void main() { ANSEL = 0x0C ; // AN2 and AN3 convertors will be used C1ON_bit = 0; // Disable comparators C2ON_bit = 0; PORTA = 0 ; TRISA = 0xff ; // set PORTA as input for ADC ANSELH = 0; // Configure other AN pins as digital I/O PORTB = 0 ; TRISB = 0xff ; // set PORTB as input for buttons PORTD = 0 ; TRISD = 0 ; // set PORTD as output /* * starts ENC28J60 with : * reset bit on RC0 * CS bit on RC1 * my MAC & IP address * full duplex */ SPI1_Init(); SPI_Ethernet_Init(myMacAddr, myIpAddr, Spi_Ethernet_FULLDUPLEX) ; while(1) // do forever { /* * if necessary, test the return value to get error code */ SPI_Ethernet_doPacket() ; // process incoming Ethernet packets /* * add your stuff here if needed * Spi_Ethernet_doPacket() must be called as often as possible * otherwise packets could be lost */ } }
0 1 mikroCPIC1618.exe -MSF -DBG -pP16F887 -DL -O11111110 -fo8 -N"C:\Mikroelektronika\mikroC PRO for PIC\Examples\Extra Boards\SPI Ethernet\p16\HTTP Demo\HTTP_Demo.mcppi" -SP"C:\Mikroelektronika\mikroC PRO for PIC\Defs\" -SP"C:\Mikroelektronika\mikroC PRO for PIC\Uses\P16\" -SP"C:\Mikroelektronika\mikroC PRO for PIC\Examples\Extra Boards\SPI Ethernet\p16\HTTP Demo\" "HTTP_Demo.c" "__Lib_Math.mcl" "__Lib_MathDouble.mcl" "__Lib_System.mcl" "__Lib_Delays.mcl" "__Lib_CType.mcl" "__Lib_CString.mcl" "__Lib_CStdlib.mcl" "__Lib_Conversions.mcl" "__Lib_ADC_88X.mcl" "__Lib_SPI_c345.mcl" "__Lib_EthEnc28j60.mcl"
0 1139 Available RAM: 352 [bytes], Available ROM: 8192 [bytes]
0 122 Compilation Started P16F887.c
973 123 Compiled Successfully P16F887.c
0 122 Compilation Started __ethenc28j60.h
377 123 Compiled Successfully HTTP_Demo.c
0 127 All files Compiled in 94 ms
0 1144 Used RAM (bytes): 204 (58%) Free RAM (bytes): 148 (42%) Used RAM (bytes): 204 (58%) Free RAM (bytes): 148 (42%)
0 1144 Used ROM (program words): 6731 (82%) Free ROM (program words): 1461 (18%) Used ROM (program words): 6731 (82%) Free ROM (program words): 1461 (18%)
0 125 Project Linked Successfully HTTP_Demo.mcppi
0 128 Linked in 78 ms
0 129 Project 'HTTP_Demo.mcppi' completed: 328 ms
0 103 Finished successfully: 05 Jul 2017, 00:56:10 HTTP_Demo.mcppi
unsigned char myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f} ; // my MAC address
unsigned char myIpAddr[4] = {10, 101, 14, 52} ; // my IP address
unsigned char getRequest[15] ; // HTTP request buffer
unsigned char dyna[30] ; // buffer for dynamic response
unsigned long httpCounter = 0 ;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?