學號:140201211 姓名:張潤澤html
組別:第3組 實驗地點:D19程序員
1、實驗目的:瀏覽器
1.熟悉WWW技術中的SSI(Server Side Include)技術。服務器
2.學會使用SSI技術編寫代碼把當前開發板內RTC的時鐘及日期數據送往PC機瀏覽器顯示。異步
3.學會使用SSI技術把當前開發板的按鍵(KEY二、KEY1)次數信息送往PC機瀏覽器顯示。tcp
2、實驗內容:ide
1.編寫代碼完成Web服務器端發送RTC實時時 鍾信息的任務。函數
2.編寫代碼完成Web服務器端發送按鍵(KEY二、KEY1)按鍵次數的任務。3d
3、實驗過程描述及結果展現:調試
SSI技術簡介 服務器端嵌入SSI(Server Side Include)是一種基於服務器的網頁製做技術。大多數的WEB服務器等均支持SSI命令。將內容發送到瀏覽器以前,可使用「SSI」指令將文本、圖形或應用程序信息包含到網頁中。由於包含SSI指令的文件要求特殊處理,因此必須爲全部SSI文件賦予SSI文件擴展名。默認的擴展名是.stm、.shtm、.shtml。
SSI是爲WEB服務器提供的一套命令,這些命令只要直接嵌入到HTML文檔的註釋內容之中便可。如:<!=--#include file = 「info.htm」-->就是一條SSI指令,其做用是將「info.htm」的內容拷貝到當前頁面中。 <!=-- -->是HTML語法中的註釋,當WEB服務器不支持SSI時,會忽略這些信息。
按鍵與STM32的硬件鏈接圖
STM32F407芯片與鍵盤的鏈接電路圖以下所示
代碼展現:
#include "sys.h"
#include <string.h>
#include "delay.h"
#include "httpd.h"
#include "lwip/tcp.h"
#include "fs.h"
#include "lwip_comm.h"
void system_init(void);
void RTCTime_Handler(char *pcInsert);
void RTCDate_Handler(char *pcInsert);
void RTCKey1_Handler(char *pcInsert);
void RTCKey2_Handler(char *pcInsert);
const char *ppcTAGs[]=
{
"time",
"date",
"key2",
"key1"
};
u8 key1=0,key2=0;
void EXTI2_IRQHandler(void){
delay_ms(10);
key1++;
printf("%d\n",key1);
EXTI_ClearITPendingBit(EXTI_Line2);
}
void EXTI3_IRQHandler(void){
delay_ms(10);
key2++;
printf("%d\n",key2);
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTIX_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
KEY_Init(); //按鍵對應的I/O初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時鐘
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//PE2 鏈接到中斷線2
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);//PE3 鏈接到中斷線3
/*配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 /*| EXTI_Line4*/;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //降低沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中斷線使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中斷2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//搶佔優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中斷3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//搶佔優先級2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
}
int main(void)
{
system_init();//系統化初始化
//如下代碼對RTC進行初始化
{
RTC_InitTypeDef RTC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能電源接口時鐘
PWR_BackupAccessCmd(ENABLE);//使能RTC+SRAM區域
RCC_LSEConfig(RCC_LSE_ON);//開啓LSE時鐘
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //選擇LSE時鐘做爲RTC時鐘
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //等待LSE準備好
RCC_RTCCLKCmd(ENABLE);//使能RTC時鐘
while(RTC_Wait_Synchro());//等待RTC和APB同步
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//24小時格式
RTC_InitStructure.RTC_SynchPrediv = 0xFF;//同步預分頻器
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;//異步預分頻器
RTC_Set_Time(10,0,0,0);//設置時間
RTC_Set_Date(17,3,20,1);//設置日期
}
EXTIX_Init();
//uart_init(115200); //串口初始化
while(1)
{
lwip_periodic_handle();//LWIP輪詢任務
}
}
//SSI的Handler
u16_t SSIHandler(int iIndex,char *pcInsert,int iInsertLen)
{
switch(iIndex)//iIndex索引號
{
case 0:
RTCTime_Handler(pcInsert);
break;
case 1:
RTCDate_Handler(pcInsert);
break;
case 2:
RTCKey2_Handler(pcInsert);
break;
case 3:
RTCKey1_Handler(pcInsert);
break;
}
return strlen(pcInsert);
}
//SSIHandler中須要用到的處理RTC時間的函數
void RTCTime_Handler(char *pcInsert)
{
u8 hour,min,sec,ampm;
RTC_Get_Time(&hour,&min,&sec,&m);
*(pcInsert+0) = (char)((hour/10)+0x30);
*(pcInsert+1) = (char)((hour%10)+0x30);
*(pcInsert+2) = ':';
*(pcInsert+3) = (char)((min/10)+0x30);
*(pcInsert+4) = (char)((min%10)+0x30);
*(pcInsert+5) = ':';
*(pcInsert+6) = (char)((sec/10)+0x30);
*(pcInsert+7) = (char)((sec%10)+0x30);
}
void RTCDate_Handler(char *pcInsert)
{
u8 year,month,day,week;
RTC_Get_Date(&year,&month,&day,&week);
*(pcInsert+0) = '2';
*(pcInsert+1) = '0';
*(pcInsert+2) = (char)((year/10)+0x30);
*(pcInsert+3) = (char)((year%10)+0x30);
*(pcInsert+4) = '-';
*(pcInsert+5) = (char)((month/10)+0x30);
*(pcInsert+6) = (char)((month%10)+0x30);
*(pcInsert+7) = '-';
*(pcInsert+8) = (char)((day/10)+0x30);
*(pcInsert+9) = (char)((day%10)+0x30);
*(pcInsert+10) = ' ';
*(pcInsert+11) = 'w';
*(pcInsert+12) = 'e';
*(pcInsert+13) = 'e';
*(pcInsert+14) = 'k';
*(pcInsert+15) = ':';;
*(pcInsert+16) = (char)(week+0x30);
}
void RTCKey1_Handler(char *pcInsert)
{
if (key1<10)
{
*(pcInsert+0) = (char)(key1+0x30);
*(pcInsert+1) = '\0';
}
else
{
*(pcInsert+0) = (char)((key1/10)+0x30);
*(pcInsert+1) = (char)((key1%10)+0x30);
*(pcInsert+2) = '\0';
}
}
void RTCKey2_Handler(char *pcInsert)
{
if (key2<10)
{
*(pcInsert+0) = (char)(key2+0x30);
*(pcInsert+1) = '\0';
}
else
{
*(pcInsert+0) = (char)((key2/10)+0x30);
*(pcInsert+1) = (char)((key2%10)+0x30);
*(pcInsert+2) = '\0';
}
}
4、總結及實驗心得:
今天課上的任務是編寫代碼完成Web服務器端發送RTC實時時鐘信息以及完成Web服務器端發送按鍵(KEY二、KEY1)按鍵次數,由於有了以前幾回課的基礎,因此今天的課相對來講還算比較順利,大的問題沒有,都是一些小的細節問題,大部分時間都花費在了修改代碼上,看着一個個問題被咱們修改正確,程序得已成功的運行後,一股成就感油然而生,可能做爲一個局外人以爲結果纔是最重要的,可咱們做爲一名程序員卻以爲這其中的過程才更應該被記住,由於對咱們來講,這一段不斷修改調試的過程纔是最刻骨銘心的。