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

📄 main.c

📁 F020集成以太网接口核心模块以太网通讯与数据采集例程源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------// MN核心模块以太网测试程序
// CGI WEB服务器测试程序
// 版本:V2.1
// 核心模块物理参数:
// 1.主频:22.1184MHZ
// 2.RAM:片内4K,片外32K+256K(MAX)
// 
// COPYRIGHT 2007-2009
//------------------------------------------------------------------------------ 
// 版本记录:
// 版本              日期             内容
// 2007/05/15        1.0             基本WEB测试程序
// 2007/05/20        2.0             增加LED控制的CGI程序
// 2007/06/26        2.1             增加电压和温度采集部分,网页信息自动刷新(JavaScript)
//                                   增加mn_init_m函数,修正程序脱离调试器无法运行的问题
//-------------------------------------------------------------------------------------
// 实验效果:
// 从计算机浏览器中访问http://192.168.0.90,显示数据采集和控制页面
// 1.可以通过页面控制LED2
// 2.页面每两秒自动刷新一次温度和电压数据
//
// 实验条件:
// 1.JP1和JP2所有位处于ON状态
// 2.计算机与核心模块通过交叉网线连接(或两者都使用直联网线连接到HUB或路由器上)
// 3.计算机的IP地址必须为192.168.0.XXX,其中XXX可以为2-254中的数据,但不能为90(因为核心模块为90)
// 4.调解电位器可以观察到网页上的数据变化
// 
// 编译条件:
// 1.使用KEIL C8.0以上版本C51编译器
// 2.使用LARGE RAM模式
// 3.连接选项不使用覆盖分析,即增加连接选项NOOL
//--------------------------------------------------------------------------------------------

// //#include "mn_userconst.h"                      // TCP/IP Library Constants#include "mn_stackconst.h"                     // TCP/IP Library Constants#include "mn_errs.h"                           // Library Error Codes#include "mn_defs.h"                           // Library Type definitions#include "mn_funcs.h"                          // Library Function Prototypes#include "VFILE_DIR\index.h"#include <c8051F020.h>                         // Device-specific SFR Definitions

#include <stdio.h>
#include <ctype.h>                             // for toupper()

//-------------------------------
// 常量定义
//-------------------------------
#define SYSCLK          22118400

// AD内部参考电压,由于单片机个体差异,该参考电压可能不同
// 用户可测量J1双排插针的2,3引脚间的电压来调整该值,该值为
// 测量电压的1000倍
#define AD_VREF         2438

#define AD_VOLTAGE      0
#define AD_TEMPERATURE  8
  



//-----------------------------
// 引脚定义
//-----------------------------
sbit P_LED2  = P3^1;			// LED2 指示灯
sbit P_RST   = P3^0;			// CP2201复位引脚
sbit INT_PIN = P2^2;		    // CP2201中断引脚
//------------------------------------------------------------------------------// Function Prototypes//------------------------------------------------------------------------------// Initialization Routinesvoid PORT_Init (void);void SYSCLK_Init (void);void EMIF_Init(void);
void Timer_Init();

void UART0_Init();
void SendString(char *pSendString);
int establish_network_connection();
void get_data (PSOCKET_INFO socket_ptr);
void get_led(PSOCKET_INFO socket_ptr);
void set_led(PSOCKET_INFO socket_ptr);



void Dlyms(unsigned int ms);              

void ADC_Init();
void Voltage_Reference_Init();
void DAC_Init();

unsigned long SampleVoltageAndOut();
long SampleTemperature();

void InitVariable();


//---------------------------------------------
// 全局变量定义
//----------------------------------------------
unsigned char HTML_BUFFER[400];
unsigned char msg_ans[20];

unsigned long   g_Voltage;         // 电压
long            g_Temperature;     // 温度 
unsigned char   g_ADChannel;

//------------------------------------------------
// mn_init_m:修正库函数中的mn_init函数
//-------------------------------------------------
//------------------------------------
// mn_init_m修正函数使用的变量声明
//-----------------------------------
#include <string.h>

extern byte code NUM_SOCKETS;
extern byte code DEVICE_ID;
extern byte code NUM_VF_PAGES;
extern byte code NUM_POST_FUNCS;

int  mn_ip_init();
void mn_timer_init();
void mn_http_init();
void mn_arp_init();

