Pic16f887+enc28j60 using mikroc

Status
Not open for further replies.

Johnny_Churne

Newbie level 6
Joined
May 13, 2017
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
70
Hello all friends I am new to Enc28j60, is it possible to use PIC16F887 with Enc28j60? I tried the library that provide by Mikroc but it couldn't compile and don't understand the code .please help!
 

The ENC28J60 uses an SPI interface so, theoretically, any MCU that has an SPI Master peripheral can drive it.
Also, have you tried a quick search for information on both devices - there are lots of references.
Also look at the older Microchip peripheral library for code - both devices are from Microchip.
A word of caution: the ENC28J60 is not the simplest device to use without using a supplied library. Microchip do supply documentation on all of the registers but that just tells you the individual parts and not how to put them all together. However their library code is documented and fairly straight forward.
I've not used MikroC and my commented therefore do not apply to that toolchain.
Susan
 

As the library provided in mikroc is very complex, I really need the very simple code that may compile and send data and receive data to the internet.
 

I suspect that you may have conflicting requirements there: whether you use TCP or UDP, internet connections are, by their nature, not "simple".
If you want something at the level of "enter a URL and read a web page" then you may want something more than a simple library (which is probably designed to be fairly low level but allow a whole range of operations). However there is likely to be a lot of code that you will need to compile or link against.
On the other hand if you understand DHCP, TCP/UDP sockets and packets then the libraries that are provided (again, I know the Microchip IP stack which is at this level - MikroC may well be different) then you can get just get the parts you need and build on top of that.
One work of caution: the PIC16F887 only has 8K words of FLASH and 368 bytes of RAM - this may not be big enough to hold the IP stack and whatever code you may want to put over the top. The actual memory usage will depend on the components that you include.
If you are just starting out with microcontrollers then you probably want to start with something simpler. If you are experienced with microcontrollers but want to start learning about network connections, then you may want a bigger device.
Susan
 

Thank for the suggestion but I still need a guide just how to send and receive data form PIC any PIC family, with ENC28J60.
 

Assuming that you have a library that lets you access the ENC28J60 and provides you with functions that you can call to create a connection to the remote host, create a TCP packet and then send it, wait for a response and interpret it and so on, then you need to read up on how to create POST, GET and possibly PUT packets and how to parse the results from the web (and by this I assume you mean an HTTP) server.
There are multiple layers of code between the hardware and MAC (the ENC28J60 does this) and the application that you want.
Take each of these at a time and you will begin to understand how to build up the stack that you need.
Susan
 
So the PIC16 is a bit of a small micro for this type of stuff, however it is supported with restrictions. (PIC16 does not support all features that the PIC18 does.) I have never worked with MikroC, however here is a link that looks like a place I would start with.
https://www.studentcompanion.co.za/...t-controller-with-pic-microcontroller-mikroc/

I also saw online a possible example of someone else building a web server with a similar chip. (However I may recommend caution downloading it!)

I recommend starting simple, by building an application that transmits a UDP packet out to a computer that is listening on a custom port. Have the micro transmit a message like "Hello World!", if you can see that then you know the your library and hardware are in order. Also wireshark is really handy in times like this! Python, netcat and C code can be used to talk back, but that is for later on.

However this is the best I can do without code and schematics.
 
Now I got ENC28j60 and I test the library pic16f887 that mikroc provide but it does not work anything. even test in Proteus.
 

What does not work? Also what DOES work? We really need a better fault description than that.
Does the PIC send and receive SPI data and is the slave select in correctly synchronised?
Can you read and write register in the ENC28J60?
Is the PIC programmed correctly and can you debug the running code?
I could go on....
Susan
 

Firstly the mikroc library I can't debug it. the library given is for pic16f887.
I can't find the solution.
 

Always start with the first error message which, at least in the image you have posted, is that the compiler can't find an include file.
Check your IDE/Compiler setup and make sure that the file exists somewhere in the search path.
Susan
 

Maybe the file does not exist that why error, but why mikroc provide such a bad library like this? are there any way to go without mikroc library?
 

Look at the Microchip site for the MLA (Microchip library for Applications) which also has a library for the chip. It is still not trivial to use and you must read the various app notes that apply to the IP stack.
Susan
 

I found the library and example in mikroc and test it, it doesn't work. just in case I need hex file for testing in proteus to be sure it works. Then will check the source code.
 

You are doing something wrong.

I have mikroC PRO and it has a ETHERNET example for PIC16F887.

Here is the code:


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
                 */
                }
        }




It compiles OK for me! No errors.

Code:
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

Are you sure that you have correctly created project?
 

I do using Mikroc Pro and using it library sample SPI Enthernet and choose pic16f887 load hex file to pic16f887 in proteus. and even in real hardware, but the result nothing. please any one have success on that help me.
 

1. Did you compile without errors?
2. Did you setup correct IP stuff?


Code:
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 ;

you must change myIpAddr to the IP on your network.


Are you using windows? Press WINDOWS + R, then type "cmd", then "ipconfig /all" and show us result... you need to set myIpAddr to something accessible on your local network
 

Yes I do success compile the code. yes I do change IP.
 

Attachments

  • Screen Shot 2017-07-05 at 5.18.43 PM.png
    146.6 KB · Views: 144

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…