⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 在Luminary单片机的以太网控制器的底层驱动程序的编写!Luminary的单片机采用Cortex-M3内核
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.embedtools.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name:          main.c
** Last modified Date: 2008.7.18
** Last Version:       1.0
** Description:        Luminary系列MicroControllers以太网应用uIP TCP/IP协议栈应用模板,包含了主函数控制
**                     循环
** 
**------------------------------------------------------------------------------------------------------
** Created By:         任海波
** Created date:       2008.7.18
** Version:            1.0
** Descriptions:       The original version 初始版本
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include"includes.h"
uint8 IPAddress[4]=MY_IP_ID;
uint8 IPNetMask[4]=IP_MARK_ID;
uint8 MACAddress[6]=My_Mac_ID;
uint8 IPGateWAY[4]=MY_GATEWAY_ID;

/*************************************************************************************
***设定系统时钟定时器的常数
**************************************************************************************/
#define SYSTICKHZ               100
#define SYSTICKMS               (1000 / SYSTICKHZ)
#define SYSTICKUS               (1000000 / SYSTICKHZ)
#define SYSTICKNS               (1000000000 / SYSTICKHZ)

/******************************************************************************
**定义一个宏,可以访问缓冲区中以太网数据报的报头信息
******************************************************************************/
#define BUF                     ((struct uip_eth_hdr *)&uip_buf[0])

/**********************************************************************
**设置一些标志位,各标志位的定义如下:
**标志位0:指示一个系统时钟定时器中断发生
**标志位1:一个以太网数据包接收中断发生
************************************************************************/
#define FLAG_SYSTICK            0
#define FLAG_RXPKT              1
static volatile unsigned long g_ulFlags;

/**********************************************************************
***uIP TCP/IP协议栈的定时器常数(以ms为单位)
************************************************************************/
#define UIP_PERIODIC_TIMER_MS   500
#define UIP_ARP_TIMER_MS        10000

/**********************************************************************
***如果系统的驱动库调用出错,将会弹出提示,可以查出相应的错误
************************************************************************/
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
/****************************************************************************
**函数原型:    SysTickIntHandler()
**入口参数:		无
**出口参数:		无
**返 回 值:	无            
**说    明:	系统时钟定时器中断,标志中断发生 
*****************************************************************************/
void
SysTickIntHandler(void)
{
    // 标志一个系统时钟定时器中断已经发生.
    HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 1;
}

