PICおよびW5100に基づいお5分でWebサヌバヌ

5分でW5100チップで簡単なWebサヌバヌを起動する方法に぀いお孊びたいず思っおいたが、尋ねるのは恥ずかしかった。



画像



この蚘事では、たずえば、Wiznetの玠晎らしく安䟡なW5100チップ䞊でWebサヌバヌを実行する方法を簡単か぀詳现に、明確に説明したす。



なぜ圌女は玠晎らしいのですか

第二に-安䟡。

そしお最初に、圌女はあなたのためにすべおの仕事をしたす。 遅延しおTEXTたたは-HTMLデヌタを送受信する必芁がありたす。



免責事項120幎以䞊の経隓を持぀電子技術者は、すでにおそらく察象になっおいるため、衚面的で単玔に芋えるかもしれたせん。 この蚘事は、電子工孊、たたは少なくずもマむクロコントロヌラヌのプログラミングの経隓があり、これを実行するこずを最終的に完党に望んでいる人を察象ずしおいたす...取り消し線わかりたした、「玠晎らしい」 チップW5100。



免責事項2普遍的な孊習、デヌタシヌトの完党な翻蚳、およびそのすべおのポむントの解釈の目暙を蚭定したせんでした。 私のタスクは、玛らわしい点を明確にし、W5100チップの䜿甚方法ずそのアプリケヌションWebサヌバヌなどを実行する方法を瀺すこずです。



私の説明ず応甚䟋に基づいお、マむクロコントロヌラの経隓があり、ネットワヌクの少なくずも基本的な抂念を持っおいる人なら誰でも、他のすべおを自分で理解するこずができたす。



免責事項3この実隓は自宅で行わないでください。 そしお、倧人の䞀人が近くにいたこずが望たしい。



範囲



この蚘事は、広範なネットワヌクトピックに関する包括的な知識を提䟛するこずを意図したものではなく、これに関するマニュアルもありたすが、原則ずしお、䜕が起こっおいるのか、なぜ、そしおどの情報が䞻題の詳现な理解を求めおいるのかを理解する機䌚を提䟛したす。



ただし、最埌に瀺した䟋では、マむクロコントロヌラヌ䞊のアプリケヌションでむンタヌネットより正確にはむヌサネットずTCP / IPを䜿甚する方法を把握できたす。その単玔さにもかかわらず、実際に完党に適甚できたす。 クラむアントずサヌバヌの接続の操䜜方法を理解し、最終的には䜕かを手元に眮いお、トピックをよりよく理解できるようになるため、説明が耇雑になりたす-説明付きで䜕十ペヌゞにもわたっお眠るこずなく、知識を深めるこずがはるかに容易になりたすレゞスタの割り圓お、NATチュヌニングの原則、たたはパケット内のフラグメントオフセットの正しい指瀺。



 "...パケット内のフラグメント.."りッディアレンのようなもの



私自身の経隓から通垞、蚘事を曞く人にずっお、䞻題は明確で理解しやすいので、圌は簡朔か぀「明確に」曞く。

しかし、これは倚くの堎合、読者の堎合には圓おはたらず、話題から倖れお、著者が䜕を念頭に眮いおいたのか、そしおこのような声明を理解するべきか、それずもたったく逆なのかを疑問に思わせるこずがよくありたすか したがっお、可胜な限り、私は解散せず、完党に明快で理解が明確になるたで噛む必芁がある堎所では、蚀葉を節玄したせん。



同時に、完璧な人は誰もいないこずを忘れないでください私でさえ。



最埌たで読んだ人にはボヌナスです。蚘事の最埌に、簡単な「C」にWORKINGコヌドず倚数のコメントが衚瀺され、5幎生でもプログラムで䜕が起こっおいるかを理解できたす。 コヌドは通垞のPICa甚に曞かれおいたすすべおがAVR-shikiずArduin-shikiの呚蟺にあるわけではありたせんか。



成分



ボヌドを広げおTQFP80パッケヌゞにチップをはんだ付けする特別な欲求がない堎合は、W5100に基づく通垞のArduinoむヌサネットシヌルドを䜿甚するこずをお勧めしたす。 たた、操䜜䞭にサヌバヌ内で䜕が起こっおいるかに突然興味がある堎合に備えお、シンプルで安䟡なPIC、PICaのブレッドボヌド、いく぀かの接続ワむダ、むヌサネットパッチコヌド、および奜みに応じおシリアルRS232ケヌブルが必芁になりたす出力の行がコヌドに挿入されたす関連情報-端末ぞ。



歌詞スキップ



開発の経隓がある人なら誰でも、この状況はおなじみですそうでないのか、それずも私だけが負けおいるのでしょうか



アプリケヌションを実行する必芁がある特定のチップを䜿甚したす。 簡単にするために、このアプリケヌションが䜿甚されるトピック/領域むヌサネット、TCP / IP、HTTP、CGIなどにも粟通しおいるずしたしょう。



最初に、チップ䞊のデヌタシヌトを100,500ペヌゞで取埗し、
歌詞をお芋逃しなく


泚意深く読んでください。 その埌、それをさらに数回読み盎し、最終的にこのチップの䜿甚方法を理解し始めたす。 その埌、正誀衚を䜜成しお同じ繰り返しを繰り返したす。



これらを読んだ埌、最終的にチップの動䜜方法、正しくプログラムする方法100500レゞスタ-1を理解できたすが、これたでのずころ、適切に実行する方法は完党には明らかではありたせん。 たずえば、レゞ​​スタヌにアクセスする順序は重芁ですかその堎合、どの順序が正しいか、それが重芁でない堎合は、間違いなく重芁ですか。



もちろん、倚くの有甚な情報はむンタヌネットずフォヌラムで芋぀けるこずができたすが、そこにあるすべおの䟋から、どれが実際に機胜するか、恐ろしい間違いがたくさんあるにもかかわらずどの機胜が機胜するのかただ疑わない、どの「䟋「-曞いたがチェックはしなかった、圌がそれをするこずを望んでいる著者の空想の単なる想像。



さお、あなたはこれらのすべおの段階を経お、今では確かにすべおを理解しおいたす。



チップのすべおのピンを必芁なものに正しく接続し、チップをプロセッサに正しく接続し、すべおのレゞスタずその䞭にある他のものを正しく蚭定したす。 -最埌に...

はい、はい、すべおが正垞です-䜕も機胜したせんでした。



これは最も厄介な段階です-デヌタシヌト䞊ですべおが正確か぀厳密に行われおいるが、ただ機胜しない堎合。 問題が長く退屈なものであるかを把握し、最終的に1 ... 5 ... 17のバグを芋぀けたす。 もちろんです これは、デヌタシヌト/゚ラスで述べられおいるこずです。 さお、今、圌らが䜕を意味しおいたのかが明確になりたしたそしお、あなた自身が掚枬できるこず。



それだけです

アプリケヌションが獲埗したした。

今、あなたはこのチップで特別です。

ファンファヌレ。 賞。 ビヌル ファンの矀衆。 栄光ず次のディドラむン。





この蚘事は、読者が退屈な段階をスキップし、すぐに「うたくいった」段階に進んでから本文を読みやすくするこずを目的ずしおいたす。



歌詞-2スキップできたす



䜕幎も前もう少し、Windows98以前の時代でさえ、私の友人はこれらの停のナヌザヌず離婚したず䞍平を蚀っおいたした。DOSチヌムを知らず、Windows 3.11があるのでconfig.sysに入るず思いたす必ずしもではありたせんが、そこにも-圌らはコンピュヌタヌを持ちたいです。

Lyric 2をスキップしたすか
私はい぀も誰かが䞭を歩き回るのが奜きだず思っおいたした。 そしお、䞡方の皮には存圚する暩利がありたす。 Guy Kawasaki "...電子レンゞはどのように゚ラヌメッセヌゞを出すこずができたすか電子レンゞはりォヌムアップする必芁がありたす誰も特別なマむクロ波プログラミングコヌスを取るべきではありたせん"



今日、苊情がよく聞かれたす。よく、圌らはこれらのArduinsが人々を台無しにしお無知を生み出しおいるず蚀いたす-䜕幎も孊ばずn + 1幎でも経隓を積むために-プログラミングず電子工孊の深い知識を埗ようずせず、誰もが圌らのプロゞェクトをリベットするために急いで行きたした。

ホラヌ、ホラヌ。

それで䜕

これは正垞だず思いたす-創造的な粟神ず創造性を備えた人がアむデアを思い぀きたたはその逆、それを実装したいず思いたす。 最も深い知識を持っおいない。 これは正垞です。



たた、むンタヌネットの倜明けには、ペヌゞの䞋郚に誇らしげに瀺すようなファッションがありたした。「このサむトは、notepad.exeで完党に手動で䜜成されたした。 HTML゚ディタヌはありたせん」 䜕にも䌌おいたせんか



同時に、たずえば、Cたたはアセンブラヌでさえ開始したせんでした-最初のコンピュヌタヌは、れロから組み立おられお完党に空で、少なくずもブヌトロヌダヌを埋めるために、アドレスバスの16のトグルスむッチず8デヌタバストグルスむッチ。

倢の䞭で長い間、たくさんの赀いれロず1の長い列が私に来たした、そしお私の母がパンを買うために私を送ったずき、私の最初の考えは
「パンに行くために...これはどんなコヌドですか」



経隓豊富なバガヌでさえ、進歩をサポヌトし、新人が働く機䌚を増やし、さたざたなタむプのナヌザヌをサポヌトしおいたす。



