电路原理图如下:
STM32单片机源程序如下:
#include "main.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "OLED_NEW.H"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define LED0(a) if(a){HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);}
#define LED1(a) if(a){HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);}
#define BEEP(a) if(a){HAL_GPIO_WritePin(BEEP_GPIO_Port,BEEP_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(BEEP_GPIO_Port,BEEP_Pin,GPIO_PIN_RESET);}
#define Trig(a) if(a){HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET);}
#define IN1(a) if(a){HAL_GPIO_WritePin(IN1_GPIO_Port,IN1_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(IN1_GPIO_Port,IN1_Pin,GPIO_PIN_RESET);}
#define IN2(a) if(a){HAL_GPIO_WritePin(IN2_GPIO_Port,IN2_Pin,GPIO_PIN_SET);}\
else{HAL_GPIO_WritePin(IN2_GPIO_Port,IN2_Pin,GPIO_PIN_RESET);}
#define k1 HAL_GPIO_ReadPin(K1_GPIO_Port,K1_Pin)
#define k2 HAL_GPIO_ReadPin(K2_GPIO_Port,K2_Pin)
#define k3 HAL_GPIO_ReadPin(K3_GPIO_Port,K3_Pin)
#define level_Reservoir 145 //水库高度
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t key_bz,mode,ms_20,state,state_bz;
uint8_t value_set,value_H,value_L,uart_buf[2];
uint16_t value_level;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void key()//按键程序
{
if(k1==1 && k2==1 && k3==1){key_bz=1;}
if(k1==0 && key_bz==1)//K1按下,切换设置参数
{
key_bz=0;mode++;
if(mode>=4){mode=0;}
switch(mode)
{
case 0:
OLED_ShowChar(7*8,2,' ');
OLED_ShowChar(7*8,4,' ');
OLED_ShowChar(7*8,6,' ');
break;
case 1:
OLED_ShowChar(7*8,2,'*');
OLED_ShowChar(7*8,4,' ');
OLED_ShowChar(7*8,6,' ');
break;
case 2:
OLED_ShowChar(7*8,2,' ');
OLED_ShowChar(7*8,4,'*');
OLED_ShowChar(7*8,6,' ');
break;
case 3:
OLED_ShowChar(7*8,2,' ');
OLED_ShowChar(7*8,4,' ');
OLED_ShowChar(7*8,6,'*');
break;
}
}
if(k2==0 && key_bz==1)//K2按下,参数加
{
key_bz=0;
if(mode == 0)
{
mode=4;state_bz=1;
}
if(mode == 1)
{
value_set++;
if(value_set > 9){value_set=2;}
}
else if(mode == 2)
{
value_H++;
if(value_H > 9){value_H=2;}
}
else if(mode == 3)
{
value_L++;
if(value_L > 9){value_L=2;}
}
}
if(k3==0 && key_bz==1)//K3按下,参数减
{
key_bz=0;
if(mode == 1)
{
value_set--;
if(value_set >= 17){value_set=9;}
}
else if(mode == 2)
{
value_H--;
if(value_H >=17){value_H=9;}
}
else if(mode == 3)
{
value_L--;
if(value_L >= 17){value_L=9;}
}
}
}
void Control_Motor(uint8_t way)//控制水泵的方式
{
switch(way)
{
case 0://电机停止
IN1(0);IN2(0);
LED0(1);LED1(1);
break;
case 1://抽水
IN1(1);IN2(0);
LED0(0);LED1(1);
break;
case 2://补水
IN1(0);IN2(1);
LED0(1);LED1(0);
break;
}
}
void Uart_Send(uint8_t dat)//串口发送
{
HAL_UART_Transmit(&huart1,&dat,1,999);
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim1);
HAL_TIM_Base_Start_IT(&htim2);
HAL_UART_Receive_DMA(&huart1,uart_buf,2);
OLED_Init();
OLED_Clear();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
BEEP(0);
OLED_ShowCHinese(0,0,"水位");OLED_ShowChar(4*8,0,':');
OLED_ShowCHinese(0,2,"设置");OLED_ShowChar(4*8,2,':');
OLED_ShowCHinese(0,4,"上限");OLED_ShowChar(4*8,4,':');
OLED_ShowCHinese(0,6,"下限");OLED_ShowChar(4*8,6,':');
value_set=6;value_L=2;value_H=8;
while (1)
{
key();
Control_Motor(state);//0停止 1抽水 2补水
if(ms_20 == 1)
{
ms_20=0;
Trig(1);
HAL_Delay(1);
Trig(0);
}
OLED_ShowChar(5*8,0,value_level/100%10 + 0x30);
OLED_ShowChar(6*8,0,value_level/10%10 + 0x30);//显示液位
OLED_ShowChar(7*8,0,'.');
OLED_ShowChar(8*8,0,value_level%10 + 0x30);
Uart_Send(value_level/100%10 + 0x30);//串口发送液位值
Uart_Send(value_level/10%10 + 0x30);
Uart_Send(value_level%10 + 0x30);
Uart_Send('\r');
Uart_Send('\n');
if(value_level>=(value_H*10) || value_level<=(value_L*10)){BEEP(1);}
else{BEEP(0);}
OLED_ShowChar(5*8,2,value_set/10 + 0x30);//显示 设置 值
OLED_ShowChar(6*8,2,value_set%10 + 0x30);
OLED_ShowChar(5*8,4,value_H/10 + 0x30);//显示 设置 值
OLED_ShowChar(6*8,4,value_H%10 + 0x30);
OLED_ShowChar(5*8,6,value_L/10 + 0x30);//显示 设置 值
OLED_ShowChar(6*8,6,value_L%10 + 0x30);
if(mode == 4)
{
if(state_bz == 1)
{
if(value_level > (value_set*10)){state=2;state_bz=2;}//大于设置值,抽水
else if(value_level < (value_set*10)){state=1;state_bz=3;}//小于设置值补水
}
if(state_bz == 2)
{
if(value_level <= (value_set*10)){mode=0;state=0;}
}
if(state_bz == 3)
{
if(value_level >= (value_set*10)){mode=0;state=0;}
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//外部中断 中断回调函数
{
if(GPIO_Pin == GPIO_PIN_11)
{
TIM1->CNT = 0;
while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == 1);
value_level = TIM1->CNT*0.34/2;//计算液面与传感器距离
if(value_level <= value_level){value_level = level_Reservoir - value_level;}//计算液位距离
else{value_level = 0;}
}
}
uint16_t time;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器中断回调函数
{
if(htim == &htim2)
{
time++;
if(time >= 500){time=0;ms_20=1;}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口回调函数
{
if(uart_buf[0] == 'S'){value_set = uart_buf[1]-0x30;}
else if(uart_buf[0] == 'H'){value_H = uart_buf[1]-0x30;}
else if(uart_buf[0] == 'L'){value_L = uart_buf[1]-0x30;}
else if(uart_buf[0] == 'Z'){state_bz=1;mode=4;}
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
全部代码51hei附件下载:
KEIL5_LEVEL.7z
(2.96 MB, 下载次数: 38)
|