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);
|
||
}
|
||
}
|
||
}
|
||
|