クラむアント-サヌバヌ。 䞀般的に



おそらく最埌から始めお䞊に移動するのが理にかなっおいたす。



ブラりザヌプログラムを起動し、サむトの名前を入力したす-画面にWebペヌゞのコンテンツが衚瀺されたす。

もちろん、ブラりザは写真付きの矎しいペヌゞを受信したせんが、倧量のテキスト、HTMLタグ、写真/ビデオぞのリンクなどがすべおをたずめお、矎しい時にはWebペヌゞを提䟛したす。



これはすべお、HTTPプロトコルを䜿甚しおサヌバヌずブラりザヌの間で送信されたす。HTTPプロトコルは、それらの間の接続の確立ずその動䜜も制埡したす。



ネットワヌク/むンタヌネットを扱っおいるため、ネットワヌク/むンタヌネットで採甚されおいるルヌルに埓っお送信するために、このデヌタHTML、HTTPを「ラップ」するはすべお新しい「レむダヌ」-TCP / IPでラップされたす。



TCPTransmission Control Protocolは、保蚌された接続の確立ずデヌタパケットの配信を保蚌するために䜿甚されたす。 Webブラりザ電子メヌルクラむアントなどは正確にTCPを䜿甚したす。



おそらく、TCPに加えお、UDPUser Datagram Protocolもありたす。UDPは、接続の確立やメッセヌゞの配信の保蚌などの些现なこずにたったく困惑せず、時間を費やさないため、マシンガンのようにパケットを萜曞きしたす、ただし、接続チャネルが高品質で信頌性の高い堎合、たたはパケットの損倱たたは損倱ではなくに厳しい芁件が課されおいない堎合にのみ䜿甚できたす神、それらを数えたす。



この蚘事ではUDPは考慮されたせんが、W5100でも可胜です。



Webサヌバヌはむヌサネット接続を介しおコンピュヌタヌに接続されるため、これらすべおは別のレむダヌである「むヌサネットフレヌム」に「ラップ」されたす。



実際、ご存知のように、むヌサネットを䜿甚せずに暙準のRS-232チャネル経由でもTCP / IPを送信できたす。



そのため、ネスティングドヌルがありたす。サヌビスバむト「ヘッダヌ」ず実際のデヌタペむロヌドを持぀バむトで構成されるむヌサネットフレヌムです。



このデヌタにはTCP / IPパケットが含たれおおり、このパケットにはヘッダヌバむトずデヌタ自䜓も含たれおいたす。



そしお、この最埌のデヌタは、HTTPヘッダヌで構成されおおり、長い間埅たれおおり、HTML圢匏のテキストや画像を少し冷やす時間がありたした。



Etheretet、TCP、およびIPに぀いおの話-W5100はこれらすべおの困難に察凊し、頭痛を取り陀きたすこれが魅力です頭痛ではなく、W5100の魅力です。



しかし、HTTPに぀いお詳しく芋おいきたしょう。W5100からHTTPを取埗しお凊理する必芁があるためですWebブラりザヌがサヌバヌに芁求を送信する堎合。逆の堎合も同様です-Webに応答するずきにHTTPを䜜成しおW5100に提䟛したすブラりザに。



この蚘事でHTTPプロトコルのすべおのニュアンスを完党に開瀺するこずはできたせん私はHTTP / 1.1 RFC 2616に興味を持っおいたす、ここでは最も基本的で、シンプルなしかし非垞に䜿いやすいWebサヌバヌを䞊げるのに圹立぀ものを怜蚎したす。



ブラりザヌでWebサむトを開くず䟋 opticaldt.us-広告ではありたせん、ブラりザヌはWebサむトサヌバヌにリク゚ストを送信したす。



GET / HTTP/1.1

Host: opticaldt.us

Connection: keep-alive

Cache-Control: max-age=0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36

Accept-Encoding: gzip,deflate,sdch

Accept-Language: en-US,en;q=0.8,ru;q=0.6








この行に泚意しおくださいGET ...



「... /」の埌、「HTTP / 1.1」の前-空。

぀たり、デフォルトでは、index.htmlファむルたたはindex.htmが芁求されたす。

サヌバヌのindex.htmlファむルがこのサブディレクトリに実際にある堎合、ブラりザはそれを正垞に開きたす。 このファむルが存圚しない堎合たたは、䞀般に、任意の名前ず拡匵子を持぀欠萜ファむルのリク゚ストを行った堎合、サヌバヌぱラヌ404ペヌゞを返したすこれも最初から衚瀺されたす-䞍正なリク゚ストぞの応答ずしおそれを䞎えるのはサヌバヌのタスクです個人的にそのようなペヌゞを䜜成する必芁がありたす。



タむトルからわかるように、クラむアントブラりザは、自身に関する倚くの興味深く有甚な情報を報告したす。

サヌバヌは非垞にシンプルで、クラむアントに特別なものを送信したせんたずえば、ヘッダヌから芪密な詳现をすべお抜出し、次のようなこずでナヌザヌを怖がらせるこずはありたせん。 2階の䜏所、アパヌトはあなたのものではありたせんが、プロバむダヌのアカりントは3日で終了したす。補充するこずを忘れないでください。このような画面解像床ずWindowsXPで猫Fedorに逌をやる時間です。なりたすか Mozillaではなく、IE 11、そうそう、あなたはりクラむナのIPを持っおいるので、「倧きないじめ」がありたすが、いや、それはYevpatoriyaなので、「hello again」など、我々、ブラりザからのリク゚ストでは、最初の行のみが察象になりたす。クラむアントブラりザがサヌバヌから受信したいファむルを芋぀けるために「解析」ず蚀われるように、それが必芁になりたす。



最も単玔なバヌゞョンでは、サヌバヌが機胜しおいるこずをテストするために、すべおの芁求぀たり、すべおのファむルの芁求に察しお同じHTMLペヌゞを送信できたす。

先ほど、この䟋では、「ファむル」index.htmlが芁求された堎合はそれを、他の䜕かを芁求された堎合ぱラヌのあるペヌゞを枡したす。



そこで、幞いなこずに、このサむトのindex.htmlファむルがあり、サヌバヌは、ヘッダヌずindex.htmlファむルの実際のコンテンツで構成されるメッセヌゞでブラりザヌに応答したす。



HTTP/1.1 200 OK

Date: Sun, 13 Jul 2014 21:32:49 GMT

Server: Apache

Accept-Ranges: bytes

Vary: Accept-Encoding

Content-Length: 185

Keep-Alive: timeout=5, max=100

Connection: Keep-Alive

Content-Type: text/html








 <html> <head> <meta http-equiv = "Content-Type" content = "text / html; charset = Windows-1251"> <title> W5100 WebServer </ title> </ head> <body> <center>さお、<br> <b> Hello World ?! </ b> </ center> </ html>




最初の行 "... 200 OK .."では、サヌバヌは芁求が正しい぀たり、そのようなファむルが存圚するこずを報告したす。

「Content-Length185」の行では、サヌバヌは、送信されたファむルの長さより正確には、具䜓的にはHTTPヘッダヌの盎埌に続くWebペヌゞの長さに぀いおクラむアント぀たりブラりザヌに譊告したす。



ブラりザヌでの䜜業が倚少なりずも正しくなるようにするには、サヌバヌ応答ずしおHTMLファむルに加えおHTTPヘッダヌで少なくずも3぀のパラメヌタヌを指定する必芁がありたす。



HTTP / 1.1 200 OK

Content-Typetext / htmlたずえば、写真ではなくこれを送信する堎合。

コンテンツの長さ埌でカりント



実際、最新のブラりザは非垞に自由床が高いため、3番目のヘッダヌ行を削陀できたす。 さらに、この䟋では、「Webペヌゞ」をクラむアントに提䟛した埌、切断したす。そのため、クラむアントブラりザヌはすべおを受け取ったず掚枬したす。



しかし...ペヌゞが長い堎合、たたは、たずえば、写真などを送信する堎合 -送信するデヌタブロックの長さContent-Lengthを瀺す方が適切です。



TCP / IPに぀いお少しだけ



䞊蚘でW5100がむヌサネットずTCP / IPを䜿甚しおすべおの䜜業を行っおいるず曞いたずき、私は珟実を少し装食したした。 䜕かほんの少し私たちはただ自分でやらなければなりたせん。 すなわち接続を確立するプロセスずその完了を管理する。



芁するに、サヌバヌずクラむアントはお互いにIPパケットを転送するこずで通信したす。IPパケットには「有甚な」デヌタたずえばHTMLペヌゞが含たれるか、「有甚な」デヌタのない玔粋なサヌビスデヌタになりたす。



W5100チップセットデヌタシヌトを開いおはい、はい、今です、サヌバヌモヌドでクラむアントブラりザヌずW5100が通信する方法を考えおみたしょう。



画像



たず、OPENモヌドのW5100は、゜ケットネットワヌク接続を開いお䜜成し、「リスニング」モヌドLISTENに切り替えお、クラむアントブラりザヌなどからの芁求を埅ちたす。



クラむアントからの芁求が到着し、サヌバヌずクラむアント間で接続が確立されるず、サヌバヌW5100はESTABLISHEDモヌドに切り替わり、 デヌタが圓事者間で亀換されたす。



泚憲章によるず、IPパケットの最倧デヌタサむズは1500バむトです。 デヌタが1぀のパッケヌゞに収たらない堎合倧きなHTMLコヌド、たたは画像を転送する必芁がある堎合など、デヌタを1500バむト未満の郚分に分割し、1぀ず぀転送する必芁がありたす。



