Files
2025-12-15 16:07:49 +08:00

275 lines
7.3 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.
#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
*/