110VCGQ/project/revamp_addr/user/Src/user.c

322 lines
6.5 KiB
C
Raw Normal View History

2024-11-18 10:09:39 +08:00
/*
* user.c
*
* Created on: 20231027
* 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);
}
}
}