さらに、圓事者が魂で燃えおいるすべおのものを互いに衚明したずき、圌らのうちの1人人生のようには切断芁求を送信するこずによっお最初に「電話を切りたした」。



泚完党なデヌタ転送埌に垞に切断が発生するずは限りたせん。 たずえば、チャネルが遅い、たたは干枉があり、ブラりザは完了を埅぀のにうんざりしおおり、タむムアりトで接続を終了したした。 たたは、Webサヌバヌで䜕か問題が発生し、最も興味深い堎所で切断するこずにしたした。 たあ、䞀般的に、すべおは人生で起こりたす。



それらの間の接続が切断された埌、サヌバヌは閉じた接続゜ケットモヌドになりたす-閉じられたしたたあ、必芁なこずはすべお蚀われた/送信されたした、なぜ他に埅぀のですか。



それだけです



あなたが぀かの間の絆の支持者である堎合、および/たたは䞀床十分以䞊がある堎合は、ここで停止できたす。

あなたが人生の楜芳䞻矩者たたは氞続的であり、サヌバヌがおそらく2回以䞊接続されるず考えおいる堎合は、「OPEN」ステップに戻っお、写真に埓うだけです。 通垞、適切なサヌバヌがそれを行いたす。 しかし、おそらく将来的には安䟡なプラスチック補の䜿い捚おサヌバヌがあるでしょうか タむプは1回䜿甚したした-そしおそれを捚おたしたか



これなしでもできたすW5100のおかげですが、それに぀いおは匕き続き蚀及したす。 実際には、クラむアントずサヌバヌ間でaketsが亀換され、接続ステヌタスが倉曎されるたびに、転送されたパケットでフラグが送信され、珟圚䜕が起こっおいるのか、どのように察応するのかが瀺されたす。



最も䞀般的なIPスタックを䜿甚したす。



IBM-360ずAS-400の魔術垫ず魔術垫は、「スタック」ずいう矎しい蚀葉で誰も怖がらないようにしたしょう。 実際、これは単なるプロトコルであり、サヌビスフィヌルドず実際のデヌタがどのような順序でどのような順序で描画されるかを瀺すデヌタ転送フォヌマットです。 Zhvanetsky「...そしおブルガリア人でさえ、私たちの衚珟を理解するこずはできたせん」それは倩候条件にもかかわらず「単に雚を意味する」



画像



7番目のバむトの3぀の最䞊䜍ビットFLAGSに興味がありたす。



これらの3ビットの組み合わせにより、FIN、SYN、RST、PSH、ACK、URGのフラグが圢成されたす。



FIN-セッションの終了を瀺したす。

SYN-接続の初期化。

RST-接続の䞭断通垞ぱラヌぞの応答;

ACK-受領確認パッケヌゞ;

PSH-簡略化-確認をすぐに送信するための芁件。

URG-パッケヌゞのアヌキテクチャの衚瀺。



奜奇心If盛称賛に倀し、䟿利、実際にパケットが亀換され、どのフラグが蚭定され、どのような堎合に、他のすべおに-他のヘッダヌフィヌルドは䜕ですかたあ、良い、「スタック」-自分で芋぀けなければなりたせん。 この蚘事では、W5100がパッケヌゞずフラグをすべお凊理するため、これに぀いおは考慮したせんが、珟時点での接続のステヌタスOPEN、LISTEN、ESTABLISHED、CLOSEDを凊理したす。



W5100の可胜な限り簡単な説明



さお、さらにこの瞬間を遅らせるこずはできたせん。鉄ず゜フトりェアの偎面からW5100を怜蚎する時です。



画像



䞀方では、W5100はむヌサネットコネクタにトランスず敎合回路を介しお接続し、他方ではマむクロコントロヌラヌから接続したす。

アドレスバスずデヌタバスを䜿甚しお、たたはSPIむンタヌフェむスを介しお、奜みや状況に応じおマむクロコントロヌラに接続できたす。

チップをどのように正確に接続するか-私は、むンタヌネット䞊で完党な説明で既補の回路をペむントしたせん。 さらに秘密をお話ししたす、この䟋では、このチップを備えた既補のボヌドを䜿甚したす。



チップには、むヌサネットPHYおよびMAC、むヌサネットフレヌムのハンドラヌ、ハヌドりェアに実装されたいく぀かのIPグルヌププロトコルが含たれ、最倧4぀の゜ケットネットワヌク接続を䜜成でき、それぞれ8KBのメモリのRXおよびTXバッファヌが含たれ、各゜ケットで盞互に共有できたすたたは公平にたたは同等に、゜ケットごずに1.2.4たたは8 KBを割り圓おたすただし、バッファヌ党䜓のサむズが受信甚に8KB、転送甚に8KBであるこずを忘れないでください。



メモリ割り圓お



画像



図からわかるように



アドレス0x0000からアドレス0x002Fたではすべおの共通レゞスタであり、

アドレス0x0400からアドレス0x07FFたで-レゞスタの4぀の同䞀グルヌプ-各゜ケットに1぀、

アドレス0x4000からアドレス0x5FFFぞ-送信バッファ8KB。自由に゜ケット間で分配できたす。

アドレス0x6000からアドレス0x7FFF-受信バッファヌ8KB。これは、独自の刀断で゜ケット間で配垃するこずもできたす。



すべおのレゞスタは8ビットです。 ほずんどの人が読み曞きできたす。



すべおのレゞスタを怜蚎するのではなく、Webサヌバヌの䜜成に必芁なレゞスタのみを怜蚎したすが、䞀般的なアむデアを簡単に理解し、特定のタスク甚にさらに開発するこずができたす。



重芁なポむントW5100は、䞀般に「ビッグ゚ンディアン」たたは「ネットワヌクオヌダヌ」ず呌ばれるバむトオヌダヌを䜿甚したす。 深い科孊的意味は、最䞊䜍バむトの最䞊䜍ビットが最初に来お送信され、最埌が最䞋䜍バむトの最䞋䜍ビットであり、最も重芁なこずには、最䞊䜍バむトが䞋䜍メモリアドレスにあるずいう事実に芁玄されたす。 ぀たり、たずえば、サヌバヌのIPアドレスたずえば192.168.0.155の4バむトを゜ヌスIPアドレス0x000F ... 0x0012SIPR0 ... SIPR3レゞスタに曞き蟌むには、SIPR0、「168」レゞスタに「192」を曞き蟌む必芁がありたす。 -SIPR1では、SIPR2で「0」、SIPR3で「155」。



汎甚レゞスタ



䞀般-チップ党䜓ずすべおの゜ケットの動䜜に圱響を䞎えるこずを意味したす。぀たり、 特定の゜ケットには適甚されたせん 。



0x0000 MR-モヌド-ここではすべおが明確です-それらを通しお、動䜜モヌドを蚭定したす。

0x0001 ..0x0004 GAR0..3-ゲヌトりェむアドレス䟋192.168.0.254;

0x0005 ... 0x0008 SUBR0..3-サブネットマスクアドレス䟋255.255.255.0;

0x0009..0x000E SHAR0..5-゜ヌスハヌドりェアアドレス

぀たり、MACアドレス、たずえば0A 1B 2C 3D 4E 5F。

サヌバヌで垂堎をあふれさせない堎合、任意のMACを指定できたす。䞻なこずは、ネットワヌクに同じMACアドレスを持぀デバむスがないこずです-競合は必芁ありたせんよね



0x000F ... 0x0012 SIPR0..3-送信元IPアドレス-Webサヌバヌのアドレス。䟋192.168.0.155;

0x001A-RMSR-RXメモリサむズ-ここでは、各゜ケットの受信バッファのメモリ量を指定したす。

0x001B-TMSR-TXメモリサむズ-ここでは、各゜ケットの転送バッファのメモリ量を指定したす。



゜ケットレゞスタ



この䟋では、1぀の゜ケットず、TCP / IPサヌバヌに必芁なレゞスタのみを操䜜するため、これらのレゞスタのみを考慮したす。



0x400 S0_MR-Socket0モヌドレゞスタ-この特定の゜ケットの動䜜モヌドを蚭定したす。

0x0401 S0_CR-Socket0コマンドレゞスタ-ここでは、接続の状態を制埡するコマンドを蚭定したす。

0x0403 S0_SR-Socket0ステヌタスレゞスタ-ここから、珟圚のステヌタスに関するデヌタを読み取りたす。

0x0404、0x0405 S0_PORT0、S0_PORT1-Socket0゜ヌスポヌト-サヌバヌが䜿甚可胜なポヌトより正確な堎合-開いた゜ケットが䜿甚可胜なポヌト。



正盎に蚀うず、サヌビスを参照するずきは、プロトコル、このサヌビスのサヌバヌアドレス、ポヌト番号およびファむルの名前ずそのフルパスを完党に瀺す必芁がありたす。



たずえば、ポヌト123を介しお゜ケットにアクセスできるアドレス192.168.0.155のサヌバヌにあるindex.htmlファむルが必芁な堎合、ブラりザのURLバヌ぀たり、アドレスバヌに次のように蚘述する必芁がありたす。



192.168.0.155123 / index.html Enterキヌを抌すたで埅ち​​たす。



しかし...「http// ...」のような接続の堎合぀たり、HTTPプロトコルの堎合、ポヌト80を割り圓おるのが慣䟋です。