/****************************************************************************
**函数原型:    EthernetIntHandler()
**入口参数:		无
**出口参数:		无
**返 回 值:	无            
**说    明:	以太网中断,标志中断发生 
*****************************************************************************/
void
EthernetIntHandler(void)
{
    unsigned long ulTemp;
   /****************读取并清除中断*************/
    ulTemp = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulTemp);

    // 检查发生的是否是一个数据包接收的中断
    if(ulTemp & ETH_INT_RX)
    {
       // 指示一个数据包已经被接收
        HWREGBITW(&g_ulFlags, FLAG_RXPKT) = 1;

        // 禁止以太网接收中断
        EthernetIntDisable(ETH_BASE, ETH_INT_RX);
    }
}
/****************************************************************************
**函数原型:    main()
**入口参数:		无
**出口参数:		无
**返 回 值:	无            
**说    明:	uIP TCP/IP协议栈应用的主函数,其中包含了底层的硬件驱动
*****************************************************************************/
int
main(void)
{
    uip_ipaddr_t ipaddr;
    static struct uip_eth_addr sTempAddr;
    long lPeriodicTimer, lARPTimer, lPacketLength;
    unsigned long ulTemp;

    // 根据硬件电路的晶振设置系统时钟
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_8MHZ);

    // 使能并复位以太网控制器
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);


    // 使能PF口的以太网控制器的发生接收指示灯.
    //  LED0        Bit 3   输出
    //  LED1        Bit 2   输出
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_DIR_MODE_HW);
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3,
                     GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

    // 配置初始化系统时钟定时器,并使能该定时器中断
    SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ);
    SysTickEnable();
    SysTickIntEnable();

    // 初始化以太网控制器,并禁止以太网控制器的所有中断源
    EthernetIntDisable(ETH_BASE, (ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
                       ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
    ulTemp = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulTemp);

    // 初始化以太网控制器,以便可以操作它
    EthernetInitExpClk(ETH_BASE, SysCtlClockGet());

    // 配置以太网控制器,使它以正常的模式工作.
    // - 全双工
    // - TX CRC 校验自动产生
    // - TX Padding Enabled
    EthernetConfigSet(ETH_BASE, (ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN |
                                 ETH_CFG_TX_PADEN));

    // 使能以太网控制器.
    EthernetEnable(ETH_BASE);

    // 使能以太网控制器的中断.
    IntEnable(INT_ETH);

    // 使能以太网控制器的数据包接收中断.
    EthernetIntEnable(ETH_BASE, ETH_INT_RX);

    // 使能系统总中断
    IntMasterEnable();

    // 初始化 uIP TCP/IP 协议栈.
    uip_init();
    uip_ipaddr(ipaddr, IPAddress[0], IPAddress[1], IPAddress[2],
               IPAddress[3]);
    uip_sethostaddr(ipaddr);
    uip_ipaddr(ipaddr, IPNetMask[0], IPNetMask[1], IPNetMask[2],
               IPNetMask[3]);
    uip_setnetmask(ipaddr);

    //配置以太网控制器的硬件物理地址(即MAC地址)
    sTempAddr.addr[0] = MACAddress[0];
    sTempAddr.addr[1] = MACAddress[1];
    sTempAddr.addr[2] = MACAddress[2];
    sTempAddr.addr[3] = MACAddress[3];
    sTempAddr.addr[4] = MACAddress[4];
    sTempAddr.addr[5] = MACAddress[5];
     EthernetMACAddrSet(ETH_BASE, (unsigned char *)&sTempAddr);
    uip_setethaddr(sTempAddr);

/*********这这里初始化一个具体的应用***********************************/
	 httpd_init();

    // 主控制应用程序循环.
    lPeriodicTimer = 0;
    lARPTimer = 0;
    while(true)
    {
    	//等待一个事件发生。该事件可以是一个系统时钟定时器的事件也可以是一个RX数据包接收的中断
        while(!g_ulFlags)
        {
        }
        //事件发生,如果是系统时钟定时器中断,则清除中断标志位,并给计数定时器加 1
        if(HWREGBITW(&g_ulFlags, FLAG_SYSTICK) == 1)
        {
            HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 0;
            lPeriodicTimer += SYSTICKMS;
            lARPTimer += SYSTICKMS;
        }
        //
        //检查RX接收缓冲区中是否有数据,并读取.
        //
        lPacketLength = EthernetPacketGetNonBlocking(ETH_BASE, uip_buf,
                                                     sizeof(uip_buf));
        if(lPacketLength > 0)
        {
            // 设置 uip_len 用来指示uIP stack 可用.
            uip_len = (unsigned short)lPacketLength;

            // 清除RX数据包接收中断,并重新使能该中断
            if(HWREGBITW(&g_ulFlags, FLAG_RXPKT) == 1)
            {
                HWREGBITW(&g_ulFlags, FLAG_RXPKT) = 0;
                EthernetIntEnable(ETH_BASE, ETH_INT_RX);
            }

            // 这里处理IP数据包接收
            if(BUF->type == htons(UIP_ETHTYPE_IP))
            {
                uip_arp_ipin();
                uip_input();
                //
                // If the above function invocation resulted in data that
                // should be sent out on the network, the global variable
                // uip_len is set to a value > 0.
                //
                if(uip_len > 0)
                {
                    uip_arp_out();
                    EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
                    uip_len = 0;
                }
            }

            //
            // 这里处理ARP数据包接收
            //
            else if(BUF->type == htons(UIP_ETHTYPE_ARP))
            {
                uip_arp_arpin();
                //
                // If the above function invocation resulted in data that
                // should be sent out on the network, the global variable
                // uip_len is set to a value > 0.
                //
                if(uip_len > 0)
                {
                    EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
                    uip_len = 0;
                }
            }
        }

        //这里处理Timer决定的TCP/IP周期性事件.
        if(lPeriodicTimer > UIP_PERIODIC_TIMER_MS)
        {
            lPeriodicTimer = 0;
            for(ulTemp = 0; ulTemp < UIP_CONNS; ulTemp++)
            {
                uip_periodic(ulTemp);

                //
                // If the above function invocation resulted in data that
                // should be sent out on the network, the global variable
                // uip_len is set to a value > 0.
                //
                if(uip_len > 0)
                {
                    uip_arp_out();
                    EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
                    uip_len = 0;
                }
            }

#if UIP_UDP
            for(ulTemp = 0; ulTemp < UIP_UDP_CONNS; ulTemp++)
            {
                uip_udp_periodic(i);

                //
                // If the above function invocation resulted in data that
                // should be sent out on the network, the global variable
                // uip_len is set to a value > 0.
                //
                if(uip_len > 0)
                {
                    uip_arp_out();
                    EthernetPacketPut(ETH_BASE, uip_buf, uip_len);
                    uip_len = 0;
                }
            }
#endif // UIP_UDP
        }

        //
        // Process ARP Timer here.
        //
        if(lARPTimer > UIP_ARP_TIMER_MS)
        {
            lARPTimer = 0;
            uip_arp_timer();
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -