ShipCentralControl/Anjiehui7_DTU/User/uart_Ethernet.c

288 lines
6.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* IAR Development Kits
* on the
*
* M451
*
* Filename : uart_Ethernet.h
* Version : V1.00
* Programmer(s) : Qian Xianghong
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <includes.h>
// ETHERNET串口接收的循环缓冲
#define ETHERNET_DATA_COUNT 200
loopbuff_t Ethernet_Buff;
uint8_t Ethernet_Buff_Data[sizeof(uint8_t) * (ETHERNET_DATA_COUNT + 1)] = {0};
// ETHERNET串口接收的消息通知
SemaphoreHandle_t Ethernet_semQ = NULL;
// ETHERNET串口AT命令接收的循环缓冲
#define ETHERNET_ATDATA_COUNT 50
loopbuff_t Ethernet_ATBuff;
uint8_t Ethernet_ATBuff_Data[sizeof(uint8_t) * (ETHERNET_ATDATA_COUNT + 1)] = {0};
// 网口初始化状态
uint8_t Ethernet_initStatus = 0, Ethernet_connected = 0;
static void Ethernet_IRQHandler(USART_Handle *huart)
{
BaseType_t xHigherPriorityTaskWoken;
uint8_t c = (uint8_t) huart->Instance->DR;
// 加入缓冲
LoopBuff_PutItem(&Ethernet_Buff, &c);
// 发消息给任务
xSemaphoreGiveFromISR(Ethernet_semQ, &xHigherPriorityTaskWoken);
}
static void Ethernet_ATHandler(USART_Handle *huart)
{
uint8_t c = (uint8_t) huart->Instance->DR;
// 加入缓冲
LoopBuff_PutItem(&Ethernet_ATBuff, &c);
}
void Ethernet_Send(char *buf)
{
UART_Transmit(&huart3, (uint8_t *) buf, strlen(buf));
}
// 非中断方式,直接从串口接收数据
uint16_t Ethernet_Recv(char *buf, uint16_t wait_cnt)
{
uint16_t recv_cnt = 0;
uint32_t stop_seconds;
char c;
stop_seconds = rf_get_seconds() + 2;
while(rf_get_seconds() < stop_seconds)
{
if(LoopBuff_GetCount(&Ethernet_ATBuff) > 0)
{
c = *(uint8_t *) LoopBuff_GetDataPtr(&Ethernet_ATBuff, Ethernet_ATBuff.info.rdPtr);
LoopBuff_RemoveItems(&Ethernet_ATBuff, 1);
printf("%c", c);
if(c != '\r' && c != '\n')
{
buf[recv_cnt++] = c;
if(recv_cnt == wait_cnt)
break;
}
}
}
return recv_cnt;
}
// 进入AT命令模式
uint8_t Ethernet_ATMode()
{
uint8_t try_cnt;
char buf[3] = {0};
// 进入AT命令模式
for(try_cnt = 0; try_cnt < 3; try_cnt++)
{
// 先进入AT命令模式
delay_ms(100);
Ethernet_Send("+++");
if(Ethernet_Recv(buf, 1) < 1 || buf[0] != 'a')
continue;
Ethernet_Send("a");
if(Ethernet_Recv(buf, 3) < 3 || strncmp(buf, "+ok", 3) != 0)
continue;
// 成功进入AT命令模式
delay_ms(100);
return 1;
}
return 0;
}
uint8_t Ethernet_ATCmd(char *cmd, char *ok_str, char *err_str)
{
char buf[21], c;
uint8_t try_cnt;
uint16_t recv_cnt = 0;
uint32_t stop_seconds;
memset(buf, 0, sizeof(buf));
for(try_cnt = 0; try_cnt < 3; try_cnt++)
{
// 清空串口缓冲区
LoopBuff_Clear(&Ethernet_ATBuff);
// 发送命令
Ethernet_Send(cmd);
Ethernet_Send("\r");
// 等待返回数据
stop_seconds = rf_get_seconds() + 2;
while(rf_get_seconds() < stop_seconds)
{
if(LoopBuff_GetCount(&Ethernet_ATBuff) > 0)
{
c = *(uint8_t *) LoopBuff_GetDataPtr(&Ethernet_ATBuff, Ethernet_ATBuff.info.rdPtr);
LoopBuff_RemoveItems(&Ethernet_ATBuff, 1);
printf("%c", c);
if(c != '\r' && c != '\n')
{
buf[recv_cnt++] = c;
if(strstr(buf, ok_str) != NULL)
return 1;
if(strstr(buf, err_str) != NULL)
return 0;
}
}
}
}
return 0;
}
void Ethernet_Open()
{
// 创建消息队列
LoopBuff_Create(&Ethernet_Buff, sizeof(uint8_t), ETHERNET_DATA_COUNT, 0, (uint32_t) Ethernet_Buff_Data);
LoopBuff_Create(&Ethernet_ATBuff, sizeof(uint8_t), ETHERNET_ATDATA_COUNT, 0, (uint32_t) Ethernet_ATBuff_Data);
// 创建信号量
Ethernet_semQ = xSemaphoreCreateBinary();
SET_BIT(USART3->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
LL_USART_Enable(USART3);
}
// 本函数要用到中断,只能在任务启动以后执行
void Ethernet_Config()
{
huart3.RxISR = Ethernet_ATHandler;
delay_ms(100);
VCC_ETHERNET_ON();
delay_ms(1000);
// 设置状态
Ethernet_initStatus = 0;
Ethernet_connected = 0;
// 设置Usr_K3工作方式
#if 1
// 进入AT命令模式
if(!Ethernet_ATMode())
return;
// 设置命令不回显
if(!Ethernet_ATCmd("AT+E=OFF", "+OK", "+ERR"))
return;
// 设置DHCP
if(!Ethernet_ATCmd("AT+WANN=DHCP", "+OK", "+ERR"))
// if(!Ethernet_ATCmd("AT+WANN=STATIC,192.168.0.3,255.255.255.0,192.168.0.1", "+OK", "+ERR"))
return;
// 设置DNS如DHCP配置可不设DNS)
// if(!Ethernet_ATCmd("AT+DNS=202.106.0.20", "+OK", "+ERR"))
// return;
// 设置TCP模式、服务器、端口
if(RF_APP == RF_APP_AJH)
{
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,171.88.5.52,8061", "+OK", "+ERR")) // 公司路由器
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,extra.cd-ls.cn,8061", "+OK", "+ERR"))
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,121.89.205.240,41001", "+OK", "+ERR"))
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,data.ajhiot.com,8088", "+OK", "+ERR"))
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,114.55.209.85,8088", "+OK", "+ERR")) // data.ajhiot.com
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,192.168.0.2,8061", "+OK", "+ERR")) // 直连电脑
return;
}
else if(RF_APP == RF_APP_PRAX)
{
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,tts.praxair.com.cn,7005", "+OK", "+ERR"))
return;
}
else
{
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,data.cd-ls.cn,8088", "+OK", "+ERR"))
return;
}
// 关闭串口心跳包
if(!Ethernet_ATCmd("AT+HEARTEN1=OFF", "+OK", "+ERR"))
return;
// 关闭串口注册包
if(!Ethernet_ATCmd("AT+REGEN1=OFF", "+OK", "+ERR"))
return;
// 关闭短连接功能
if(!Ethernet_ATCmd("AT+SOCKSL1=OFF", "+OK", "+ERR"))
return;
// 设置超时重启时间60秒
if(!Ethernet_ATCmd("AT+RSTIM=60", "+OK", "+ERR"))
return;
// 连接前是否清理串口缓存?
if(!Ethernet_ATCmd("AT+UARTCLBUF=ON", "+OK", "+ERR"))
return;
// 设为默认参数
if(!Ethernet_ATCmd("AT+CFGTF", "saved", "+ERR"))
return;
// 重启模块
if(!Ethernet_ATCmd("AT+Z", "OK", "+ERR"))
return;
#endif
/* Enable UART3 interrupt */
huart3.RxISR = Ethernet_IRQHandler;
// 设置状态
Ethernet_initStatus = 1;
}
// 检查服务器连接情况
uint8_t Ethernet_IsConnected()
{
u8 try_count;
u8 atMode = 0, connected = 0, tranMode = 0;
huart3.RxISR = Ethernet_ATHandler;
// 清除串口缓冲数据
LoopBuff_Clear(&Ethernet_ATBuff);
// 进入AT命令模式3次不成功则复位
for(try_count = 0; try_count < 3; try_count++)
{
if(Ethernet_ATMode())
{
atMode = 1;
break;
}
osDelay(500);
}
if(atMode)
{
// 检查是否连上网络
connected = Ethernet_ATCmd("AT+SOCKLKA1", "+OK=CONNECTED", "+OK=CONNECTING");
// 进入透传模式3次不成功则复位
for(try_count = 0; try_count < 3; try_count++)
{
if(Ethernet_ATCmd("AT+ENTM", "+OK", "+ERR"))
{
tranMode = 1;
break;
}
osDelay(500);
}
}
huart3.RxISR = Ethernet_IRQHandler;
return (atMode && connected && tranMode);
}