したがっお、Socket0 Source Portにポヌト番号80を割り圓おた堎合、ブラりザヌのアドレスバヌにポヌト番号を入力できたせん。ポヌトが指定されおいない堎合、ブラりザヌは定矩䞊、 192.168.0.155 / indexずいう圢匏のURLの結果ずしおこのポヌトを䜿甚するためですhtmlぱラヌなしで機胜したす。 より䞀般的には、これはデフォルトポヌトがあるすべおの堎合に圓おはたりたす

-サヌビスぞのアクセス時にそれらを指定しない堎合、クラむアントはデフォルトポヌトHTTPの堎合は80、Telnetの堎合は23などを通過したす。



たた、以前に分析したように、芁求されたファむルの名前を指定しない堎合、双方がindex.htmlたたはindex.htmたたはindex.phpファむルに぀いお話しおいるず想定するのが慣䟋です。 そのため、ブラりザのアドレスバヌ192.168.0.155で指定するず、サヌバヌから正しい応答が返されたす぀たり、クラむアントが特定のファむル名を芁求しない堎合、むンデックスファむルを期埅しおいるこずがわかりたすたずえば、クラむアントがディレクトリを芁求し、その内容をみんなずみんなに芋せお恥ずかしいたずえば、猫やスクリプトの写真など堎合、ペヌゞに「404゚ラヌ」を䞎えるのは非垞に面癜くなるでしょう。



アドレスの入力にかかる時間を完党に節玄するために、プロトコルのタむプを指定しない堎合、ブラりザは自動的にそれがHTTPであるず芋なしたすもちろん、ブラりザがそれを愛するIEでない限り... OK、それは重芁ではありたせん、忘れおしたいたした。



したがっお、アドレスバヌ192.168.0.155に曞き蟌むだけで、すべおの関係者は192.168.0.155に぀いお話しおいるこずを理解できたす80 / index.html



だから、それは決たっおるよね サヌバヌの゜ケットポヌトアドレスを80に蚭定したす。

同時に、「ビッグ゚ンディアン」を忘れないでください。したがっお、80より正確には-0080は次のように蚘述されたす。S0_PORT0= 00、S0_PORT1 = 80はい。これらは10進数の「80」であり、16進数ではないこずを忘れないでください。



0x0420、0x0421 S0_TX_FSR0、S0_TX_FSR1-Socket0 TX Free Size-゜ケット0送信バッファヌの空き領域のサむズ。

0x0422、0x0423 S0_TX_RD0、S0_TX_RD1-Socket0 TX読み取りポむンタヌ*読み取り専甚-転送バッファヌ内で、クラむアントに送信するデヌタデヌタブロックの先頭を瀺したす。



ここには扱いにくい小さなものがありたすWiznetはダミヌを぀ぶやくこずに決めたした。たずえば、Socket0 TX読み取りポむンタヌを読み取り、たずえばアドレス0x4200を指しおいる堎合、...正しく-これは、転送にデヌタを曞き蟌む必芁があるずいう意味ではありたせんこの堎所から始たるバッファ。 ええ、ええ...「運転しおいる女性が巊折を瀺しおいる堎合-これは圌女がたっすぐに行くこずを意味しない」C。 これに぀いおは埌で詳しく説明したす。



0x0424、0x0425 S0_TX_WR0、S0_TX_WR1-Socket0 TX曞き蟌みポむンタヌ-クラむアントに送信デヌタするデヌタブロックの終わりを転送バッファヌで瀺したす。



ここで重芁な説明をする必芁がありたす。

最埌の2぀のレゞスタは、バッファに送信するデヌタのブロックを曞き蟌む必芁がある物理アドレスを決定したせん。 これらのアドレスを自分で把握する必芁がありたす。



もう1぀の泚意転送バッファに2KBを割り圓おたずしたしょう。 Socket0 TX読み取りポむンタヌを読み取り、バッファヌの最埌の10バむトを指すこずが刀明したした。 たた、䞀般的に1000バむトを転送぀たり、バッファに曞き蟌むするこずを意図しおいたした。 どうする

簡単ですこれらの10バむトに転送するデヌタを曞き蟌んでから、バッファヌの先頭に移動し、残りのデヌタをさらに曞き続けたす぀たり、デヌタの1000バむトから、10バむトがバッファヌの最埌に配眮され、990バむトの残りの郚分が先頭になりたすバッファ。

W5100はこの䞍名誉を知っおおり実際、それを䜜ったのは圌でした、したがっお、終わりに達した埌、バッファの先頭にゞャンプしお、残りの郚分を蟛抱匷く読み䞊げたす。



さお、この問題に察凊したしょう。レゞスタで指定されたポむンタから、転送バッファにデヌタを曞き蟌む物理アドレスを蚈算する方法です。



もちろん、すべおのアドレスをハヌドコヌディングしおスコア付けするこずもできたすが、私たちが最も正確なプログラマヌであり、むンド人のようなものではなく、1時間あたり3ドルで蚈算する䞀般的な原則を考慮し、あらゆる堎面で最も普遍的なプログラムを䜜成したす。



誰かがデヌタシヌトを読むこずに決めた堎合、定数ず倉数のニヌモニックをできるだけデヌタシヌトに近づけおおくので、私の䟋やデヌタシヌトの説明ず混同しないようにしおください。レゞスタの名前はデヌタシヌトずたったく同じように瀺したした;もちろん、アドレスも。



そのため、䟿宜䞊、倉数



S0_TX_BASE-Socket0送信バッファヌのベヌスアドレスを玹介したす。



メモリ割り圓おの図を芋るず、0x4000のようです。

W5100チップがれロアドレスにない堎合はどうでしょうか぀たり、たずえば、システムのアドレス空間でチップの「れロ」アドレスがシフトされ、システムでたずえばチップのれロアドレスは0x1984です。

さらにSocket0ですべおがクリアな堎合、Socket1のベヌスアドレスチップアドレスの朜圚的なオフセットに加えおは、各゜ケットのバッファヌに割り圓おたメモリ量にも䟝存したす。

぀たり、再びハヌドドラむブを実行するか、TMSRレゞスタ転送バッファヌの堎合を「正しい方法で」読み取り、各゜ケットに割り圓おられおいるバッファヌメモリの量を確認しお、各゜ケットのバッファヌメモリ領域の開始䜍眮を「蚈算」するこずができたす。



䞀般に、私はあなたに譊告したした、そしお、私の䟋では、簡単にするために、圌を激しく打ちたした

S0_TX_BASE = 0x4000。



S0_TX_MASK-マスク、「蚈算」でさらに必芁になりたす。



同様に、マスクは、良い方法で、゜ケット間のバッファヌメモリ割り圓おレゞスタTMSRに曞き蟌たれたもの方法、方法に基づいお、゜ケットごずに蚈算する必芁がありたす。



私は䜕も蚈算したせん私はか぀お私が困ったこずだず思っおいたしたが、定期的な読者になったずき、Habrはすべおが正垞であるこずに気付きたした-私はただ先延ばししおいる、私は各゜ケットに2KBを割り圓おたしたあなたが芚えおいるように、これは2000グラム、ただし2048バむト、それぞれマスクは2048 -1 = 20470x07FFです。



合蚈、この䟋では、S0_TX_MASK = 0x07FFになりたす。



混乱を远加し、名誉を払っお解きたす。



䞊で曞いたように、レゞスタ読み取り専甚S0_TX_RD0、S0_TX_RD1は、゜ケット転送バッファヌにある転送デヌタのブロックの先頭ぞのポむンタヌです。

もっず正確に蚀えば、これは、珟時点でネットワヌクの倖郚に送信されるデヌタの特定のバむトぞのポむンタヌですこれは、今読んでいるように、送信に関しおはそうではありたせん。

そしお、デヌタは、送信されたバむトの珟圚のアドレスバッファ内がデヌタのブロックの終わりに達するたで送信されたす。デヌタのブロックブロックの終わりぞのポむンタは、レゞスタS0_TX_WR0、S0_TX_WR1のペアに蚘録されたす。



぀たり、実際には、W5100は転送バッファヌからデヌタのバむトを匕き出したす。これは、S0_TX_RD0、S0_TX_RD1のレゞスタヌのペアで瀺され、ネットワヌクにそれを吐き出し、その埌、レゞスタヌをむンクリメントし、このレゞスタヌが指す次のバむトに進みたす。 、レゞスタS0_TX_WR0、S0_TX_WR1のペアず倀が等しくなるたでむンクリメントされ、この時点でデヌタ転送が終了したす。したがっお、すべおのデヌタを転送するず、S0_TX_RD0、S0_TX_RD1の内容はS0_TX_WR0、S0_TX_WR1の内容ず等しくなりたす。



玳士、私はこのすべおの退屈さのために私の蚱しを蚱したす、私は本圓に誰もロヌドしたくありたせんでしたが、これなしではできたせんでした私は心でビズネットを受け入れたせん。もう少し耐えお、それはすぐに終了したす、コヌヒヌブレむクは非垞に近いです。



OK、転送バッファに䜕かを曞き始めたしょう。

5぀のアクションですべおを1行で実行するわけではありたせんが、䜕が起こっおいるのかが明確になるように、ステップごずに分解したす。



いく぀かの倉数を生成したす



OffsetS0_TX_OFFSET = make16S0_TX_RD0、S0_TX_RD1



// 2぀の8ビットレゞスタポむンタヌから16ビット倉数「オフセット」を䜜成したす

//「ビッグ゚ンディアン」なので、最䞊䜍バむトがレゞスタヌにあるこずを忘れないでくださいS0_TX_RD0、

//および最幎少-S0_TX_RD1の堎合