int mn_init_m(void)
{
	unsigned char chip_id,val,i;
	int data num;
	bit c;

	c = EA;
    EA = 0;
    chip_id = DEVICE_ID;
	if (chip_id != C8051F020)
		return  MN_VERIFY_ERROR;

    // 此处省略了原代码中的器件判断部分

    //sock_info,在任何情况下必需调用
 	num = (unsigned int)NUM_SOCKETS*sizeof(SOCKET_INFO_T);//0x3D; 
    val = 0;
	memset(sock_info,val,num); 

    //mn_ip_init: 在任何情况下必需调用
	num = mn_ip_init();
	if (num!=0)
	{

        //mn_timer_init:必需调用
		mn_timer_init();

        //使用DHCP时调用
        //mn_dhcp_init();

        //使用BOOTP时调用
        //mn_bootp_init();

        //vf_dir init, 在任何情况下必需调用
		num = (unsigned int)NUM_VF_PAGES*sizeof(VF);//(0x1F);
    	val = 0;
		memset(vf_dir,val,num); 

    	for (i=0;i<NUM_VF_PAGES;i++)
			  vf_dir[i].cp2200_page_ptr = 0x2000;

        //page_send_info init,在任何情况下必需调用 	
		num = (unsigned int)NUM_SOCKETS*sizeof(PAGE_SEND_T); 
    	val = 0;
		memset(page_send_info,val,num);

		for (i=0;i<NUM_SOCKETS;i++)
			  page_send_info[i].cp2200_page_ptr = 0x2000;

        // pf init,在任何情况下必需调用
		num = (unsigned int)NUM_POST_FUNCS*sizeof(POST_FUNCS);//(0x1F);
    	val = 0;
		memset(pf,val,num); 

        //使用HTTP时调用
		mn_http_init();                             

        //使用TFTP时调用
        //mn_ftp_server_init();

        //使用SMTP时调用
        //mn_smtp_init();

        //在任何情况下必需调用
		mn_arp_init();
		EA = c;
		return  0x0001;
    }
	else
	{
		 EA = c;
		 return  MN_INIT_ERROR;
	}
}

////////////////////////////////////////////////////////////////////////////////

// AD中断服务程序
void AD_Isr() interrupt 15
{
	unsigned int nRet;
	unsigned long lt;
	long t;

	AD0INT = 0;      // 清除中断标志

	if(g_ADChannel==AD_VOLTAGE)
	{// 上次采集的是电压值
		
		// 从DA输出电压
		DAC0L = ADC0L;
		DAC0H = ADC0H;


		nRet = ADC0H;
		nRet<<=8;
		nRet+=ADC0L;
	
		lt = nRet+1;
		lt =lt*AD_VREF;
		lt >>=12;


		g_Voltage = lt;

		g_ADChannel = AD_TEMPERATURE;


	}
	else if(g_ADChannel==AD_TEMPERATURE)
	{// 上次采集的是温度

		nRet = ADC0H<<8;
		nRet+=ADC0L;
	
		lt =nRet+1;
		lt =lt*AD_VREF;
		lt >>=12;
	
		t=lt-776;

		g_Temperature = (g_Temperature+t)>>1;  // /2


		g_ADChannel = AD_VOLTAGE;
	}
	else
	{
		g_ADChannel = AD_VOLTAGE;
	}


	AMX0SL   = g_ADChannel;
	AD0BUSY = 1;                    // 启动转换

}


//-----------------------------------------------------------------------------
// 主函数
//-----------------------------------------------------------------------------
void main(void)
{
   data int retval;
   
   
   // 关闭看门狗
   WDTCN = 0xde;
   WDTCN = 0xad;

   // 初始化硬件
   EMIF_Init();
   PORT_Init();
   SYSCLK_Init();
   
   Timer_Init();
   UART0_Init();
 	
   // 初始化模拟部分
   InitVariable();

   ADC_Init();
   Voltage_Reference_Init();
   DAC_Init();
   
   // 系统启动
   SendString("CGI Test System!\r\n");


   P_LED2 = 0;

   // 首先进行一次温度采集,初始化温度值
   SampleTemperature();

   EIE2|=0x02;         //使能AD中断

   AMX0SL   = g_ADChannel;
   AD0BUSY = 1;        // 启动转换

   
   while(1)
   {	 

	  // 此处不使用mn_init函数而改用mn_init_m函数
	  // 以解决原库函数不能脱离调试器运行的问题
	  // 用户应该根据程序实际使用的协议来调整该函数
	  // 具体参加该函数	  
      while((retval=mn_init_m()) < 0)
      {
         // If code execution enters this while(1) loop, the stack failed to initialize.
         // Verify that all boards are connected and powered properly.
		
 		 P_LED2 = !P_LED2;
													   
		 SendString(HTML_BUFFER);

		 Dlyms(1000);
      }	 	  
	 


      P_LED2 = 1;

      // Connect to the network
      establish_network_connection();

      // Add web page to virtual file system.
      // The main page MUST be called index.htm or index.html.
      mn_vf_set_entry((byte *)"index.html", INDEX_SIZE, index_html, VF_PTYPE_FLASH);
	  
	  
      mn_pf_set_entry(
	  	(byte*)"get_data",	             // Script Name (ASCII)
      	get_data	                     // Function Pointer
      );
	  mn_pf_set_entry(
	  	(byte*)"set_led",	             // Script Name (ASCII)
      	set_led	                         // Function Pointer
      );

	  
      // Start the Application Layer Services
      // If this routine exits, check the return value for an error code.
      retval = mn_server();

   }
}

