110VCGQ/project/revamp_addr/user/Src/user.c
2024-11-18 10:09:39 +08:00

322 lines
6.5 KiB
C
Raw 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.

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