、このポむンタヌは通垞、チップのアドレス空間の倖偎を指すこずがありたすラむブアプリケヌションでこれらのレゞスタを読み取る堎合は、自分で確認しおください。この゜ケット甚に予玄されたゟヌン内぀たり、食べる b アドレスの物理的範囲内。

私たちは、レゞスタの倀が近い倀倀の珟実にあるたしょう



S0_TX_OFFSET =S0_TX_OFFSETS0_TX_MASK



私たちは今、本圓の、蚈算物理我々は転送に我々のデヌタの曞き蟌みを開始する必芁がありたすアドレス



S0_TX_Start_Addr = S0_TX_OFFSET + S0_TX_BASE



たあが、今我々が持っおいたす転送バむトの読み取りを開始する堎所をチップに指瀺するポむンタヌ、゜ケットの転送バッファヌSocket0の物理アドレスを蚈算し、たずえば転送にデヌタをアップロヌドしたした-蚈算した物理アドレスからチップの転送バッファヌに。



チップは、転送バッファからデヌタを読み取る時間をどのように知るのですか

これは、前述のレゞスタペア-Socket0 TX Write Pointerによっお圌に瀺されたす。



これたでのずころ、Socket0 TX読み取りポむンタヌずSocket0 TX曞き蟌みポむンタヌの倀は同じです。

䞊蚘を参照デヌタブロックが転送された埌、それらの内容は同じになり、デヌタセット内の単語ではなく、チップのリセット埌も疑われるためです。



最埌の仕䞊げ-転送バッファ内のデヌタブロックの最埌を指す必芁がありたす。

泚意-転送バッファにデヌタをロヌドするために必芁な物理アドレスずは異なり、ここでは、メモリ内の自分自身の内郚チップ衚珟で動䜜したす。

぀たり、送信デヌタブロックの長さだけ、曞き蟌みポむンタヌの内容を増やすだけです



。Socket0TX曞き蟌みポむンタヌ= Socket0 TX曞き蟌みポむンタヌ+ Data_Block_Length。



頭が既に回転しおいるず仮定するず、「Socket0 TX Write Pointer」16ビットずは、8ビットのレゞスタS0_TX_WR0䞊䜍バむトずS0_TX_WR1䞋䜍バむトの内容を意味するこずを思い出したす。



そしお-はい、-あなたが疲れおいる堎合-あなたはコヌヒヌず煙を飲むこずができたす、私は埅ちたす...



! 
 , 
 . , , – – – , .

: ? , . - – . Deal?






蚘事ぞの招埅を垌望しおいれば、新しい段萜ごずに溶けおしたいたす。



はい-読者はおそらく「...サヌバヌを5分で」でそれを買ったず思いたす。埅っおください-あなたはただコヌドを芋おいたせんいいえ、それはもちろん、短いものではありたせんが、少し逆もありたすが、これはすべおコメントが豊富なためですあたりにも倚く削陀しお、有甚なコヌドだけが残っおいる堎合は、ナプキンに曞き留めたすそしお、100ペヌゞのデヌタシヌトを読むのに2日間かかるよりも、10分間読む方が良いです。 5分間のトレヌニングでの戊闘-「誰もキャンセルしたせんでした。




はい、そうです-アルゎリズム。



原則ずしお、私はプログラムで䜕が行われおいるかを理解するのが奜きで、フロヌチャヌトを持぀こずを奜みたす。同様に、すぐにコヌドを曞きたいずいう圧倒的な欲求にもかかわらず、私は通垞、フロヌチャヌトを䜜成しお最初に䜜業するロゞックをデバッグし、それからコヌドに移りたす。 Webサヌバヌがどのように機胜するかを理解したしょう写真を参照。



画像



「1回聞くよりも100回芋る方が良い」ずいう原則がただ機胜しおいる堎合、おそらく写真に曞かれおいるこずを説明しおも意味がありたせん。



ちょうど2぀の単語



プロセス制埡は、S0_CRSocket0コマンドレゞスタ0x0401を介しお行われたす。



珟圚のステヌタス接続などの確認-S0_SRSocket0ステヌタスレゞスタ0x0403を介しお。



原則ずしお、状態チェックは゜ケット割り蟌みレゞスタを介しお぀たり、割り蟌みによっお実行できたすが、ほずんどのアプリケヌションでは超高速は䞍芁であり、そのような堎合には、ステヌタスレゞスタのポヌリングによる䜜業が正圓化されたす。



むヌサネットシヌルド接続-PICコントロヌラヌぞ



画像



ここでも、酞掗には意味がありたせん-写真にすべおが瀺されおいたす。



ヒントボヌドの2x3ヘッダヌボヌドの䞋にあり、図には衚瀺されおいたせんは、薄っぺらでバグがありたす。䜿甚せず、コンポヌネントの偎面から盎接ワむダをボヌドにはんだ付けするこずをお勧めしたす。



ボヌド接続-マむクロコントロヌラヌのピンを匕きたせんでした。これはプログラムで説明されおおり、さらに、ピン割り圓おプログラムをお奜みに倉曎するだけで、奜きなように接続できたす。



プログラムチェック枈み-動䜜したす



本物の科孊者ずしお、人間たたは実隓動物で䜕かをテストする前に、私は圌女の仕事を最初に自分でテストしたので、この胜力を倱っおいなければ圌女を信頌できたす。



このプログラムは、CCSコンパむラヌで䜜成されおいたす。䟿利なIDEに問題なく簡単にやり盎せたす移怍-あたりにも倧声で蚀われたす。



PIC16F77がコントロヌラヌずしお䜿甚されたした完成したデモボヌドで手元にありたした。同様に、どのPICでも簡単に調敎できたす実際には-プロセッサ定矩に1行ありたす。リ゜ヌスをほずんど消費せず、すべおの印刷機胜デバッグには圹立ちたすが、プログラムに圱響を䞎えないをすべお捚おるず、コヌドは再び半分に枛少したす。



前述したように、この䟋には「プリント」が詰め蟌たれおおり、プロセスの理解を容易にするために、RS232を介しお䜕が起こっおいるかを端末画面に出力したす。それらを安党に削陀できたす-これはサヌバヌ操䜜に圱響したせん。



サヌバヌプログラムでは、クラむアントからのHTTPヘッダヌを最も簡単な方法で単玔に分析しお、芁求しおいるファむルを芋぀けたす。実際、デフォルトのindex.htmlファむルリク゚ストを探したす。぀たり、ファむルの名前が綎られおいない堎合は、むンデックスファむルを意味したす。



この芁求は次のようになりたす



。GET / HTTP / 1.1



最初の「/」の埌、「HTTP」の前のスペヌスに泚意しおください。この堎所では、広告が芁求されたファむルの名前になりたす。



空スペヌスであるため、index.htmlが芁求されるこずを意味したす。 わかりたした、説明は完党に正しいわけではありたせん。通垞、サむトにアクセスするずきは、サむト名をスラッシュずファむル名なしで指定するだけです。䞡方の人が誰にでも支払いたす。ファむル名が指定されおいない堎合、応答むンデックスファむル。



ブラりザのアドレスバヌの䟋タむピングのため、このアドレス



192.168.0.155/kotiki.jpgは



それはこのように芋えたす、サヌバヌにリク゚ストを送信したす



GET /kotiki.jpg HTTP / 1.1



なぜ私はそう長くrazmusolivatおいたす-私たちはHTTPヘッダヌかどうかを確認する必芁がありたすスラッシュの埌のスペヌス。その堎合、クラむアントにindex.htmlの「ペヌゞ」を送信したす非垞に単玔です。そしお、少なくずも䜕か他のものがある堎合-゚ラヌ_404を持぀ペヌゞ。



぀たり、この䟋は単玔であり、さらに、ファむルシステムではなくWebサヌバヌを起動しおHTMLコヌドを生成する䟋でもあるため、すべおが非垞に単玔になりたす。



しかし...aahhhアフタヌルはすでにそれを手に入れたええ、しかしたた。ここにトリックがありたす「ペヌゞが芋぀かりたせん」の堎合、サヌバヌからの暙準HTTPヘッダヌは次のように始たり



たすHTTP / 1.1 404ペヌゞが芋぀かりたせん



すべおが



正垞で、サヌバヌがHTTP / 1.1 200 OK を送信する堎合ずは異なりたすブラりザには、矎しい゚ラヌメッセヌゞが衚瀺されたHTMLペヌゞが衚瀺され、そのようなタむトルを䜿甚するず、ほずんどのペヌゞに矎しいペヌゞが衚瀺されたす。 Internet Explorerを陀く。タむトルでそのような行を受け取ったので、圌は単に私たちのペヌゞを぀たんで、むンタヌネット゚クスプロヌラヌのスタむルでCurzonに答えたす。



たた、どれだけ退屈させたくないずしおも、これを指摘する必芁がありたす。HTTPヘッダヌの各行は、文字「キャリッゞリタヌン」ず「ラむンフィヌド」で終わる必芁がありたす-\ r \ nたたはASCIIコヌド0D 0A 。そしお、この順序であるこずが望たしいです。そうしないず、䞀郚のブラりザ無駄に再び蚀及したせんがあなたを理解しないかもしれたせん。さらに、HTTPヘッダヌの最埌の行ずHTMLタグの先頭の間には、これらの組み合わせのペア぀たり、ASCIIコヌドの\ r \ n \ r \ nたたは0D0A0D0Aがなければなりたせん。そうでなければ、あなた自身だけでなく、他のブラりザもあなたを理解したせん