//-----------------------------------------------------------------------------
// establish_network_connection
//-----------------------------------------------------------------------------
//
// This function calls mn_ether_init() to initialize the CP2200 and attach to
// the network.
//
// If there is a network connection, the function returns 1.
//
// In the call to mn_ether_init(), NUM_AUTONEG_ATTEMPTS is set to 0, so the
// function will not return until it successfully auto-negotiates.
//
// mn_ether_init() will not be a blocking call if NUM_AUTONEG_ATTEMPTS is set
// to a value greater than 0.
//
int establish_network_connection()
{
   int retval;

   do
   {
      // mn_ether_init() initializes the Ethernet controller.
      // AUTO_NEG indicates that the controller will auto-negotiate.
      retval = mn_ether_init(AUTO_NEG, 0, 0);

      // If there is no link, poll link_status until it sets or the
      // CP2200 resets and then call mn_ether_init() again.
      if (retval == LINK_FAIL)
      {
         while(!link_status && !ether_reset);
      }

      // If retval is less than zero and is not LINK_FAIL, there is a 
      // hardware error.
      else if (retval < 0)
      {
         // Verify that the Ethernet controller is connected and powered properly.
         // Verity that the EMIF has been configured at a speed compatible with the
         //    Ethernet controller.
         while(1);
      }

   }while(retval < 0);

   return (1);

}

//-----------------------------------------------------------------------------// ether_reset_low//-----------------------------------------------------------------------------//// This routine drives the reset pin of the ethernet controller low.//void ether_reset_low(){  	P_RST = 0;}//-----------------------------------------------------------------------------// ether_reset_high//-----------------------------------------------------------------------------//// This routine places the reset pin in High-Z allowing it to be pulled up // using the external pull-up resistor.//// Additionally, this routine waits for the reset pin to read high before// exiting.//void ether_reset_high (void){   P_RST = 1;
   while(P_RST==0);}

//-----------------------------------------------------------------------------
// CGI Script: get_data
// 读取voltage&temperature状态 CGI程序
// 该函数返回电路板测试的电压和温度值
// 当使用CGI Script时调用该接口
//-----------------------------------------------------------------------------


void get_data (PSOCKET_INFO socket_ptr)
{
	bit field_name_found;
	unsigned int high,low;
   
	
	xdata byte msg_buff[75];
  
	
	// Search the URL for field-name = "type" and copy field-value to <msg_buff>
	field_name_found = mn_http_find_value(BODYptr,(byte *)"type",msg_buff);
	if(field_name_found)
	{      
		// Type Check #1 
		// Check if the requested data type is "Temperature"
		if( toupper(msg_buff[0]) == 'T')
		{
			
			// Search the URL for field-name = "format" and copy field-value to <msg_buff>
			field_name_found = mn_http_find_value(BODYptr,(byte *)"format",msg_buff);         
			
			// Check if the requested format is HTML
			if(field_name_found && toupper(msg_buff[0]) == 'H')
			{
				
				// User has requested temperature data in HTML format:
				EA = 0;
				g_Temperature*=100;
				high = g_Temperature/286;
				low  = g_Temperature-high*286;
				sprintf(HTML_BUFFER, "<html><body bgcolor=blue text=yellow><center><span style=\"font-family: sans-serif; font-size: 28pt; font-weight: bold;\">%d.%03d</span></center></body></html>",
				       high,low);    
				EA = 1;

				SendString(HTML_BUFFER);
				
				socket_ptr->send_ptr = (byte *)HTML_BUFFER;
				socket_ptr->send_len = strlen(HTML_BUFFER);
				
			} 
			
		} 
		else
		{
			
			if( toupper(msg_buff[0]) == 'V')
			{       
				

⌨️ 快捷键说明

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