275 lines
7.3 KiB
C
275 lines
7.3 KiB
C
#include "uart.h"
|
||
#include "addr.h"
|
||
#include "debug_printf.h"
|
||
#include "bl24c512.h"
|
||
#include "WaterMetermanager.h"
|
||
#include "Led.h"
|
||
#include "keywd.h"
|
||
#include "update.h"
|
||
#include "Flash.h"
|
||
#include "PHY.h"
|
||
#include "rtc_ext.h"
|
||
|
||
extern struct st_uart_port COM_485_port;
|
||
extern QueueSetHandle_t mPortsQueueSet;
|
||
extern QueueHandle_t WATERMETER485_Task;
|
||
extern void pro_645_97_read_addr(u8 *outBuf, u16 *outLen);
|
||
extern st_rtc_ext ERtctime;
|
||
extern u16 datacount_getcurcount();
|
||
extern void rp_setcount(u16 count);
|
||
extern void rp_start();
|
||
extern void datacount_add(u8 year,u8 month,u8 day,u8 hour);
|
||
extern void rp_current(u16 count,
|
||
u8 * current,
|
||
u8 * sumdata,u8 * surplus,u8 * ala,
|
||
u8 year,u8 month,u8 day,u8 hour);
|
||
|
||
extern void hb_waterdata_one_write(u16 index,u8 * sumdata,u8 year,u8 month,u8 day,u8 hour);
|
||
|
||
|
||
#define PRO_645_97_READADDR (1)
|
||
#define PRO_645_97_READDATA (2)
|
||
|
||
u8 send_485_buff[256];
|
||
u16 send_485_len = 0;
|
||
SemaphoreHandle_t sendto_485_semaphore;
|
||
|
||
static u8 pro_645_97_type = 0;
|
||
static u8 meter_addr[7] = {0};
|
||
|
||
void dl_485_initbuf(u8 * buf,u16 len)
|
||
{
|
||
memmove(send_485_buff,buf,len);
|
||
send_485_len = len;
|
||
}
|
||
|
||
void dl_485_start(u8 type,u8 *addr, u8 addrlen)
|
||
{
|
||
pro_645_97_type = type;
|
||
if(addr != NULL)
|
||
{
|
||
MemCpy(meter_addr,addr,addrlen);
|
||
}
|
||
xSemaphoreGive(sendto_485_semaphore);
|
||
}
|
||
|
||
void RS485_gpio_init(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
|
||
RCC_APB2PeriphClockCmd( RS485_CTRL_PORT_CLK | RS485_EXTIN_CLK | RS485_OVERLOAD_CLK , ENABLE);
|
||
|
||
GPIO_InitStructure.GPIO_Pin = RS485_CTRL_PIN;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_Init(RS485_CTRL_PIN_PORT, &GPIO_InitStructure);
|
||
close_RS485_switch();
|
||
|
||
GPIO_InitStructure.GPIO_Pin = RS485_EXTIN_PIN; //检测低电压
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||
GPIO_Init(RS485_EXTIN_PORT, &GPIO_InitStructure);
|
||
|
||
GPIO_InitStructure.GPIO_Pin = RS485_OVERLOAD_PIN; //检测低电压
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||
GPIO_Init(RS485_OVERLOAD_PORT, &GPIO_InitStructure);
|
||
|
||
hal_sRF_ITConfig(RS485_OVERLOAD_FLAG_LINE, DISABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = RS485_OVERLOAD_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
}
|
||
|
||
bool j645_ackPacket_analyse(u8 *inbuf, u16 len,u8 *out_datas)
|
||
{
|
||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||
//68 06 88 10 40 06 00 68 81 06 43 C3 33 48 33 33 22 16
|
||
|
||
if(inbuf[0] == 0x68 && inbuf[7] == 0x68 && inbuf[8] == 0x81)
|
||
{
|
||
if(inbuf[16] == GetSum(inbuf,16))
|
||
{
|
||
out_datas[0] = 0;
|
||
out_datas[1] = inbuf[15]-0x33;
|
||
out_datas[2] = inbuf[14]-0x33;
|
||
out_datas[3] = inbuf[13]-0x33;
|
||
out_datas[4] = inbuf[12]-0x33;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
bool read_meter_process(u8 meter_protcl)
|
||
{
|
||
ST_645_head * head_645_ptr = (ST_645_head *)NULL;
|
||
u8* WaterMeter485Data = NULL;
|
||
|
||
u16 count = 0;
|
||
u8 current_data[5];//当前流量
|
||
u8 sum_data[5];//累计流量
|
||
u8 surplus_data[6];//剩余流量
|
||
u8 ala_data[4];//报警
|
||
|
||
bool is_sumdata = false;
|
||
|
||
u16 send_length;
|
||
QueueSetMemberHandle_t rxPortMember;
|
||
|
||
|
||
MemSet(current_data,0,sizeof(current_data));
|
||
MemSet(sum_data,0,sizeof(sum_data));
|
||
MemSet(surplus_data,0,sizeof(surplus_data));
|
||
MemSet(ala_data,0,sizeof(ala_data));
|
||
|
||
|
||
RS485DataRequenstReady();
|
||
//vTaskDelay(500/portTICK_RATE_MS);
|
||
vTaskDelay(2000/portTICK_RATE_MS);
|
||
|
||
if(meter_protcl == PRO_645_97_READADDR)
|
||
{
|
||
pro_645_97_read_addr(COM_485_port.data.txBuf, &send_length);
|
||
}
|
||
|
||
send_length = create_queue_send_packet(COM_485_port.data.txBuf, send_length);
|
||
printf("[485] TX:");
|
||
printf_buf(COM_485_port.data.txBuf, send_length);
|
||
port_send(&COM_485_port, COM_485_port.data.txBuf, send_length);
|
||
|
||
if (xQueueReceive(WATERMETER485_Task, &WaterMeter485Data, pdMS_TO_TICKS(2000)) == pdTRUE)
|
||
{
|
||
rxPortMember = COM_485_port.xSemaphore;
|
||
}
|
||
else
|
||
{
|
||
printf("[485] timeover\r\n");
|
||
}
|
||
|
||
close_RS485_switch();
|
||
printf("[485] 12V close\r\n");
|
||
printf_buf(COM_485_port.data.rxBuf, COM_485_port.data.rx_len);
|
||
|
||
if (rxPortMember == COM_485_port.xSemaphore)
|
||
{
|
||
head_645_ptr = (ST_645_head *)search_645_packet(COM_485_port.data.rxBuf, COM_485_port.data.rx_len);
|
||
if(head_645_ptr != NULL)
|
||
{
|
||
printf("[485] head_645_ptr data anay\r\n");
|
||
if(j645_ackPacket_analyse((u8*)head_645_ptr,COM_485_port.data.rx_len,sum_data))
|
||
{
|
||
is_sumdata = true;
|
||
}
|
||
else
|
||
{
|
||
printf("[485] data error\r\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("[485] format error\r\n");
|
||
}
|
||
}
|
||
|
||
|
||
//如果抄表成功
|
||
if(is_sumdata)
|
||
{
|
||
//得到当前计数
|
||
count = datacount_getcurcount();
|
||
|
||
//保存当前数据
|
||
hb_waterdata_one_write(count,sum_data,ERtctime.year,ERtctime.month,ERtctime.day,ERtctime.hour);
|
||
|
||
//上报当前数据
|
||
rp_current(count,current_data,sum_data,surplus_data,ala_data,ERtctime.year,ERtctime.month,ERtctime.day,ERtctime.hour);
|
||
|
||
//计数增加
|
||
datacount_add(ERtctime.year,ERtctime.month,ERtctime.day,ERtctime.hour);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
|
||
处理485端口1 接收线程
|
||
*****************************************************************************/
|
||
void XYDX485Data_process_task(void *ptr)
|
||
{
|
||
WATERMETER485_Task = xQueueCreate( 1, sizeof( void* ) );
|
||
u32 WaterMeter485Data = (u32)&COM_485_port.data.rxBuf[0];
|
||
|
||
vTaskDelay( 500 / portTICK_RATE_MS );
|
||
|
||
for (;;)
|
||
{
|
||
//此处可改为等待PLC与485两种信号,对信号做同样处理,但是对于485做上行,需要统一下行接口在哪里
|
||
xSemaphoreTake(COM_485_port.xSemaphore, portMAX_DELAY);
|
||
|
||
printf("[485] RX:");
|
||
printf_buf(COM_485_port.data.rxBuf, COM_485_port.data.rx_len);
|
||
|
||
xQueueSendToBack( WATERMETER485_Task, &WaterMeter485Data, 10);
|
||
|
||
xQueueReset((QueueHandle_t)COM_485_port.xSemaphore);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
void send_to_485(void *ptr)
|
||
{
|
||
vSemaphoreCreateBinary(sendto_485_semaphore);
|
||
xSemaphoreTake(sendto_485_semaphore, 0);
|
||
|
||
for (;;)
|
||
{
|
||
xSemaphoreTake(sendto_485_semaphore, portMAX_DELAY);
|
||
if(0 == pro_645_97_type)
|
||
{
|
||
continue;
|
||
}
|
||
if(pro_645_97_type == PRO_645_97_READADDR)
|
||
{
|
||
read_meter_process(pro_645_97_type);
|
||
}
|
||
else if(pro_645_97_type == PRO_645_97_READDATA)
|
||
{
|
||
//MemCpy(MeterUnit.Addr.Address,meter_addr,ADDRESS_LENGTH-1);
|
||
//ret = ReadAddrListDataInfo( &MeterUnit , true);
|
||
}
|
||
pro_645_97_type = 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
|
||
//读地址
|
||
FE FE FE FE 68 99 99 99 99 99 99 68 01 02 43 C3 6F 16
|
||
68 06 88 10 40 06 00 68 81 06 43 C0 31 48 03 23 04 00 41 06 00 68 81 06 43 C3 33 C5 CC 33 B6 16
|
||
|
||
|
||
//读水表数据
|
||
FE FE FE FE 68 06 88 10 40 06 00 68 01 02 43 C3 BD 16
|
||
68 06 88 10 40 06 00 68 81 06 43 C3 33 48 33 33 22 16
|
||
水表数据是15
|
||
|
||
|
||
FE FE FE FE 68 99 99 99 99 99 99 68 01 02 43 C3 6F 16
|
||
FE FE FE 68 59 23 39 09 21 20 68 81 06 43 C3 33 34 33 33 29 16
|
||
*/
|
||
|