そしお、それでもなおすべお同じ貎重な経隓であり、あなたはそれに぀いお知っおおくべきです。過床に綿密なブラりザヌのバレルにある軟膏の別のフラむよくわかりたす埌続のHTMLコヌドContent-Lenght...の長さを文字通り1文字以䞊瀺しおいるため、HTTPヘッダヌに䜕らかの誀りを犯したした実際぀たり、文字、たずえば665、および私はそれらの666があるこずを瀺したした。

そのため、すべおのブラりザは点滅せずにペヌゞを飲み蟌み、IEは青色が666番目の文字に到達するたで正盎に埅ち、それが到着するたでペヌゞの衚瀺をたったく拒吊したした。



私は通垞、論理ブロック関数からそれらを構成するプログラムを䜜成し、埌で関数自䜓を発明しおペむントしたす。したがっお、最初の私の䟋では関数が宣蚀されおからmainが宣蚀され、最埌に関数が詳现に説明されたす。さらに、最初に定数や倉数からそれほど遠くないmainが実行され、メむンディッシュに到達する前にたくさんの関数を歩いおいくのではなく、すぐにそれを芋お、䜕が起こっおいるのかを理解するこずができたす。



たた、あるプログラムがサポヌトするping芁求は、あなたが私たちのサヌバのアドレス192.168.0.155ぞのpingを送信できるこずは泚目に倀する- 。ず答えを埗るには、

実際には、pingに応答が- 。それは明らかにされおいたせん

回/オプションがあり、サヌビスがある堎合および非垞に機胜するもの、pingには応答したせん。

実際、pingナヌティリティはIPプロトコルのサブ皮の1぀であるICMPInternet Control Message Protocolを介しおリク゚ストを送信したす。ICMPは蚺断機胜もサポヌトし、IPパケットの配信に倱敗した堎合の゚ラヌを報告したすRFC 792の詳现を参照。 、pingが成功するように、このプロトコルを含むサポヌトを提䟛する必芁がありたす。

W5100チップにはすでにこのサポヌトがありたす。



ああ、もう䞀床プログラムをいく぀かのファむルに分割するのではなく、すべおを1぀のファむルにたずめお、操䜜しやすくしたした。



プログラムぱレガントなコヌドの理想ではありたせんが、もちろん改善するこずができたす。定数ず倉数の半分ず関数の3分の1を取り陀くこずができたすが、この堎合、私のタスクは䜕が起こっおいるのか、プログラムがどのように機胜するかに぀いおの理解を隠すこずでした。



そしお、あなたは信じないでしょうが、私たちは終わりに来たした。

それはたさに2むンチ䞋です-非垞に玄束されたプログラムは「5分で」。



たあ、それは始たった



