//-----------------------------------------------------------------
// 名称: STC15+W5500-Server模式应用
//-----------------------------------------------------------------
//网关:192.168.1.1
//掩码: 255.255.255.0
//物理地址:0C 29 AB 7C 00 01
//本机IP地址:192.168.1.199
//端口0的端口号:5000
//端口0的目的IP地址:192.168.1.190
//端口0的目的端口号:6000
//-----------------------------------------------------------------
#define u8 unsigned char
#define u16 unsigned int
#define MAIN_Fosc 12000000L //系统时钟
#include <string.h>
#include <stdio.h>
#include <intrins.h>
#include <stdlib.h>
#include "STC15xxx.h"
#include "W5500.h"
#include "src/oled.h"
#include "src/bmp.h"
//10号模块板外部资源引脚定义
sbit BEEP = P0^6;
sbit RELAY = P0^7;
sbit LED0 = P1^4;
sbit LED1 = P1^5;
sbit LED2 = P1^6;
volatile u8 LED_Control_Flag = 0;
sbit MA = P3^2;
sbit MB = P3^3;
sbit DQ = P1^7;
extern u8 Read_Temperature();
extern u8 Temp_Value[];
void Delay300us() { //@12.000MHz
u8 i, j; i = 4; j = 125;
do {
while (--j);
} while (--i);
}
//-----------------------------------------------------------------
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL 0x20 //360个时钟
#define ADC_SPEEDH 0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
extern void Delay1us();
extern void delay_us(u16 x);
extern void Delay1ms();
extern void delay_ms(u16 ms);
//-----------------------------------------------------------------
// 蜂鸣器程序
//-----------------------------------------------------------------
void Sound() {
u16 i;
for (i = 0; i < 300; i++) { Delay300us(); BEEP ^= 1;};
BEEP = 1;//最后要判断驱动三极管
}
void Delay(unsigned int d); //延时函数(ms)
//-----------------------------------------------------------------
// 初始化ADC
//-----------------------------------------------------------------
void InitADC() {
P1ASF = 0xF0; //P1高4位设为AD口
ADC_RES = 0; //结果寄存器清0
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;//上电,转换速度:540个时钟
delay_ms(2); //ADC上电并延时
}
//-----------------------------------------------------------------
// 读取ADC结果
//-----------------------------------------------------------------
u16 GetADCResult(u8 ch) {
ADC_RES = 0; ADC_RESL = 0; //A/D转换结果先清零(可省)
//选择通道并启动转换(含上电与540个时钟速度配置)
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
_nop_(); _nop_(); _nop_(); _nop_();
while (!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG; //清ADC结束标志
return (ADC_RES<<2 | ADC_RESL) ; //读取转换结果
}
//-----------------------------------------------------------------
// 读取ADC结果
//-----------------------------------------------------------------
u8 GetKeyStatus() {
u8 keystatus = 0x00;
if (GetADCResult(0)<400) keystatus |= 1<<0;
if (GetADCResult(1)<400) keystatus |= 1<<1;
if (GetADCResult(2)<400) keystatus |= 1<<2;
if (GetADCResult(3)<400) keystatus |= 1<<3;
return keystatus;
}
//-----------------------------------------------------------------
// W5500初始化
//-----------------------------------------------------------------
void W5500_Initialization(void) {
W5500_Init(); //初始化W5500寄存器函数
Detect_Gateway(); //检查网关服务器
Socket_Init(0); //指定Socket(0~7)初始化,初始化端口0
}
//-----------------------------------------------------------------
// W5500装载网络参数
// 网关、掩码、物理地址、本机IP地址、端口号、目的IP地址、目的端口号、端口工作模式
//-----------------------------------------------------------------
void Load_Net_Parameters(void) {
Gateway_IP[0] = 125;//加载网关参数
Gateway_IP[1] = 221;
Gateway_IP[2] = 52;
Gateway_IP[3] = 254;
Sub_Mask[0] = 255;//加载子网掩码
Sub_Mask[1] = 255;
Sub_Mask[2] = 255;
Sub_Mask[3] = 0;
Phy_Addr[0] = 0x0c;//加载物理地址
Phy_Addr[1] = 0x29;
Phy_Addr[2] = 0xab;
Phy_Addr[3] = 0x7c;
Phy_Addr[4] = 0x00;
Phy_Addr[5] = 0x01;
IP_Addr[0] = 125;//加载本机IP地址 125.221.52.100
IP_Addr[1] = 221;
IP_Addr[2] = 52;
IP_Addr[3] = 100;
S0_Port[0] = 0x13;//加载端口0的端口号5000
S0_Port[1] = 0x88;
// S0_DIP[0]=192;//加载端口0的目的IP地址
// S0_DIP[1]=168;
// S0_DIP[2]=1;
// S0_DIP[3]=190;
//
// S0_DPort[0] = 0x17;//加载端口0的目的端口号6000
// S0_DPort[1] = 0x70;
S0_Mode = TCP_SERVER;//加载端口0的工作模式,TCP服务端模式
}
//-----------------------------------------------------------------
// W5500端口初始化配置
// 分别设置4个端口,根据端口工作模式,将端口置于TCP服务器、TCP客户端或UDP模式.
// 从端口状态字节Socket_State可以判断端口的工作情况
//-----------------------------------------------------------------
void W5500_Socket_Set(void) {
if(S0_State==0) { //端口0初始化配置
if(S0_Mode==TCP_SERVER) { //TCP服务器模式
if(Socket_Listen(0)==TRUE) S0_State=S_INIT; else S0_State=0;
}
else if(S0_Mode==TCP_CLIENT) { //TCP客户端模式
if(Socket_Connect(0)==TRUE) S0_State=S_INIT; else S0_State=0;
}
else { //UDP模式
if(Socket_UDP(0)==TRUE) S0_State=S_INIT|S_CONN; else S0_State=0;
}
}
}
//-----------------------------------------------------------------
// W5500接收并发送接收到的数据
// 本过程先调用S_rx_process()从W5500的端口接收数据缓冲区读取数据,
////* 然后将读取的数据从Rx_Buffer拷贝到Temp_Buffer缓冲区进行处理。
////* 处理完毕,将数据从Temp_Buffer拷贝到Tx_Buffer缓冲区。调用S_tx_process()
////* 发送数据
//-----------------------------------------------------------------
void Process_Net_IO_Data(SOCKET s) {
unsigned short Size;
//读取接收缓冲中的数据放入Rx_Buffer并返回字节数
Size = Read_SOCK_Data_Buffer(s, Rx_Buffer);
Rx_Buffer[Size] = '\0';
if (strcmp((char*)Rx_Buffer,"BEEP") == 0) { Sound(); }
else if (strcmp((char*)Rx_Buffer,"LED_M") == 0) { LED_Control_Flag = 1; } //滚动显示
else if (strcmp((char*)Rx_Buffer,"LED_F") == 0) { LED_Control_Flag = 2; } //闪烁显示
else if (strcmp((char*)Rx_Buffer,"LED_K") == 0) { LED_Control_Flag = 0; } //停止显示
else if (strcmp((char*)Rx_Buffer,"RELAYON") == 0) { RELAY = 0; }
else if (strcmp((char*)Rx_Buffer,"RELAYOFF") == 0) { RELAY = 1; }
else if (strcmp((char*)Rx_Buffer,"MOTOR_F") == 0) { MA = 1; MB = 0;}
else if (strcmp((char*)Rx_Buffer,"MOTOR_R") == 0) { MA = 0; MB = 1;}
else if (strcmp((char*)Rx_Buffer,"MOTOR_STOP") == 0) { MA = 0; MB = 0;}
OLED_ShowString(6,0,Rx_Buffer,16);
// //所接收数据全部放的发送缓冲Tx_Buffer
// memcpy(Tx_Buffer, Rx_Buffer, Size);
//
// Write_SOCK_Data_Buffer(s, Tx_Buffer, Size);
}
//-----------------------------------------------------------------
// T0初始化(16位自动重装载模式/12分频,5ms@12MHz)
//-----------------------------------------------------------------
void Timer0Init() {
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x78; //设置定时初值
TH0 = 0xEC; //设置定时初值
//上述两行由STC-ISP自动生成的语句还可写成以下语句
//TL0 = (65536 - 5000) & 0x00FF;
//TH0 = (65536 - 5000) >> 8;
//或者:
//TL0 = - 5000 & 0x00FF;
//TH0 = - 5000 >> 8;
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
int main(void) {
unsigned int W5500_Send_Delay_Counter =0;
int x = 0;
int i = 100;
char disp_buff[20];
//float temp;
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00; //P1 = 0xF0;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
MA = 0; MB = 0; //初始时电机停转
RELAY = 1; //初始时继电器断开
OLED_Init(); //初始化OLED
OLED_Clear();
// OLED_ShowCHinese(0,0,0);//中
// OLED_ShowCHinese(18,0,1);//景
// OLED_ShowCHinese(36,0,2);//园
OLED_ShowString(6,0,"0.91' EE-HELLO",16);
//OLED_ShowString(8,2,"ZHONGJINGYUAN");
// OLED_ShowString(20,4,"2014/05/01");
// OLED_DrawBMP(0,0,128,8,BMP1); //图片显示(图片显示慎用,生成的字表较大,会占用较多空间,FLASH空间8K以下慎用)
//while (1);
InitADC();
Load_Net_Parameters(); //装载网络参数
W5500_Hardware_Reset(); //硬件复位W5500
W5500_Initialization(); //W5500初始化
Timer0Init(); //T0初始化
IE = 0x82; //允许T0中断
TR0 = 1; //启动T0
while (1) {
W5500_Socket_Set(); //W5500端口初始化配置
W5500_Interrupt_Process(); //W5500中断处理程序框架
//如果Socket0接收到数据
if((S0_Data & S_RECEIVE) == S_RECEIVE) {
S0_Data &=~S_RECEIVE;
Process_Net_IO_Data(0); //W5500接收并发送接收到的数据
//这里可放显示语句
}
else if(W5500_Send_Delay_Counter >= 2000) {//定时发送字符串
if(S0_State == (S_INIT|S_CONN)) {
S0_Data &= ~S_TRANSMITOK;
//memcpy(Tx_Buffer, "\r\n欢迎使用E-HELLO模块板!\r\n", 25);
//Write_SOCK_Data_Buffer(0, Tx_Buffer, 25);//指定Socket(0~7)发送数据处理,端口0发送23字节数据
//--------------------------------------------
Tx_Buffer[0] = GetKeyStatus(); //放置4位按键状态
//--------------------------------------------
x = rand() % 1000;
Tx_Buffer[1] = x >> 8;
Tx_Buffer[2] = x & 0xFF;
sprintf(disp_buff,"Send=>PC:%4d",x);
OLED_ShowString(6,2,disp_buff,16);
//--------------------------------------------
//if (Read_Temperature())
{ //读取正常则显示
Tx_Buffer[3] = Temp_Value[0];
Tx_Buffer[4] = Temp_Value[1];
//计算温度浮点值
//temp = (int)(Temp_Value[1]<<8 | Temp_Value[0]) * 0.0625;
//sprintf(disp_buff,"TEMP:%4.1f",temp);
//OLED_ShowString(6,0,disp_buff,16);
}
//else
{
Tx_Buffer[3] = -1000>>8;
Tx_Buffer[4] = -1000;
}
//--------------------------------------------
Write_SOCK_Data_Buffer(0, Tx_Buffer, 5);//发送5字节
}
W5500_Send_Delay_Counter = 0;
}
W5500_Send_Delay_Counter++;
}
}
//-----------------------------------------------------------------
// T0中断函数(控制LED显示:滚动,闪烁,停止)
//-----------------------------------------------------------------
void LED_Control() interrupt 1 {
static u8 T_Count = 0, LED_M_Pattern = 0x40, LED_F_Pattern = 0xFF;
if ( ++T_Count == 10) { //累加形成5ms×10=50ms定时
if (LED_Control_Flag == 1) { //控制移动显示
P1 = (P1 & 0x8F) | LED_M_Pattern;
if ((LED_M_Pattern >>= 1) == 0x08) LED_M_Pattern = 0x40;
}
else if (LED_Control_Flag == 2) { //控制闪烁
LED_F_Pattern ^= 0x70; P1 = LED_F_Pattern;
}
else if (LED_Control_Flag == 0) { //停止显示
P1 &= ~0x70;
}
T_Count = 0;
}
} |