【1】去lwip的官方網站下載最新的lwip-2.0.2.zip
【2】新建空白STM32工程,建工程時一定要在Manage Run-Time Environment對話框裏勾選啟動文件
【3】新建一個main.c文件,文件內容如下:
#include <stdio.h>
#include <stm32f10x.h>
#include "lwip/etharp.h" // etharp_tmr函數所在的頭文件
#include "lwip/init.h" // lwip_init函數所在的頭文件
#include "lwip/priv/tcp_priv.h" // tcp_tmr函數所在的頭文件
#include "netif/ethernet.h" // ethernet_input函數所在頭文件
#include "ENC28J60.h"
// 這兩個函數位於ethernetif.c中, 但沒有頭文件聲明
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif);
// 聲明httptest.c中的函數
void init_http(void);
// printf串口輸出
// 必須要在項目屬性里勾選Use MicroLIB後才能使用
int fputc(int ch, FILE *fp)
{
if (fp == &__stdout)
{
USART1->DR = ch;
while ((USART1->SR & USART_SR_TXE) == 0);
}
return ch;
}
int main(void)
{
struct ip4_addr ipaddr, netmask, gw;
struct netif enc28j60;
uint8_t cnt = 0;
// 配置PA口
RCC->APB2ENR = RCC_APB2ENR_IOPAEN;
GPIOA->CRH = 0x000004b3; // PA8為開發板上的一個LED燈
GPIOA->CRL = 0xb4bb0080;
GPIOA->BSRR = GPIO_BSRR_BS1; // PA1為網卡中斷輸出
// 配置SPI
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1; // 主機模式, 時鐘至少需要8分頻(BR=010), 也就是72MHz/8=9MHz
SPI1->CR2 = SPI_CR2_SSOE; // 開CS片選輸出
// 配置串口
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
USART1->BRR = 0x271; // 波特率: 115200
USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
printf("Hello World!\r\n");
// 配置定時器
RCC->APB1ENR = RCC_APB1ENR_TIM6EN;
TIM6->ARR = 2499; // 共2500個數, 2500*0.1ms=250ms
TIM6->PSC = 7199; // 72MHz/7200=10kHz -> 0.1ms
TIM6->CR1 = TIM_CR1_URS; // 防止UG=1時UIF置位
TIM6->EGR = TIM_EGR_UG; // 應用上述設置
TIM6->CR1 |= TIM_CR1_CEN; // 開定時器
lwip_init();
IP4_ADDR(&ipaddr, 192, 168, 0, 2); // IP位址
IP4_ADDR(&netmask, 255, 255, 255, 0); // 子網掩碼
IP4_ADDR(&gw, 192, 168, 0, 1); // 網關
netif_add(&enc28j60, &ipaddr, &netmask, &gw, NULL, ethernetif_init, ethernet_input);
netif_set_default(&enc28j60); // 設為默認網卡
netif_set_up(&enc28j60);
printf("進入主循環...\r\n");
init_http(); // 初始化HTTP服務
while (1)
{
if (ENC28J60_GetPacketNum() != 0)
{
GPIOA->ODR ^= GPIO_ODR_ODR8; // PA8上的LED燈閃爍表明系統正常工作
ethernetif_input(&enc28j60);
}
// 若定時器溢出
if (TIM6->SR & TIM_SR_UIF)
{
// 250ms
TIM6->SR &= ~TIM_SR_UIF; // 清除溢出標誌
cnt++;
if (cnt >= 20)
{
// 250ms * 20 = 5s
GPIOA->ODR ^= GPIO_ODR_ODR8; // LED燈每5秒鐘改變一次狀態
cnt = 0;
etharp_tmr(); // ARP定時處理
}
tcp_tmr(); // TCP定時處理
}
}
}