゜ヌスコヌドパスワヌド-通垞-6぀星
 // =====  -   W5100  Wiznet ====== // *     Ethernet Shield //   W5100 //=========================================================== #include <16F77.H> #fuses HS //  ,  #use delay(clock=16M) ) //    16  //     –   #use rs232(baud=19200, xmit=PIN_A2, rcv=PIN_A3) //    RS232 // *  CCS   « printf» - , //       - // **   //   PICa    Ethernet Shield #define RESET pin_B2 // *active LOW #define MISO pin_B3 // input #define MOSI pin_B5 // output #define SS pin_B0 // output. SlaveSelect, Active LOW #define SCK pin_B1 // output. //**********   W5100 ********************* //************************************************************** #define MR 0x0000 // MODE register #define GAR0 0x0001 // GATEWAY Addr register0 (MSB) #define GAR1 0x0002 // GATEWAY Addr register1 #define GAR2 0x0003 // GATEWAY Addr register2 #define GAR3 0x0004 // GATEWAY Addr register3 (LSB) #define SUBR0 0x0005 // SUBNET MASK Addr register0 (MSB) #define SUBR1 0x0006 // SUBNET MASK Addr register1 #define SUBR2 0x0007 // SUBNET MASK Addr register2 #define SUBR3 0x0008 // SUBNET MASK Addr register3 (LSB) // MAC   #define SHAR0 0x0009 // SOURCE HARDWARE Addr register0 (MSB) #define SHAR1 0x000A // SOURCE HARDWARE Addr register1 #define SHAR2 0x000B // SOURCE HARDWARE Addr register2 #define SHAR3 0x000C // SOURCE HARDWARE Addr register3 #define SHAR4 0x000D // SOURCE HARDWARE Addr register4 #define SHAR5 0x000E // SOURCE HARDWARE Addr register5 (LSB) #define SIPR0 0x000F // Source IP Addr register0 (MSB) #define SIPR1 0x0010 // Source IP Addr register1 #define SIPR2 0x0011 // Source IP Addr register2 #define SIPR3 0x0012 // Source IP Addr register3 (LSB) #define RMSR 0x001A // RX memory size (1K,2K,4K or 8K per socket, from total 8K) #define TMSR 0x001B // TX memory size (1K,2K,4K or 8K per socket, from total 8K) //--  Socket0 (*       ) #define S0_MR 0x0400 // Socket0 MODE register #define S0_CR 0x0401 // Socket0 COMMAND register #define S0_SR 0x0403 // Socket0 STATUS register #define S0_PORT0 0x0404 // Socket0 SOURCE Port register0 (H byte) #define S0_PORT1 0x0405 // Socket0 SOURCE Port register1 (L byte) #define S0_TX_FSR0 0x0420 // Socket0 TX Free SIZE register0 #define S0_TX_FSR1 0x0421 // Socket0 TX Free SIZE register1 #define S0_TX_RD0 0x0422 // Socket0 TX Read POINTER register0 #define S0_TX_RD1 0x0423 // Socket0 TX Read POINTER register1 #define S0_TX_WR0 0x0424 // Socket0 TX Write POINTER register0 #define S0_TX_WR1 0x0425 // Socket0 TX Write POINTER register1 #define S0_RX_RSR0 0x0426 // Socket0 RX Received SIZE register0 (H byte) #define S0_RX_RSR1 0x0427 // Socket0 RX Received SIZE register1 ( L byte) #define S0_RX_RD0 0x0428 // Socket0 RX Read POINTER0 (H byte) #define S0_RX_RD1 0x0429 // Socket0 RX Read POINTER1 (L byte) // -----   (     0 ) ----- #define OPEN 0x01 #define LISTEN 0x02 #define CONNECT 0x04 #define DISCON 0x08 #define CLOSE 0x10 #define SEND 0x20 #define SEND_MAC 0x21 #define SEND_KEEP 0x02 #define RECV 0x40 // -----   (    STATUS 0 ) --- #define SOCK_CLOSED 0x00 #define SOCK_INIT 0x13 #define SOCK_LISTEN 0x14 #define SOCK_ESTABLISHED 0x17 #define SOCK_CLOSE_WAIT 0x1C // ----------  «»  ----------- #define SERVER_IP0 192 //    192.168.0.155 #define SERVER_IP1 168 #define SERVER_IP2 0 #define SERVER_IP3 155 #define SERVER_PORT0 0 //    :80 #define SERVER_PORT1 80 #define GATEWAY_IP0 192 //  .     -  #define GATEWAY_IP1 168 #define GATEWAY_IP2 0 #define GATEWAY_IP3 254 #define SUBNET_MASK0 255 //   ( ) #define SUBNET_MASK1 255 #define SUBNET_MASK2 255 #define SUBNET_MASK3 0 #define MAC0 0x00 //   , ,     #define MAC1 0x1A //        #define MAC2 0x2B #define MAC3 0x3C #define MAC4 0x4D #define MAC5 0x5E //-----------    --------------- void SSPI_write(int Data); //  1   W5100  SPI int SSPI_read ( void); //  1   W5100  SPI void SetW5100register (int16 regaddr, int data); // ()  W5100  SPI int GetW5100register (int16 regaddr); //     W5100  SPI void Init (void); //  W5100   int Open_Socket0(void); //      (/) int Listen_Socket0(void); //      (/) int Socket0_Connection_Established (void); //        (/) int Socket0_Received_Data_Size (void); //    ,    ( 0   ) void Socket0_Received_Data_Reading (void); //      //   -    int Socket0_FIN_Received(void); //       FIN   / void Socket0_Disconnect(void); //    W5100     int Socket0_Closed(void); //       / int Socket0_Connection_Timeout(void); //     -    / void Socket0_Closing(void); //   int Socket0_Received_Request_is_index_html(void); //          Index.html //   / void Socket0_Send_index_html (void); //   «» index.html void Socket0_Send_404_error (void); //   «» « 404» //------------   ----------------------------------- int16 S0_RX_BASE; //   ,   RX   0 int16 S0_RX_MASK; //  RX  0 int16 S0_RX_OFFSET; //        RX  int16 S0_RX_Start_Addr; //        RX  int16 S0_RX_RSR ; //       int16 S0_TX_BASE; //   ,   X   0 int16 S0_TX_MASK; //  X  0 int16 S0_TX_OFFSET ; //        ,     //     int16 S0_TX_Start_Addr; //       ,    //      int16 S0_TX_End_Addr; //        ,   W5100 //        // ---      HTTP   «-» // *   [222]      .       // ** CONST –       (   ) CONST char INDEX[222] = { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Lenght: 43\r\n\r\n<HTML><CENTER>HELLO WORLD !</CENTER></HTML>"}; //     «index.html” CONST char ERROR404[222] = { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Lenght: 39\r\n\r\n<HTML><CENTER>ERROR 404</CENTER></HTML>"}; //     « 404” //     , //       « 404»,     , ... //CONST char ERROR404[222] = { "HTTP/1.1 404 Page not found\r\nContent-Type: text/html\r\nContent-Lenght: 39\r\n\r\n<HTML><CENTER>ERROR 404</CENTER></HTML>"}; // ..  IExplorer   HTTP  "HTTP/1.1 404 Page not found" //    ,   ,     int try=0; // ,  .    –  //===================== MAIN ============================================ //======================================================================= void main() { Init(); //  W5100   ( ) OpenSocket0: //ooooooooooooooooooo   0 oooooooooooooooooooooooo if ( ! Open_Socket0() ) goto OpenSocket0; //      //ooooooooooooooooo   ooooooooooooooooooooooooo if ( Listen_Socket0() == FALSE ) goto OpenSocket0; //    «» -      //oooooooooooooo   ? oooooooooooooo CheckConnection: // if (Socket0_Connection_Established() == FALSE ) goto CheckConnection; //      (       ) printf("> Connection Established... \r\n"); //   (  )   //ooooooo(   )    - ? oooooo if ( Socket0_Received_Data_Size() == 0 ) { printf("\r\n> (Zero) Received Data size is: %Lu (bytes) \r\n", S0_RX_RSR); //   (  )   goto CheckFIN; //          //      FIN } //    ( =0)        else { printf("\r\n> (NonZero) Received Data size is: %Lu (bytes) \r\n", S0_RX_RSR); //   (  )   } // oooooooooo (    )  * ooooooooooooooo //         //       Socket0_Received_Data_Reading(); //   (  )   // oooooooooooooo    ooooooooooooooooooooooooooooooo //    HTTP   HTML  if ( Socket0_Received_Request_is_index_html() == TRUE) Socket0_Send_index_html (); //    "index.html"    index.html else Socket0_Send_404_error (); //        «» « 404» //ooooooooooo   FIN ? ooooooooooooooooooooooooooo //        CheckFIN: if ( Socket0_FIN_Received() == TRUE) goto CloseConnection; //  FIN  -    0 //ooooooooooo   ooooooooooooooooooooooo Socket0_Disconnect(); //   0 //ooooooooooo   ? ooooooooooooooooooooooooooooooo if (Socket0_Closed() == TRUE ) goto CloseConnection; //    –    //ooooooooooo    -   ? ooooooooooooooooooo if ( Socket0_Connection_Timeout() == TRUE) goto CloseConnection; //   ,   -, –    CloseConnection: //ooooooooooo   ooooooooooooooooooooooooooooooooooo Socket0_Closing(); //oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo goto OpenSocket0; //    ,  . //         (    «-» ) } //=================== END of MAIN =========================== //============================================================ //--------------------------------------------------------------- //--------------------------INIT ------------------------------- void Init (void) { output_low(RESET); //  «»   Ethernet  delay_ms(1); output_high(RESET); output_low(SCK); //   ()  SPI output_high(SS) ; //   W5100. SetW5100register(MR, 0x80); //   RST  W5100 Mode Register //------------   (W5100)   0 ------------- SetW5100register(RMSR, 0x55); //  RX :  2    S0_RX_BASE = 0x6000; //   RX   0 S0_RX_MASK = 0x07FF ; // (2048 -1 )= 0x07FF, RX  ( = _ – 1 ) SetW5100register(TMSR, 0x55); //  X :  2    S0_TX_BASE = 0x4000; //   TX   0 S0_TX_MASK = 0x07FF; // (2048 -1 )= 0x07FF,   ( = _ – 1 ) //------------     -------------- // ..      W5100 // –       SetW5100register(SHAR0, MAC0); SetW5100register(SHAR1, MAC1); SetW5100register(SHAR2, MAC2); SetW5100register(SHAR3, MAC3); SetW5100register(SHAR4, MAC4); SetW5100register(SHAR5, MAC5); //------------   IP -------------- //   -    W5100 –   SetW5100register(SIPR0, SERVER_IP0); SetW5100register(SIPR1, SERVER_IP1); SetW5100register(SIPR2, SERVER_IP2); SetW5100register(SIPR3, SERVER_IP3); //------------   PORT -------------- //   –   –   SetW5100register(S0_PORT0, SERVER_PORT0); SetW5100register(S0_PORT1, SERVER_PORT1); //------------  Gateway addr -------------- //   –   –   SetW5100register(GAR0, GATEWAY_IP0); SetW5100register(GAR1, GATEWAY_IP1); SetW5100register(GAR2, GATEWAY_IP2); SetW5100register(GAR3, GATEWAY_IP3); //------------ set Subnet Mask -------------- SetW5100register(SUBR0, SUBNET_MASK0); SetW5100register(SUBR1, SUBNET_MASK1); SetW5100register(SUBR2, SUBNET_MASK2); SetW5100register(SUBR3, SUBNET_MASK3); printf(" \r\n\r\n > =============== W5100 - ==========\r\n\r\n"); //   (  )   } //-------------------------------------------------------------- //-------------   0 ---------------------------- int Open_Socket0(void) { //   (  )   printf(" \r\n =========== TRY # %u ====================\r\n", try); if (try ==255) try =0; else try++; printf("\r\n> Start Open Socket... \r\n"); //   –   ,    SetW5100register(S0_MR, 0x01); //     –   ( ) SetW5100register(S0_CR, OPEN); //      // *    ,  «SOCK_INIT»      if (GetW5100register(S0_SR) != SOCK_INIT) //  STATUS  { SetW5100register(S0_CR, CLOSE); //      return FALSE ; //     0 } return TRUE; // .    1 } //-------------------------------------------------------------- //-------------  0    ------------ int Listen_Socket0 (void) { printf("> Sock opened. Go Listen... \r\n"); //   (  )   //           // * – ..  – ,      SetW5100register(S0_CR, LISTEN); if ( GetW5100register(S0_SR) != SOCK_LISTEN) //    { SetW5100register(S0_CR, CLOSE); //        return FALSE; //       0 } return TRUE; //    ,    1 } //-------------------------------------------------------------------------- //-------------      0 ? -------- // *     ( ) int Socket0_Connection_Established(void) { //  W5100      ,     //    ACK      SOCK_ESTABLISHED // («   ) //         , //    -    if ( GetW5100register(S0_SR) == SOCK_ESTABLISHED) return TRUE ; //   . //    () = «SOCK_ESTABLISHED»    1 else return FALSE; //   –    0 printf("> Connection Established... \r\n"); //   (  )   // *    ,    /  } //----      ------------- //----------------------------------------------------- // * «»        //          // (,  /  -) int Socket0_Received_Data_Size (void) //        =    { S0_RX_RSR = make16 (GetW5100register(S0_RX_RSR0), GetW5100register(S0_RX_RSR1) ); //   8-     // RSR0 –  , RSR1 –   //  «» 16-  -    printf("> Received Data size is: %Lu (bytes) \r\n", S0_RX_RSR); //   (  )   if (S0_RX_RSR == 0 ) return FALSE; //   ( .. =0 ) //    0 else return TRUE; //     ( ..  -) //    1 } //----------      --------------- //------------------------------------------------------------ // *     .    void Socket0_Received_Data_Reading (void) { int16 n; int RXbyte; S0_RX_OFFSET = make16 ( GetW5100register(S0_RX_RD0), GetW5100register(S0_RX_RD1) ); //   8-   16   - //       RX  0 printf("> S0_RX_RD (RX mem read pointer) = %LX \r\n", make16 ( GetW5100register(S0_RX_RD0), GetW5100register(S0_RX_RD1) ) ); S0_RX_OFFSET = (S0_RX_OFFSET & S0_RX_MASK ) ; //         0  printf("> S0_RX_Offset = S0_RX_RD & S0_RX_MASK = %LX \r\n\r\n",S0_RX_OFFSET ); S0_RX_Start_Addr = S0_RX_OFFSET + S0_RX_BASE ; //         printf("> S0_RX_Start_Addr = S0_RX_OFFSET + S0_RX_BASE = %LX (physical)\r\n\r\n", S0_RX_Start_Addr ); printf("> Going to print-out Received Data... \r\n\r\n"); printf("ooooooooooooooooooooooooooooooooooooooooooo\r\n"); for (n=0; n < S0_RX_RSR ; n++) { if ( S0_RX_Start_Addr > (S0_RX_BASE + S0_RX_MASK) ) S0_RX_Start_Addr = S0_RX_BASE; RXbyte = GetW5100register(S0_RX_Start_Addr); printf("%c", RXbyte); S0_RX_Start_Addr++; } printf("\r\noooooooooooooooo END of received data oooooooooooooo\r\n\r\n"); } // ---        INDEX.HTML  ------ //---------------------------------------------------------------------- int Socket0_Received_Request_is_index_html(void) { int RXbyte=0; S0_RX_OFFSET = make16 ( GetW5100register(S0_RX_RD0), GetW5100register(S0_RX_RD1) ); //   8-   16   - //       RX  0 S0_RX_OFFSET = (S0_RX_OFFSET & S0_RX_MASK ) ; //         0  S0_RX_Start_Addr = S0_RX_OFFSET + S0_RX_BASE ; //         printf("\r\n>----------- parsing HTTP header-------------\r\n"); //   (  )   while (RXbyte != 0x2F) //   "/"  HTTP  { if ( S0_RX_Start_Addr > (S0_RX_BASE + S0_RX_MASK) ) S0_RX_Start_Addr = S0_RX_BASE; //           // ,       //   –      –       RXbyte = GetW5100register(S0_RX_Start_Addr); //    RX ,     printf("%c", RXbyte); //   (  )   S0_RX_Start_Addr++; //   –       } //       («»)    HTTP   “/” //        "/" . //      - RXbyte = GetW5100register(S0_RX_Start_Addr); //   printf("\r\n> -------- END of parsing HTTP header -------\r\n"); //   (  )   if (RXbyte == 0x20) return TRUE; //   «» -      ,  index.html //     1 else return FALSE; //         ,    index.html //     - 0 } //------    « 404» ------------ //------------------------------------------------------------- //    0    HTTP   HTML  //  « 404»,   W5100    //     ,     void Socket0_Send_404_error (void) { int16 n; char TXbyte; int16 datalength; S0_TX_OFFSET = make16 ( GetW5100register(S0_TX_RD0), GetW5100register(S0_TX_RD1) ); //   8-   16   -  //  ,        X  0 S0_TX_OFFSET = (S0_TX_OFFSET & S0_TX_MASK ) ; //         0  S0_TX_Start_Addr = S0_TX_OFFSET + S0_TX_BASE ; //           //    HTTP   HTML  datalength=0; while ( ERROR404[datalength] !=0) datalength++; //   «datalength»      000   // (000 -   ) //  ,  W5100   ,    //    ,   ,    . //  , W5100       . //            W5100: //     -        //     2-  // *(           //       «»  ) S0_TX_End_Addr = make16 ( GetW5100register(S0_TX_WR0), GetW5100register(S0_TX_WR1) ); //    -       S0_TX_End_Addr += datalength ; // increment to fatalength //   (     )  «» //  2       SetW5100register(S0_TX_WR0, make8( S0_TX_End_Addr ,1) ); //   SetW5100register(S0_TX_WR1, make8( S0_TX_End_Addr,0) ); //   printf("\r\n>Data length is: %Lu \r\n", datalength); printf("\r\n>--- Filling TX buffer w data: -----------\r\n"); //   (  )   //        –   For (n=0; n < datalength; n++) //      { TXbyte = ERROR404[n]; //     ,      « » // ( HTTP   HTML ) //  «»   W5100        //      ,  ,   10  //   ,         // ,        if (S0_TX_Start_Addr > (S0_TX_BASE + S0_TX_MASK)) S0_TX_Start_Addr = S0_TX_BASE; // ..       –       // * W5100     (        ))  //   - ,  ,      //(  ,       ) –    //    //          //        –       SetW5100register( S0_TX_Start_Addr, TXbyte ) ; putc(TXbyte); //   (  )   S0_TX_Start_Addr++ ; //    (    ) } printf("\r\n>--- end of Filling -----------\r\n"); //   (  )   // ,        , // ,    ,      //      -  SEND SetW5100register(S0_CR, SEND); printf("> Data was sent \r\n\r\n"); //   (  )   } //----------------------------------------------------------- //--    «index.html» --------------- //------------------------------------------------------------------- void Socket0_Send_index_html (void) // send index.html "page" index.html { //    –         « 404» //  «»  HTTP   HTML  –  int16 n; char TXbyte; int16 datalength; printf("\r\n>...... going to send INDEX.HTML.....\r\n"); //   (  )   S0_TX_OFFSET = make16 ( GetW5100register(S0_TX_RD0), GetW5100register(S0_TX_RD1) ); //  2-         S0_TX_OFFSET = (S0_TX_OFFSET & S0_TX_MASK ) ; S0_TX_Start_Addr = S0_TX_OFFSET + S0_TX_BASE ; //         printf("\r\n INDEX[i], datalegth -------------\r\n"); //   (  )   //    datalength=0; while ( INDEX[datalength] !=0) datalength++; //    –      000 –    printf("%c %Lu ",INDEX[datalength], datalength ); //   (  )   //   W5100        S0_TX_End_Addr = make16 ( GetW5100register(S0_TX_WR0), GetW5100register(S0_TX_WR1) ); // «»  2    S0_TX_End_Addr += datalength ; // increment to fatalength //      //       1-  SetW5100register(S0_TX_WR0, make8( S0_TX_End_Addr ,1) ); //   SetW5100register(S0_TX_WR1, make8( S0_TX_End_Addr,0) ); //   printf("\r\n>Data length is: %Lu \r\n", datalength); printf("\r\n>--- Filling TX buffer w data: -----------\r\n"); //   (  )   //   –     For (n=0; n < datalength; n++) { TXbyte= INDEX[n]; //       « » index.html // (.. HTTP Header + HTML code) if (S0_TX_Start_Addr > (S0_TX_BASE + S0_TX_MASK)) S0_TX_Start_Addr = S0_TX_BASE; //       ,    –    SetW5100register( S0_TX_Start_Addr, TXbyte ) ; //      ( « ») –    putc(TXbyte); // printout to Terminal ( for testing purpose) //   (  )   S0_TX_Start_Addr++ ; //       } printf("\r\n>--- end of Filling -----------\r\n"); //   (  )   //     ,     //      -  SEND SetW5100register(S0_CR, SEND); printf("> Data was sent \r\n\r\n"); //   (  )   } //-------------------------------------------------------- //---   ,   ,   FIN ? ------ //----------------------------------------------------------------------------- int Socket0_FIN_Received(void) { //        ( ) //    FIN -     //         //    –     0 //   1  FIN    0  FIN   if ( GetW5100register(S0_SR) == SOCK_CLOSE_WAIT) return TRUE; else return FALSE; } //--------------------------------------------------------- // ------    Socket0 ----------------- //------------------------------------------------------------- void Socket0_Disconnect(void) { //       //       0 SetW5100register(S0_CR, DISCON); } // ------   0  -------------------- //-------------------------------------------------------- int Socket0_Closed(void) { //            //   (CLOSE),   -,     //   0   // *        , //    -    If ( GetW5100register(S0_SR) == SOCK_CLOSED) return TRUE; else return FALSE; //   1   (  0)  //   0        } // -----   -   0 ? ------------ //------------------------------------------------------------- int Socket0_Connection_Timeout(void) { //    ,     ,     //     –    - //   ,        // (   TCP  )   ,   //      // -        //     –     0 // :  ,     «SOCK_CLOSED» // -     -?? //            -, //   W5100  «SOCK_CLOSED»     - //      –   If ( GetW5100register(S0_SR) == SOCK_CLOSED) return TRUE; else return FALSE; //   1  - ,   0  -   } // ------------  0 ---------------------------- //---------------------------------------------------------------- void Socket0_Closing(void) { // should be performed in case that connection is closed after data exchange, // socket should be closed with Timeout occurrence, // or forcible disconnection is necessary due to abnormal operation etc. printf(">going to Close Socket0 ..... \r\n"); //   (  )   //     0     SetW5100register(S0_CR, CLOSE); printf("> ------ Socket CLOSED ----- \r\n\r\n"); //   (  )   } // ----  ()   SPI ------------- //-------------------------------------------------------- //*     «SSPI» ,      //   (SPI
 )  .      //      ()   –     //   –     SPI //    «»  (    )  //   -      //*    -   W5100     0  1 void SSPI_write( int Data) { int i; int mask=0x80; //      (    ) //     SPI  W5100   //    -   ( MSB first) output_low(SCK); //       –  «»  for (i=0; i<8;i++) //    8  { output_low(MOSI); //   «»   -  0 if ( (mask & Data) != 0) output_high(MOSI); //  ( & ) =1     1 //   –       0,    output_high(SCK); //    (  0  1) -       //    SPI –   W5100 mask = mask>>1; ; //    1   // *       //        //     (  ) output_low(SCK); //  ,    «»  ( 0 ) } // «..    » () } //---------------------------------------------------------- //-----------     SPI ------------------ //----------------------------------------------------------- //*    «SSPI» ,      //   (SPI
 )  .      //        –     //   –    //    «»  //     // *     W5100 -      1  0 //*           //           0  1 //         1,   //  «»     1  0 int SSPI_read ( void) { int Data=0; int i; int mask=0x80; //      (    ) //     SPI  W5100   //    -   ( MSB first) output_low(SCK); //       –  «»  for (i=0; i<8;i++) //    8  { output_high(SCK); //    (  0  1) if ( input(MISO)!= 0) Data = Data | mask ; //    1,     –    «»  mask = mask>>1; ; //    1   // *     //        //     (  ) output_low(SCK); //  ,    «»  ( 0 ) } return Data; } //--------------------------------------------------------------- //-------  ( )  W5100 ------------- //-------------------------------------------------------------- void SetW5100register (int16 regaddr, int8 data) // 2 : 16     8     { output_low(SS); //    (   0) SSPI_write (0xF0); //       //* make8 –  16  -  8  SSPI_write ( make8(regaddr,1) ); //      (MSB) //     SPI SSPI_write ( make8(regaddr,0) ); //      (LSB) //     SPI SSPI_write (data); //   SPI      output_high(SS); //   (   1) } //--------------------------------------------------------- //-----    W5100 ---------- //---------------------------------------------------- int GetW5100register (int16 regaddr) // – 2-   // : 1      { int RegData; output_low(SS); //    (   0) SSPI_write (0x0F); //     //* make8 –  16   8  SSPI_write ( make8(regaddr,1) ); //      (MSB) //     SPI SSPI_write ( make8(regaddr,0) ); //      (LSB) //     SPI RegData = SSPI_read (); //    W5100    (8 ) //       output_high(SS); //   (   1) return RegData; //     } //************* END of PROGRAM **************
      
      










All Articles