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