322 lines
6.5 KiB
C
322 lines
6.5 KiB
C
|
/*
|
|||
|
* user.c
|
|||
|
*
|
|||
|
* Created on: 2023年10月27日
|
|||
|
* Author: wyf
|
|||
|
*/
|
|||
|
|
|||
|
#include "user.h"
|
|||
|
|
|||
|
|
|||
|
uint8_t uart1_count = 0; //串口1接收数据个数
|
|||
|
uint8_t uart1_RxBuff[UART_BUFF_LEN] = {0}; //串口1接收缓冲区
|
|||
|
uint8_t uart1_TXBuff[UART_BUFF_LEN] = {0}; //串口1发送缓冲区
|
|||
|
uint8_t uart1_uBuff[UART_BUFF_LEN] = {0}; //串口1用户缓冲区
|
|||
|
|
|||
|
uint16_t RegularConvData_Tab[10] = {0};
|
|||
|
uint8_t vlotage =0; //电压
|
|||
|
uint8_t voltage_class=0; //电压等级
|
|||
|
BELL_STATE bell_state = {0};
|
|||
|
|
|||
|
uint8_t current_addr = 1; //要修改的地址
|
|||
|
uint8_t last_send =99; //上一次修改的值
|
|||
|
|
|||
|
|
|||
|
void user_init(void)
|
|||
|
{
|
|||
|
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
|
|||
|
__HAL_UART_CLEAR_IT(&huart1,UART_CLEAR_IDLEF|UART_CLEAR_TCF);
|
|||
|
bsp_InitTimer();
|
|||
|
HAL_GPIO_WritePin(TX485_EN_GPIO_Port, TX485_EN_Pin, GPIO_PIN_RESET);//使能485芯片接收
|
|||
|
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)RegularConvData_Tab, 10); //开启ADC转换
|
|||
|
|
|||
|
HAL_Delay(600);
|
|||
|
|
|||
|
HAL_ADC_Stop_DMA(&hadc1); //算电压
|
|||
|
// uint16_t temp =0;
|
|||
|
// for(uint8_t i=0; i<10;i++)
|
|||
|
// {
|
|||
|
// temp+=RegularConvData_Tab[i];
|
|||
|
// }
|
|||
|
// temp = temp/10*3300/4095;
|
|||
|
// OLED_ShowNum(1, 0, temp, 4, 16);
|
|||
|
|
|||
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|||
|
GPIO_InitStruct.Pin = KEY_PWR_Pin;
|
|||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
|||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|||
|
HAL_GPIO_Init(KEY_PWR_GPIO_Port, &GPIO_InitStruct);
|
|||
|
Init_Key();
|
|||
|
bsp_ClearKey();
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void bsp_RunPer10ms(void)
|
|||
|
{
|
|||
|
bsp_KeyScan10ms();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void oled_show(void)
|
|||
|
{
|
|||
|
|
|||
|
uint8_t count =0,x = 50;
|
|||
|
if(current_addr <10)
|
|||
|
{
|
|||
|
count = 1;
|
|||
|
x = 50;
|
|||
|
}
|
|||
|
else if(current_addr <100)
|
|||
|
{
|
|||
|
count =2;
|
|||
|
x = 40;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
count =3;
|
|||
|
x = 30;
|
|||
|
}
|
|||
|
// OLED_Clear();
|
|||
|
for(uint8_t i=2;i<8;i++)
|
|||
|
{
|
|||
|
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
|
|||
|
OLED_WR_Byte (0x02,OLED_CMD); //设置显示位置—列低地址
|
|||
|
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
|
|||
|
for(uint8_t n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
|
|||
|
} //更新显示
|
|||
|
|
|||
|
OLED_ShowNum(x, 1, current_addr, count, 48);
|
|||
|
oled_voltage(voltage_class);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//发送指令
|
|||
|
void send_addr(uint8_t addr)
|
|||
|
{
|
|||
|
uint8_t data[8] ={0},num = 0;
|
|||
|
uint16_t crc =0;
|
|||
|
if(addr != 0) //发送修改地址命令
|
|||
|
{
|
|||
|
data[num++] = 1; //485地址
|
|||
|
data[num++] = 0x06; //功能位
|
|||
|
data[num++] = 0; //寄存器高位
|
|||
|
data[num++] = 0x0F; //寄存器低位
|
|||
|
data[num++] = 0; //要设置数据的高位
|
|||
|
data[num++] = addr; //要设置数据的低位
|
|||
|
|
|||
|
}
|
|||
|
else { //发送地址复位命令
|
|||
|
data[num++] = 0; //485地址
|
|||
|
data[num++] = 0x06; //功能位
|
|||
|
data[num++] = 0; //寄存器高位
|
|||
|
data[num++] = 0x0F; //寄存器低位
|
|||
|
data[num++] = 0; //要设置数据的高位
|
|||
|
data[num++] = 1; //要设置数据的低位
|
|||
|
}
|
|||
|
crc =crc16_modbus(data, 6);
|
|||
|
data[num++] = crc&0x00FF;
|
|||
|
data[num++] = crc>>8;
|
|||
|
|
|||
|
HAL_GPIO_WritePin(TX485_EN_GPIO_Port, TX485_EN_Pin, GPIO_PIN_SET);//使能485芯片发送
|
|||
|
HAL_UART_Transmit_DMA(&huart1, data, 8);
|
|||
|
while(HAL_DMA_GetState(&hdma_usart1_tx) != HAL_DMA_STATE_READY);
|
|||
|
// while( __HAL_UART_GET_FLAG(&huart1,UART_FLAG_TXE) != SET );
|
|||
|
// while(HAL_UART_GetState(&huart1) != HAL_UART_STATE_BUSY_TX);
|
|||
|
HAL_Delay(3);
|
|||
|
HAL_GPIO_WritePin(TX485_EN_GPIO_Port, TX485_EN_Pin, GPIO_PIN_RESET);//使能485芯片接收
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//CRC校验
|
|||
|
uint16_t crc16_modbus(uint8_t *data, uint16_t length)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
uint16_t crc = 0xffff; // Initial value
|
|||
|
while(length--)
|
|||
|
{
|
|||
|
crc ^= *data++; // crc ^= *data; data++;
|
|||
|
for (i = 0; i < 8; ++i)
|
|||
|
{
|
|||
|
if (crc & 1)
|
|||
|
crc = (crc >> 1) ^ 0xA001; // 0xA001 = reverse 0x8005
|
|||
|
else
|
|||
|
crc = (crc >> 1);
|
|||
|
}
|
|||
|
}
|
|||
|
return crc;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//按键处理
|
|||
|
void key_slave(void)
|
|||
|
{
|
|||
|
static uint8_t flag =0;
|
|||
|
uint8_t key_code;
|
|||
|
key_code = bsp_GetKey();
|
|||
|
if(key_code != KEY_NONE)bsp_StartTimer(3, 300000); //更新关机时间
|
|||
|
switch(key_code)
|
|||
|
{
|
|||
|
case KEY_UP_DOWN: //编码器按键
|
|||
|
current_addr++;
|
|||
|
if(current_addr ==0)current_addr++;
|
|||
|
oled_show();
|
|||
|
break;
|
|||
|
|
|||
|
case KEY_UP_LONG: //编码器按键
|
|||
|
current_addr++;
|
|||
|
if(current_addr ==0)current_addr++;
|
|||
|
oled_show();
|
|||
|
break;
|
|||
|
|
|||
|
case KEY_DOWN_DOWN:
|
|||
|
current_addr--;
|
|||
|
if(current_addr ==0)current_addr--;
|
|||
|
oled_show();
|
|||
|
break;
|
|||
|
|
|||
|
case KEY_DOWN_LONG:
|
|||
|
current_addr--;
|
|||
|
if(current_addr ==0)current_addr--;
|
|||
|
oled_show();
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
case KEY_OK_DOWN:
|
|||
|
RLED_OFF();
|
|||
|
BLED_OFF();
|
|||
|
bsp_StartTimer(0, 1000);
|
|||
|
|
|||
|
send_addr(0);
|
|||
|
HAL_Delay(300);
|
|||
|
send_addr(current_addr);
|
|||
|
last_send =current_addr;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case KEY_RESET_DOWN:
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case KEY_PWR_DOWN:
|
|||
|
|
|||
|
if(flag == 0) //开机
|
|||
|
{
|
|||
|
uint16_t temp =0;
|
|||
|
for(uint8_t i=0; i<10;i++)
|
|||
|
{
|
|||
|
temp+=RegularConvData_Tab[i];
|
|||
|
}
|
|||
|
|
|||
|
temp = temp/10*3300/4095*6/5;
|
|||
|
|
|||
|
if(temp>= 3950)
|
|||
|
{
|
|||
|
voltage_class = 5;
|
|||
|
}
|
|||
|
else if(temp>= 3920)
|
|||
|
{
|
|||
|
voltage_class = 4;
|
|||
|
}
|
|||
|
else if(temp >= 3870)
|
|||
|
{
|
|||
|
voltage_class = 3;
|
|||
|
}
|
|||
|
else if(temp >= 3790)
|
|||
|
{
|
|||
|
voltage_class = 2;
|
|||
|
}
|
|||
|
else if(temp >= 3680)
|
|||
|
{
|
|||
|
voltage_class = 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
voltage_class =0;
|
|||
|
}
|
|||
|
|
|||
|
PWR_ON();
|
|||
|
OLED_Init(); //初始化OLED
|
|||
|
OLED_Clear();
|
|||
|
oled_show();
|
|||
|
// OLED_ShowNum(1, 0, temp, 4, 16);
|
|||
|
BLED_ON();
|
|||
|
BELL_ON();
|
|||
|
bsp_StartTimer(1, 100);
|
|||
|
|
|||
|
flag++;
|
|||
|
}
|
|||
|
//关机
|
|||
|
else {
|
|||
|
OLED_Clear();
|
|||
|
PWR_OFF();
|
|||
|
BLED_OFF();
|
|||
|
RLED_OFF();
|
|||
|
BELL_ON();
|
|||
|
bsp_StartTimer(1, 100);
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
default:break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void uart_slave(void)
|
|||
|
{
|
|||
|
if(uart1_count==8 && uart1_uBuff[5] == last_send)
|
|||
|
{
|
|||
|
|
|||
|
bell_state.num = 1;
|
|||
|
bell_state.continue_time = 200;
|
|||
|
bell_state.interval_tine = 300;
|
|||
|
BLED_ON();
|
|||
|
RLED_OFF();
|
|||
|
|
|||
|
bsp_StartTimer(2, bell_state.interval_tine);
|
|||
|
BELL_ON();
|
|||
|
bsp_StartTimer(1, bell_state.continue_time);
|
|||
|
|
|||
|
bsp_StopTimer(0);
|
|||
|
}
|
|||
|
|
|||
|
uart1_count = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//根据电压等级显示电量
|
|||
|
void oled_voltage(uint8_t voltage_class)
|
|||
|
{
|
|||
|
uint8_t b[2][28] =
|
|||
|
{{0xFF,0xFF,0xFF,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
|
|||
|
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0xFF,0xFF,0xE0,0xE0},
|
|||
|
{0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
|
|||
|
0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xFF,0xFF,0x07,0x07}};/*"未命名文件",0*//*"未命名文件",0*/
|
|||
|
|
|||
|
for(uint8_t i=1;i<=voltage_class;i++)
|
|||
|
{
|
|||
|
b[0][i*4] =b[0][i*4]|0xf0;
|
|||
|
b[0][i*4+1] =b[0][i*4+1]|0xf0;
|
|||
|
b[0][i*4+2] =b[0][i*4+2]|0xf0;
|
|||
|
|
|||
|
b[1][i*4] =b[1][i*4]|0x0f;
|
|||
|
b[1][i*4+1] =b[1][i*4+1]|0x0f;
|
|||
|
b[1][i*4+2] =b[1][i*4+2]|0x0f;
|
|||
|
}
|
|||
|
|
|||
|
for(uint8_t j=0;j<2;j++)
|
|||
|
{
|
|||
|
OLED_Set_Pos(2,j);
|
|||
|
for(uint8_t i=0;i<28;i++)
|
|||
|
{
|
|||
|
OLED_WR_Byte(b[j][i],OLED_DATA);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|