直接上代码首先是所有变量加LCD任务和ADC读取
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "key.h"
#include "led.h"
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO uint32_t keyTick; //按键扫描时间
__IO uint32_t adcTick; //adc扫描时间
__IO uint32_t uartTick; //串口扫面时间
u8 Lcdpage; //界面序号
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
u8 Vmax = 30,Vmin=10; //lcd显示的电压最大最小值
u8 Vmax_com = 30,Vmin_com = 10; //B1返回主界面时进行逻辑判断的变量
u8 Vmax_uart; u8 Vmin_uart; //串口命令是否合理变量判断
u16 Time,sec; //电压计时
u8 led_ctrl; //led灯点亮
_Bool rx_cnt_flag = 0; //串口命令是否正确
_Bool timeflag; //D1灯标志位
_Bool keyflag; //D2灯标志位
_Bool uartflag; //D3灯标志位
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
u16 adc2_value,adc_num; //adc2_value读取值,adc__num为均值滤波
u8 adc_cnt; //adc采集的数量
float v37,V15_value; //v37是当前时刻电位,V15_value为上一时刻电位
u8 uart_buf[2]; //串口发送,重定向
u8 rx_buf[10]; //串口接收数组
u8 rx_cnt; //串口接收几个数
/* USER CODE END PM */
void LCD_Process()
{
u8 text[30];
if(!Lcdpage) //主界面
{
LCD_SetTextColor(White);
sprintf((char*)text," Data");
LCD_DisplayStringLine(Line1,text);
sprintf((char*)text," V:%0.2fv",v37);
LCD_DisplayStringLine(Line3,text);
sprintf((char*)text," T:%ds",sec);
LCD_DisplayStringLine(Line4,text);
}
if(Lcdpage==1) //参数界面
{
LCD_SetTextColor(White);
sprintf((char*)text," Para");
LCD_DisplayStringLine(Line1,text);
sprintf((char*)text," V:%0.1fV",Vmax/10.0f);
LCD_DisplayStringLine(Line3,text);
sprintf((char*)text," T:%0.1fV",Vmin/10.0f);
LCD_DisplayStringLine(Line4,text);
}
}
//2.adc的采集
void ADC_Process()
{
HAL_ADC_Start(&hadc2); //开启adc2
adc2_value = HAL_ADC_GetValue(&hadc2); //获取adc2值
adc_num = adc_num+adc2_value; //采集5次adc值的总和
adc_cnt++;
if(adc_cnt == 5) //把5次的值进行均算
{
V15_value = v37;
v37 = (adc_num/5.0f) / 4095.0f* 3.3f;
adc_num = 0;
adc_cnt = 0;
}
}
随后加按键的任务
//3.按键任务
void KEY_Process()
{
//10ms扫描一次
if(uwTick - keyTick<10) return;
keyTick = uwTick;
Key_Read();
//KB1按下
if(Trg & 0x01)
{
LCD_Clear(Black);//刷新界面
Lcdpage =(Lcdpage+1)%2;
if(!Lcdpage) //逻辑判断,数值是否合理,主界面生效
{
if(Vmax>=(Vmin+10))
{
keyflag = 0;
Vmax_com = Vmax;
Vmin_com = Vmin;
}
else
{
keyflag = 1; //不合理则D2的标志位打开,D2亮
Vmax = Vmax_com;
Vmin = Vmin_com;
}
}
}
//KB2
if(Trg & 0x02)
{
if(Lcdpage)
{
if(Vmax<33)
Vmax+=1;
else
Vmax = 0;
}
}
//KB3
if(Trg & 0x04)
{
if(Lcdpage)
{
if(Vmin<33)
Vmin+=1;
else
Vmin = 0;
}
}
}
随后是计时adc读取的时间,注意函数
void SysTick_Handler(void),我从stm32g4xx_it.c文件中剪切到了main.c文件
//5.adc计时时间
void ADC_Time()
{
//从小往大,穿过最小值
if((V15_value<=(Vmin/10.0f))&&(v37>=(Vmin/10.0f)))
{
sec = 0;
timeflag=1; //开始计时
}
//从小往大,穿过最大值
if((V15_value<=(Vmax/10.0f))&&(v37>=(Vmax/10.0f)))
{
timeflag=0;
}
//注释处为增加任务合理性
// if((V15_value<=(Vmin/10.0f))&&(v37<=(Vmin/10.0f)))
// {
// sec = 0;
// timeflag=0;
// }
}
//6.SysTick中断任务,1ms执行一次,用于adc计时
void SysTick_Handler(void)
{
HAL_IncTick();
if(timeflag==1)
{
//1ms执行一次
Time++;
if(Time ==1000)
{
//1s后sec自加
Time=0;
sec++;
}
}
}
再是串口任务,这次串口不用重定向,不过我还是建议各位都写写
//7.50ms定时清除串口接收数组
void RxIde_Process(void)
{
//50ms执行
if(uwTick - uartTick<50) return;
uartTick = uwTick;
//如果串口有数据并且不到7个
if((rx_cnt>0) &&(rx_cnt_flag==0))
{
uartflag = 1; //D3灯亮
printf("input error\r\n");
}
rx_cnt_flag = 0; //串口是否接收7个数据标志位
rx_cnt = 0; //串口接收数量
memset(rx_buf,'\0',sizeof(rx_buf)); //清空rx__buf数组
//8.检查串口发送数据的正确性
_Bool Check_String(u8 *str)
{
//判断每一位的数据,不对返回0,正确返回1
if((str[1] !='.') || (str[3] != ',')|| (str[5] !='.'))
return 0;
if((str[0] < '0') || (str[0]>'9'))
return 0;
if((str[2] < '0') || (str[2]>'9'))
return 0;
if((str[4] < '0') || (str[4]>'9'))
return 0;
if((str[6] < '0') || (str[6]>'9'))
return 0;
return 1;
}
}
//9.串口接收回调函数执行的任务
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uartTick = uwTick; //每执行一次回调函数重新计时50ms
rx_buf[rx_cnt++] = uart_buf[0];
HAL_UART_Receive_IT(&huart1,uart_buf,1); //开启串口接收中断
if(rx_cnt == 7) //接收7个数据
{
rx_cnt_flag = 1;
if(Check_String(rx_buf) == 0) //检查数据合理性,不合理打印错误
{
printf("input error\r\n");
}
if(Check_String(rx_buf) == 1)//检查数据合理性,合理改变电位极限值
{
Vmax_uart = (rx_buf[0] - '0')*10 + rx_buf[2] - '0';
Vmin_uart = (rx_buf[4] - '0')*10 + rx_buf[6] - '0';
//判断串口的数据电位是否合理
if(Vmax_uart>=(Vmin_uart+10) && (Vmax_uart<33)&& (Vmin_uart<33))
{
uartflag = 0;
Vmax = Vmax_uart;
Vmin = Vmin_uart;
}
else
{
uartflag = 1;
Vmax_uart = Vmax;
Vmin_uart = Vmin;
}
}
rx_cnt =0;
}
}
//4.led任务
void LED_Process()
{
if(timeflag) //D1的亮灭
led_ctrl |= 0x01;
else
led_ctrl &= ~0x01;
if(keyflag)
led_ctrl |= 0x02; //D2的亮灭
else
led_ctrl &= ~0x02;
if(uartflag)
led_ctrl |= 0x04; //D3的亮灭
else
led_ctrl &= ~0x04;
LED_Control(led_ctrl);
}
主函数调用任务函数即可
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LCD_Process();
LED_Process();
ADC_Process();
KEY_Process();
ADC_Time();
RxIde_Process();
}
最后欢迎各位指正错误