Giao tiếp giữa Ethernet và Pic
Mình đang làm giao tiếp về Ethernet và Pic, mình dùng MikroC để program cho Pic 16F877A, thông qua con ENC28J60. Nhưng mình chưa hiểu rõ việc kết nối giữa Pic và WebServer diễn ra như thế nào. Giả sử trong chương trình gửi một Byte lên từ PortD, vậy làm sao để Web biết được để hiển thị ra ngoài. Đây là Code của nó.
Em dùng Code này download xuống Pic nhưng khi truy cập vào địa chỉ đã assign cho Pic thì không thấy kết quả gì xảy ra.Mong các bạn giúp đỡ!!!! Cảm ơn các bạn nhiều. Code:
/* |
Ban phai cho ca nguon luon
minh moi biet ma chia sua chu Lần sau đồng chí nhớ gõ tiếng việt nhé edit phamminhtuan |
mikroC
mình nạp mã vào chương trình mikroC v6.2 biên dịch chương trình báo lỗi demo limit
nhưng khi xóa lệnh spi_ethernet_dopacket(); thì không báo lỗi . mình không biết làm thế nào để hàm spi_ethernet_dopacket(); không báo lỗi mong các bạn giải thích. thank!! |
Trích:
|
/*code
/* * file : ethdemo.c * project : ENC28J60 SPI ETHERNET LIBRARY DEMO * author : Bruno Gavand * compiler : mikroC V6.2 * date : october 27, 2006 * * description : * This program shows how to use undocumented mikroC Spi Ethernet functions * This example is an UDP push server : * * Start Ethernet services with ARP and PING reply * Listen to the UDP port 33000 for an incoming request : * 'b' will start the push * 'e' will stop the stop * any other incoming char has no effect * If push is enabled : * send to the remote UDP host a string with PORTB value one time per second * * target device : * Tested with PIC18F452 and PIC18F4620 @ 32 Mhz (8 Mhz crystal + HS PLL) * * Licence : * Feel free to use this source code at your own risks. * * history : october 30, 2006 : ARP cache management, little bug fixed. Thanks Philippe ! * * see more details on http://www.micro-examples.com/ */ #define NULL 0 #define Spi_Ethernet_FULLDUPLEX 1 #define TRANSMIT_START 0x19AE #define REPLY_START (TRANSMIT_START + 1) // reply buffer starts after per packet control byte // some ENC28J60 registers, see datasheet #define ERDPTL 0x00 #define ERDPTH 0x01 #define ECON1 0x1f #define EDMACSL 0x16 #define EDMACSH 0x17 /*********************************** * RAM variables */ unsigned char macAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f} ; // my MAC address unsigned char ipAddr[4] = {192, 168, 1, 101} ; // my IP address unsigned char destIpAddr[4] ; // IP address unsigned char transmit = 0 ; unsigned char tmr = 0 ; unsigned long longTmr = 0 ; unsigned int destPortNum = 0 ; char udpStr[16] = "PORTB=" ; #define ARPCACHELEN 3 struct { unsigned char valid ; unsigned long tmr ; unsigned char ip[4] ; unsigned char mac[6] ; } arpCache[ARPCACHELEN] ; /******************************************* * functions */ /* * ARP resolution * this function returns the MAC address of an IP address * an ARP cache is used */ unsigned char *arpResolv(unsigned char *ip) { unsigned char i ; // general purpose register unsigned int rdptr ; // backup of ENC read pointer register unsigned char freeSlot ; // index of free slot in ARP cache unsigned long tmrSlot ; // oldest slot timer in ARP cache tmrSlot = 0xffffffff ; // will try to find less than this ! // step in ARP cache for(i = 0 ; i < ARPCACHELEN; i++) { // oldest slots must expire if(arpCache[i].tmr < longTmr - 1000) // too old ? { arpCache[i].tmr = 0 ; // clear timer arpCache[i].valid = 0 ; // disable slot } // is it the address I want in a valid slot ? if(arpCache[i].valid && (memcmp(arpCache[i].ip, ip, 4) == 0)) { return(arpCache[i].mac) ; // yes, return ready to use MAC addr } // find older slot, will be needed further if(arpCache[i].tmr < tmrSlot) { tmrSlot = arpCache[i].tmr ; // save best timer freeSlot = i ; // save best index } } // select ENC register bank 0 Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /*************************** * first, build eth header */ Spi_Ethernet_memcpy(REPLY_START, "\xff\xff\xff\xff\xff\xff", 6) ; // destination is broadcast Spi_Ethernet_memcpy(REPLY_START + 6, macAddr, 6) ; // source : my mac addr Spi_Ethernet_writeMemory(REPLY_START + 12, 8, 6, 1) ; // protocol is ARP /**************************** * second, build ARP packet */ /* * 0, 1 : hardware type = ethernet * 8, 0 : protocole type = ip * 6, 4 : HW size = 6, protocol size = 4 * 0, 1 : ARP opcode = request */ Spi_Ethernet_memcpy(REPLY_START + 14, "\x0\x01\x08\x00\x06\x04\x00\x01", 8) ; Spi_Ethernet_memcpy(REPLY_START + 22, macAddr, 6) ; // mac addr source Spi_Ethernet_memcpy(REPLY_START + 28, ipAddr, 4) ; // ip addr source Spi_Ethernet_memcpy(REPLY_START + 32, "\0\0\0\0\0\0", 6) ; // mac addr destination : broadcast addr Spi_Ethernet_memcpy(REPLY_START + 38, ip, 4) ; // who has this ip addr ? /************************************************** ***************** * third, send packet over wires, ARP request packet is 42 bytes len */ Spi_Ethernet_txPacket(42) ; tmr = 0 ; while(tmr < 45) // allows around 3 seconds for reply { Spi_Ethernet_doPacket() ; // do not stop eth services ! // select ENC register bank 0, may have been changed by library Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /* * ERDPT[H|L] registers are used by library : * always save them before doing anything else ! */ rdptr = (Spi_Ethernet_readReg(ERDPTH) << 8) + Spi_Ethernet_readReg(ERDPTL) ; /* * check if packet is ARP reply to my request (last byte = 2 means ARP reply) */ if((Spi_Ethernet_memcmp(REPLY_START + 12, "\x08\x06\x00\x01\x08\x00\x06\x04\x00\x02", 10) == 0) && (Spi_Ethernet_memcmp(REPLY_START, macAddr, 6) == 0) // is it my MAC addr ? && (Spi_Ethernet_memcmp(REPLY_START + 28, ip, 4) == 0) // is it my IP addr ? ) { /* * save remote MAC addr in a free slot of the cache */ // copy MAC addr arpCache[freeSlot].mac[0] = Spi_Ethernet_readMem(REPLY_START + 22) ; arpCache[freeSlot].mac[1] = Spi_Ethernet_readMem(REPLY_START + 23) ; arpCache[freeSlot].mac[2] = Spi_Ethernet_readMem(REPLY_START + 24) ; arpCache[freeSlot].mac[3] = Spi_Ethernet_readMem(REPLY_START + 25) ; arpCache[freeSlot].mac[4] = Spi_Ethernet_readMem(REPLY_START + 26) ; arpCache[freeSlot].mac[5] = Spi_Ethernet_readMem(REPLY_START + 27) ; // copy IP addr memcpy(arpCache[freeSlot].ip, ip, 4) ; // enable slot arpCache[freeSlot].valid = 1 ; // timestamp arpCache[freeSlot].tmr = longTmr ; // restore ERDPT before exiting Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; // return the MAC addr pointer return(arpCache[freeSlot].mac) ; } // restore ERDPT before doing a new call to the library Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; } // failed, no response : MAC addr is null return((unsigned char *)NULL) ; } /* * send an UDP packet : * destIp : remote host IP address * sourcePort : local UDP source port number * destPort : destination UDP port number * pkt : pointer to packet to transmit * pktLen : length in bytes of packet to transmit */ void sendUDP(unsigned char *destIP, unsigned int sourcePort, unsigned int destPort, unsigned char *pkt, unsigned int pktLen) { unsigned char *destMac ; // destination MAC addr static int idUniq ; // uniq packet id (serial number) unsigned char align ; // alignement flag unsigned int totlen ; // total packet length unsigned int rdptr ; // ENC read pointer backup // is destination port valid ? if(destPort == 0) { return ; // no, do nothing } // does destination IP address exist ? if((destMac = arpResolv(destIP)) == NULL) { return ; // no MAC addr matches, do nothing } // select ENC register bank 0 Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /* * ERDPT[H|L] registers are used by library : * always save them before doing anything else ! */ rdptr = (Spi_Ethernet_readReg(ERDPTH) << 8) + Spi_Ethernet_readReg(ERDPTL) ; /************************** * first, build eth header */ Spi_Ethernet_memcpy(REPLY_START, destMAC, 6) ; // destination Spi_Ethernet_memcpy(REPLY_START + 6, macAddr, 6) ; // source Spi_Ethernet_writeMemory(REPLY_START + 12, 8, 0, 1) ; // IP type /************************** * second, build IP header */ totlen = 20 + 8 + pktLen ; Spi_Ethernet_writeMemory(REPLY_START + 14, 0x45, 0, 1) ; // IPV4, IHL = 20 bytes, TOS = 0 Spi_Ethernet_writeMemory(REPLY_START + 16, totlen >> 8, totlen, 1) ; // total packet length Spi_Ethernet_memcpy(REPLY_START + 18, (char *)&(idUniq++), 2) ; // identification Spi_Ethernet_writeMemory(REPLY_START + 20, 0, 0, 1) ; // flags + 0, fragment offset = 0, TTL = 128, protocol = UDP Spi_Ethernet_writeMemory(REPLY_START + 22, 0x80, 0x11, 1) ; // flags + 0, fragment offset = 0, TTL = 128, protocol = UDP Spi_Ethernet_writeMemory(REPLY_START + 24, 0, 0, 1) ; // clear IP checksum Spi_Ethernet_memcpy(REPLY_START + 26, ipAddr, 4) ; // source Spi_Ethernet_memcpy(REPLY_START + 30, destIP, 4) ; // destination /*************************** * third, build UDP header */ totlen = pktLen + 8 ; Spi_Ethernet_writeMemory(REPLY_START + 34, sourcePort >> 8, sourcePort, 1) ; // source port Spi_Ethernet_writeMemory(REPLY_START + 36, destPort >> 8, destPort, 1) ; // destination port Spi_Ethernet_writeMemory(REPLY_START + 38, totlen >> 8, totlen, 1) ; // packet length Spi_Ethernet_writeMemory(REPLY_START + 40, 0, 0, 1) ; // clear UDP checksum Spi_Ethernet_memcpy(REPLY_START + 42, pkt, pktLen) ; // payload /***************** * fourth, IP checksum */ Spi_Ethernet_checksum(REPLY_START + 14, 20) ; Spi_Ethernet_writeMemory(REPLY_START + 24, Spi_Ethernet_readReg(EDMACSH), Spi_Ethernet_readReg(EDMACSL), 1) ; /***************** * fifth, UDP checksum */ // pseudo header // word alignement align = totlen & 1 ; Spi_Ethernet_writeMemory(REPLY_START + 42 + pktLen, 0, 0, 0) ; // clear // build pseudo header Spi_Ethernet_RAMcopy(REPLY_START + 26, REPLY_START + 26 + 8, REPLY_START + 42 + pktLen + align, 0) ; Spi_Ethernet_writeMemory(REPLY_START + 42 + pktLen + align + 8, 0, 17, 1) ; Spi_Ethernet_putByte(totlen >> 8) ; Spi_Ethernet_putByte(totlen) ; // ready for checksum Spi_Ethernet_checksum(REPLY_START + 34, totlen + 12 + align) ; Spi_Ethernet_writeMemory(REPLY_START + 40, Spi_Ethernet_readReg(EDMACSH), Spi_Ethernet_readReg(EDMACSL), 1) ; /************************** * sixth, send packet over wires */ Spi_Ethernet_txPacket(42 + pktLen) ; // restore ERDPT registers before exiting Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; } /* * no TCP */ unsigned int Spi_Ethernet_userTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength) { return(0) ; } /* * save remote UDP host and port number, then reply with 'Start' */ unsigned int Spi_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength) { if(destPort != 33000) return(0) ; // service is on port 33000 switch(Spi_Ethernet_getByte()) { // begin command case 'b': case 'B': transmit = 1 ; // set transmission flag memcpy(destIPAddr, remoteHost, 4) ; // save remote host IP addr destPortNum = remotePort ; // save remote host port number Spi_Ethernet_putByte('B') ; // reply with 'Begin' string Spi_Ethernet_putByte('e') ; Spi_Ethernet_putByte('g') ; Spi_Ethernet_putByte('i') ; Spi_Ethernet_putByte('n') ; return(5) ; // 5 bytes to transmit // end command case 'e': case 'E': transmit = 0 ; // clear transmission flag Spi_Ethernet_putByte('E') ; // reply with 'End' Spi_Ethernet_putByte('n') ; Spi_Ethernet_putByte('d') ; return(3) ; // 3 bytes to transmit // error default: Spi_Ethernet_putByte('?') ; return(1) ; } } /* * timers tmr and longTmr are incremented Fosc / 4 / 65536 / TMR1prescaler * TMR1prescaler is 8 (see main) * about 15.25 times per second with 32 Mhz clock */ void interrupt() { if(PIR1.TMR1IF) // timer1 overflow ? { tmr++ ; // increment timers longTmr++ ; PIR1.TMR1IF = 0 ; // clear timer1 overflow flag } } /* * main entry */ void main() { PORTB = 0 ; TRISB = 0xff ; // set PORTB as input PORTC = 0 ; TRISC = 0b11011100 ; // set PORTC as input except for bits 0 (RESET) and 1 (CS) T1CON = 0b10110101 ; // 16 bits, from other source, prescaler 1:8, oscillator disabled, not synchronized, internal clock, enabled PIR1.TMR1IF = 0 ; // clear TMR1 overflow interrupt flag PIE1.TMR1IE = 1 ; // enable interrupt on TMR1 overflow INTCON |= 0b11000000 ; // enable global & peripheral interrupts // init ARP cache memset(&arpCache, 0, sizeof(arpCache)) ; /* * starts Spi_Ethernet with : * reset bit on RC0, * CS bit on RC1, * my MAC & IP address, * full duplex */ Spi_Init() ; Spi_Ethernet_Init(&PORTC, 0, &PORTC, 1, macAddr, ipAddr, Spi_Ethernet_FULLDUPLEX) ; while(1) // do forever { Spi_Ethernet_doPacket() ; // process incoming Ethernet packets if(transmit && (tmr > 15)) // transmit one UDP packet per second { ByteToStr(PORTB, udpStr + 6) ; // read PORTB value and convert to string sendUDP(destIpAddr, 3456, destPortNum, udpStr, sizeof(udpStr)) ; // send to remote host tmr = 0 ; // reset timer } } } |
/*code
/* * file : ethdemo.c * project : ENC28J60 SPI ETHERNET LIBRARY DEMO * author : Bruno Gavand * compiler : mikroC V6.2 * date : october 27, 2006 * * description : * This program shows how to use undocumented mikroC Spi Ethernet functions * This example is an UDP push server : * * Start Ethernet services with ARP and PING reply * Listen to the UDP port 33000 for an incoming request : * 'b' will start the push * 'e' will stop the stop * any other incoming char has no effect * If push is enabled : * send to the remote UDP host a string with PORTB value one time per second * * target device : * Tested with PIC18F452 and PIC18F4620 @ 32 Mhz (8 Mhz crystal + HS PLL) * * Licence : * Feel free to use this source code at your own risks. * * history : october 30, 2006 : ARP cache management, little bug fixed. Thanks Philippe ! * * see more details on http://www.micro-examples.com/ */ #define NULL 0 #define Spi_Ethernet_FULLDUPLEX 1 #define TRANSMIT_START 0x19AE #define REPLY_START (TRANSMIT_START + 1) // reply buffer starts after per packet control byte // some ENC28J60 registers, see datasheet #define ERDPTL 0x00 #define ERDPTH 0x01 #define ECON1 0x1f #define EDMACSL 0x16 #define EDMACSH 0x17 /*********************************** * RAM variables */ unsigned char macAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f} ; // my MAC address unsigned char ipAddr[4] = {192, 168, 1, 101} ; // my IP address unsigned char destIpAddr[4] ; // IP address unsigned char transmit = 0 ; unsigned char tmr = 0 ; unsigned long longTmr = 0 ; unsigned int destPortNum = 0 ; char udpStr[16] = "PORTB=" ; #define ARPCACHELEN 3 struct { unsigned char valid ; unsigned long tmr ; unsigned char ip[4] ; unsigned char mac[6] ; } arpCache[ARPCACHELEN] ; /******************************************* * functions */ /* * ARP resolution * this function returns the MAC address of an IP address * an ARP cache is used */ unsigned char *arpResolv(unsigned char *ip) { unsigned char i ; // general purpose register unsigned int rdptr ; // backup of ENC read pointer register unsigned char freeSlot ; // index of free slot in ARP cache unsigned long tmrSlot ; // oldest slot timer in ARP cache tmrSlot = 0xffffffff ; // will try to find less than this ! // step in ARP cache for(i = 0 ; i < ARPCACHELEN; i++) { // oldest slots must expire if(arpCache[i].tmr < longTmr - 1000) // too old ? { arpCache[i].tmr = 0 ; // clear timer arpCache[i].valid = 0 ; // disable slot } // is it the address I want in a valid slot ? if(arpCache[i].valid && (memcmp(arpCache[i].ip, ip, 4) == 0)) { return(arpCache[i].mac) ; // yes, return ready to use MAC addr } // find older slot, will be needed further if(arpCache[i].tmr < tmrSlot) { tmrSlot = arpCache[i].tmr ; // save best timer freeSlot = i ; // save best index } } // select ENC register bank 0 Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /*************************** * first, build eth header */ Spi_Ethernet_memcpy(REPLY_START, "\xff\xff\xff\xff\xff\xff", 6) ; // destination is broadcast Spi_Ethernet_memcpy(REPLY_START + 6, macAddr, 6) ; // source : my mac addr Spi_Ethernet_writeMemory(REPLY_START + 12, 8, 6, 1) ; // protocol is ARP /**************************** * second, build ARP packet */ /* * 0, 1 : hardware type = ethernet * 8, 0 : protocole type = ip * 6, 4 : HW size = 6, protocol size = 4 * 0, 1 : ARP opcode = request */ Spi_Ethernet_memcpy(REPLY_START + 14, "\x0\x01\x08\x00\x06\x04\x00\x01", 8) ; Spi_Ethernet_memcpy(REPLY_START + 22, macAddr, 6) ; // mac addr source Spi_Ethernet_memcpy(REPLY_START + 28, ipAddr, 4) ; // ip addr source Spi_Ethernet_memcpy(REPLY_START + 32, "\0\0\0\0\0\0", 6) ; // mac addr destination : broadcast addr Spi_Ethernet_memcpy(REPLY_START + 38, ip, 4) ; // who has this ip addr ? /************************************************** ***************** * third, send packet over wires, ARP request packet is 42 bytes len */ Spi_Ethernet_txPacket(42) ; tmr = 0 ; while(tmr < 45) // allows around 3 seconds for reply { Spi_Ethernet_doPacket() ; // do not stop eth services ! // select ENC register bank 0, may have been changed by library Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /* * ERDPT[H|L] registers are used by library : * always save them before doing anything else ! */ rdptr = (Spi_Ethernet_readReg(ERDPTH) << 8) + Spi_Ethernet_readReg(ERDPTL) ; /* * check if packet is ARP reply to my request (last byte = 2 means ARP reply) */ if((Spi_Ethernet_memcmp(REPLY_START + 12, "\x08\x06\x00\x01\x08\x00\x06\x04\x00\x02", 10) == 0) && (Spi_Ethernet_memcmp(REPLY_START, macAddr, 6) == 0) // is it my MAC addr ? && (Spi_Ethernet_memcmp(REPLY_START + 28, ip, 4) == 0) // is it my IP addr ? ) { /* * save remote MAC addr in a free slot of the cache */ // copy MAC addr arpCache[freeSlot].mac[0] = Spi_Ethernet_readMem(REPLY_START + 22) ; arpCache[freeSlot].mac[1] = Spi_Ethernet_readMem(REPLY_START + 23) ; arpCache[freeSlot].mac[2] = Spi_Ethernet_readMem(REPLY_START + 24) ; arpCache[freeSlot].mac[3] = Spi_Ethernet_readMem(REPLY_START + 25) ; arpCache[freeSlot].mac[4] = Spi_Ethernet_readMem(REPLY_START + 26) ; arpCache[freeSlot].mac[5] = Spi_Ethernet_readMem(REPLY_START + 27) ; // copy IP addr memcpy(arpCache[freeSlot].ip, ip, 4) ; // enable slot arpCache[freeSlot].valid = 1 ; // timestamp arpCache[freeSlot].tmr = longTmr ; // restore ERDPT before exiting Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; // return the MAC addr pointer return(arpCache[freeSlot].mac) ; } // restore ERDPT before doing a new call to the library Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; } // failed, no response : MAC addr is null return((unsigned char *)NULL) ; } /* * send an UDP packet : * destIp : remote host IP address * sourcePort : local UDP source port number * destPort : destination UDP port number * pkt : pointer to packet to transmit * pktLen : length in bytes of packet to transmit */ void sendUDP(unsigned char *destIP, unsigned int sourcePort, unsigned int destPort, unsigned char *pkt, unsigned int pktLen) { unsigned char *destMac ; // destination MAC addr static int idUniq ; // uniq packet id (serial number) unsigned char align ; // alignement flag unsigned int totlen ; // total packet length unsigned int rdptr ; // ENC read pointer backup // is destination port valid ? if(destPort == 0) { return ; // no, do nothing } // does destination IP address exist ? if((destMac = arpResolv(destIP)) == NULL) { return ; // no MAC addr matches, do nothing } // select ENC register bank 0 Spi_Ethernet_clearBitReg(ECON1, 0b00000001) ; Spi_Ethernet_clearBitReg(ECON1, 0b00000010) ; /* * ERDPT[H|L] registers are used by library : * always save them before doing anything else ! */ rdptr = (Spi_Ethernet_readReg(ERDPTH) << 8) + Spi_Ethernet_readReg(ERDPTL) ; /************************** * first, build eth header */ Spi_Ethernet_memcpy(REPLY_START, destMAC, 6) ; // destination Spi_Ethernet_memcpy(REPLY_START + 6, macAddr, 6) ; // source Spi_Ethernet_writeMemory(REPLY_START + 12, 8, 0, 1) ; // IP type /************************** * second, build IP header */ totlen = 20 + 8 + pktLen ; Spi_Ethernet_writeMemory(REPLY_START + 14, 0x45, 0, 1) ; // IPV4, IHL = 20 bytes, TOS = 0 Spi_Ethernet_writeMemory(REPLY_START + 16, totlen >> 8, totlen, 1) ; // total packet length Spi_Ethernet_memcpy(REPLY_START + 18, (char *)&(idUniq++), 2) ; // identification Spi_Ethernet_writeMemory(REPLY_START + 20, 0, 0, 1) ; // flags + 0, fragment offset = 0, TTL = 128, protocol = UDP Spi_Ethernet_writeMemory(REPLY_START + 22, 0x80, 0x11, 1) ; // flags + 0, fragment offset = 0, TTL = 128, protocol = UDP Spi_Ethernet_writeMemory(REPLY_START + 24, 0, 0, 1) ; // clear IP checksum Spi_Ethernet_memcpy(REPLY_START + 26, ipAddr, 4) ; // source Spi_Ethernet_memcpy(REPLY_START + 30, destIP, 4) ; // destination /*************************** * third, build UDP header */ totlen = pktLen + 8 ; Spi_Ethernet_writeMemory(REPLY_START + 34, sourcePort >> 8, sourcePort, 1) ; // source port Spi_Ethernet_writeMemory(REPLY_START + 36, destPort >> 8, destPort, 1) ; // destination port Spi_Ethernet_writeMemory(REPLY_START + 38, totlen >> 8, totlen, 1) ; // packet length Spi_Ethernet_writeMemory(REPLY_START + 40, 0, 0, 1) ; // clear UDP checksum Spi_Ethernet_memcpy(REPLY_START + 42, pkt, pktLen) ; // payload /***************** * fourth, IP checksum */ Spi_Ethernet_checksum(REPLY_START + 14, 20) ; Spi_Ethernet_writeMemory(REPLY_START + 24, Spi_Ethernet_readReg(EDMACSH), Spi_Ethernet_readReg(EDMACSL), 1) ; /***************** * fifth, UDP checksum */ // pseudo header // word alignement align = totlen & 1 ; Spi_Ethernet_writeMemory(REPLY_START + 42 + pktLen, 0, 0, 0) ; // clear // build pseudo header Spi_Ethernet_RAMcopy(REPLY_START + 26, REPLY_START + 26 + 8, REPLY_START + 42 + pktLen + align, 0) ; Spi_Ethernet_writeMemory(REPLY_START + 42 + pktLen + align + 8, 0, 17, 1) ; Spi_Ethernet_putByte(totlen >> 8) ; Spi_Ethernet_putByte(totlen) ; // ready for checksum Spi_Ethernet_checksum(REPLY_START + 34, totlen + 12 + align) ; Spi_Ethernet_writeMemory(REPLY_START + 40, Spi_Ethernet_readReg(EDMACSH), Spi_Ethernet_readReg(EDMACSL), 1) ; /************************** * sixth, send packet over wires */ Spi_Ethernet_txPacket(42 + pktLen) ; // restore ERDPT registers before exiting Spi_Ethernet_writeAddr(ERDPTL, rdptr) ; } /* * no TCP */ unsigned int Spi_Ethernet_userTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength) { return(0) ; } /* * save remote UDP host and port number, then reply with 'Start' */ unsigned int Spi_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength) { if(destPort != 33000) return(0) ; // service is on port 33000 switch(Spi_Ethernet_getByte()) { // begin command case 'b': case 'B': transmit = 1 ; // set transmission flag memcpy(destIPAddr, remoteHost, 4) ; // save remote host IP addr destPortNum = remotePort ; // save remote host port number Spi_Ethernet_putByte('B') ; // reply with 'Begin' string Spi_Ethernet_putByte('e') ; Spi_Ethernet_putByte('g') ; Spi_Ethernet_putByte('i') ; Spi_Ethernet_putByte('n') ; return(5) ; // 5 bytes to transmit // end command case 'e': case 'E': transmit = 0 ; // clear transmission flag Spi_Ethernet_putByte('E') ; // reply with 'End' Spi_Ethernet_putByte('n') ; Spi_Ethernet_putByte('d') ; return(3) ; // 3 bytes to transmit // error default: Spi_Ethernet_putByte('?') ; return(1) ; } } /* * timers tmr and longTmr are incremented Fosc / 4 / 65536 / TMR1prescaler * TMR1prescaler is 8 (see main) * about 15.25 times per second with 32 Mhz clock */ void interrupt() { if(PIR1.TMR1IF) // timer1 overflow ? { tmr++ ; // increment timers longTmr++ ; PIR1.TMR1IF = 0 ; // clear timer1 overflow flag } } /* * main entry */ void main() { PORTB = 0 ; TRISB = 0xff ; // set PORTB as input PORTC = 0 ; TRISC = 0b11011100 ; // set PORTC as input except for bits 0 (RESET) and 1 (CS) T1CON = 0b10110101 ; // 16 bits, from other source, prescaler 1:8, oscillator disabled, not synchronized, internal clock, enabled PIR1.TMR1IF = 0 ; // clear TMR1 overflow interrupt flag PIE1.TMR1IE = 1 ; // enable interrupt on TMR1 overflow INTCON |= 0b11000000 ; // enable global & peripheral interrupts // init ARP cache memset(&arpCache, 0, sizeof(arpCache)) ; /* * starts Spi_Ethernet with : * reset bit on RC0, * CS bit on RC1, * my MAC & IP address, * full duplex */ Spi_Init() ; Spi_Ethernet_Init(&PORTC, 0, &PORTC, 1, macAddr, ipAddr, Spi_Ethernet_FULLDUPLEX) ; while(1) // do forever { Spi_Ethernet_doPacket() ; // process incoming Ethernet packets if(transmit && (tmr > 15)) // transmit one UDP packet per second { ByteToStr(PORTB, udpStr + 6) ; // read PORTB value and convert to string sendUDP(destIpAddr, 3456, destPortNum, udpStr, sizeof(udpStr)) ; // send to remote host tmr = 0 ; // reset timer } } } |
mình đã crack rồi nhung hàm spi_ethernet_dopacket() ; vẫn không dùng được
xóa nó thì biên dịch vẫn được bạn có thể chỉ giúp mình , được ko ,thank |
Trích:
|
Múi giờ GMT. Hiện tại là 07:03 AM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam