```c
/*赛题:第七届:模拟液位检测告警系统”
**作者:*wj
**时间:2021-2-13
**注意:设备通过串口发送给PC,思路和LCD动态显示一样(记得添加"stdio.h")
*/
**第一部分:逻辑功能实现**
- #include "stm32f10x.h"
- #include "lcd.h"
- #include "led.h"
- #include "key.h"
- #include "i2c.h"
- #include "stdio.h"
- #include "usart.h"
- #include "adc.h"
- u32 TimingDelay = 0;
- u8 text1[20]; //字符串数组1
- u8 text2[20]; //字符串数组2
- u8 RXBUF[20]; //串口接收数组
- u8 TXBUF[20]; //串口发送数组
- u8 RXOVER = 0; //串口接收标志0:没有接收 1:接收
- u8 RXCOUNT = 0; //串口数组计数变量
- u8 ADC_Flag =1; //ADC以1s间隔采集变量 1:采集(初始化为1,是让上电之后就进行一次电压采集)
- u8 K1_FLAG = 0; //B1 按键: “设置”按键 0:液位检测界面 1://阈值设置界面
- u8 K2_FLAG = 0; //B2 按键:切换选择 3 个待修改的阈值,被选中的阈值应突出显示
- u8 LED1_on = 0; //控制LED1开变量
- u8 LED1_off = 0; //控制LED1关变量
- u8 Threshold_1 = 30; //液位范围1
- u8 Threshold_2 = 50; //液位范围2
- u8 Threshold_3 = 70; //液位范围3
- u8 Level_old = 0; //上一次的水平值
- u8 Level_now= 0; //新的水平值
- u8 Height = 0; //液面高度变量
- float ADC_Value; //ADC采集的值(浮点型)
- u8 i = 0; //循环变量
- u8 j = 0; //循环变量
- u8 k = 0; //循环变量
- /************************函数引用**************************************/
- void Delay_Ms(u32 nTime);
- void RCC_Configuration(void);
- void LCD_Init(void);
- void KEY_Scan(void);
- void _24c02_Write(u16 addr, u16 data);
- u16 _24c02_Read(u16 addr);
- void LCD_Display(void);
- void Deal_Data(void);
- void LED_Blink(void);
- /************************Main Body函数**************************************/
- int main(void)
- {
- i2c_init(); //IIC初始化
- LCD_Init(); //LCD初始化
- RCC_Configuration(); //所有外设时钟配置
- LED_Configuration(); //LED配置
- KEY_Configuration(); //KEY配置
- USART2_Configuration(); //串口通信2配置
- ADC_Configuration(); //ADC配置
- while(1)
- {
- KEY_Scan(); //按键扫描函数
- Deal_Data(); //数据处理比较函数
- LCD_Display(); //LCD显示函数
- LED_Blink(); //LED闪烁配置函数
- }
- }
- /************************LCD_Init初始化函数**************************************/
- void LCD_Init(void)
- {
- STM3210B_LCD_Init();
- LCD_Clear(Blue);
- LCD_SetBackColor(Blue);
- LCD_SetTextColor(White);
- SysTick_Config(SystemCoreClock/1000);
- //第一次给EEPROM写入数据
- // _24c02_Write(0x01,30);
- // Delay_Ms(10);
- // _24c02_Write(0x02,50);
- // Delay_Ms(10);
- // _24c02_Write(0x03,70);
- // Delay_Ms(10);
- //上电之后读取之前存储的数据
- Threshold_1 = _24c02_Read(0x01);
- Delay_Ms(10);
- Threshold_2 = _24c02_Read(0x02);
- Delay_Ms(10);
- Threshold_3 = _24c02_Read(0x03);
- }
- /************************LCD_Display显示函数**************************************/
- void LCD_Display(void)
- {
- if(K1_FLAG == 0) // 液位检测界面
- {
- LCD_DisplayStringLine(Line2 ," Liquid Level ");
- sprintf((char*)text1," Height: %dcm ",Height);
- LCD_DisplayStringLine(Line4,text1);
- if(ADC_Flag == 1)
- {
- ADC_Flag =0;
- ADC_Value = Get_ADC(8) * 3.3 /0xfff;
- sprintf((char*)text2," ADC_VAL: %.2fV ",ADC_Value); //保留俩位小数:.2f
- LCD_DisplayStringLine(Line6,text2);
- }
- sprintf((char*)text1," Level: %d ",Level_now);
- LCD_DisplayStringLine(Line8,text1);
- _24c02_Write(0x01,Threshold_1);
- Delay_Ms(10);
- _24c02_Write(0x02,Threshold_2);
- Delay_Ms(10);
- _24c02_Write(0x03,Threshold_3);
- Delay_Ms(10);
- }
- else if(K1_FLAG == 1) //阈值设置界面
- {
- LCD_SetBackColor(Blue); //第一行一直显示蓝色
- LCD_DisplayStringLine(Line2 ," Parameter Setup ");
- if(K2_FLAG == 1)
- {
- LCD_SetBackColor(Red); //选中高亮显示
- sprintf((char*)text1," Threshold 1: %dcm ",Threshold_1);
- LCD_DisplayStringLine(Line4,text1);
- }
- else
- {
- LCD_SetBackColor(Blue);
- sprintf((char*)text1," Threshold 1: %dcm ",Threshold_1);
- LCD_DisplayStringLine(Line4,text1);
- }
- if(K2_FLAG == 2)
- {
- LCD_SetBackColor(Red);
- sprintf((char*)text1," Threshold 2: %dcm ",Threshold_2);
- LCD_DisplayStringLine(Line5,text1);
- }
- else
- {
- LCD_SetBackColor(Blue);
- sprintf((char*)text1," Threshold 2: %dcm ",Threshold_2);
- LCD_DisplayStringLine(Line5,text1);
- }
- if(K2_FLAG == 3)
- {
- LCD_SetBackColor(Red);
- sprintf((char*)text1," Threshold 3: %dcm ",Threshold_3);
- LCD_DisplayStringLine(Line6,text1);
- }
- else
- {
- LCD_SetBackColor(Blue);
- sprintf((char*)text1," Threshold 3: %dcm ",Threshold_3);
- ![在这里插入图片描述]([img]https://img-blog.csdnimg.cn/20200225154220972.png[/img]?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDIzNjMwMg==,size_16,color_FFFFFF,t_70)LCD_DisplayStringLine(Line6,text1);
- }
- //设置不要的行的颜色为背景颜色
- LCD_SetBackColor(Blue);
- LCD_DisplayStringLine(Line0 ," ");
- LCD_DisplayStringLine(Line1 ," ");
- LCD_DisplayStringLine(Line3 ," ");
- LCD_DisplayStringLine(Line7 ," ");
- LCD_DisplayStringLine(Line8 ," ");
- LCD_DisplayStringLine(Line9 ," ");
- }
- //串口部分
- if(RXOVER)
- {
- RXOVER = 0;
- if(RXBUF[0] == 'C')
- {
- sprintf((char*)TXBUF,"C:H%d+L%d\r\n",Height,Level_now);
- Send_String(TXBUF);
- }
- else if(RXBUF[0] == 'S')
- {
- sprintf((char*)TXBUF,"S:TL%d+TM%d+TH%d\r\n",Threshold_1,Threshold_2,Threshold_3);
- Send_String(TXBUF);
- }
- for(k=0;k<5;k++)
- {
- LED_Control(LED1,1);
- LED_Control(LED3,0);
- Delay_Ms(200);
- LED_Control(LED3,1);
- Delay_Ms(200);
- }
- for(i=0;i<20;i++)
- {
- RXBUF[i] = 0; [/i][i]
- }
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- }
- }
- /************************液位水平比较函数**************************************/
- void Deal_Data(void)
- {
- Height = ADC_Value * 100 / 3.3; //根据题目要求的关系
- if(Height <= Threshold_1)
- {
- Level_now = 0;
- }
- else if((Threshold_1 < Height ) && (Height <= Threshold_2))
- {
- Level_now = 1;
- }
- else if((Threshold_2 < Height ) && (Height <= Threshold_3))
- {
- Level_now = 2;
- }
- else if(Threshold_3 < Height )
- {
- Level_now = 3;
- }
- }
- /************************LED闪烁函数**************************************/
- void LED_Blink(void)
- {
- //LED1_配置
- if(K1_FLAG == 0) //运行状态下
- {
- if(LED1_on == 1)
- {
- LED1_on =0;
- LED_Control(LED1,0);
- }
- if(LED1_off == 1)
- {
- LED1_off=0;
- LED_Control(LED1,1);
- }
- }
- else
- {
- LED_Control(LED1,1);
- }
- //LED2_配置
- if(Level_old != Level_now)
- {
- if(Level_now > Level_old)
- {
- sprintf((char*)TXBUF,"A:H%d+L%d+U\r\n",Height,Level_now);
- Send_String(TXBUF);
- }
- if(Level_now < Level_old)
- {
- sprintf((char*)TXBUF,"A:H%d+L%d+D\r\n",Height,Level_now);
- Send_String(TXBUF);
- }
- for(j=0;j<5;j++)
- {
- LED_Control(LED1,1);
- LED_Control(LED2,0);
- Delay_Ms(200);
- LED_Control(LED2,1);
- Delay_Ms(200);
- }
- }
- Level_old = Level_now; //加载上一次的液位等级
- }
- /************************外设时钟函数**************************************/
- void RCC_Configuration(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
- }
- /************************外设时钟函数**************************************/
- void KEY_Scan(void)
- {
- if(K1 == 0)
- {
- Delay_Ms(10);
- if(K1 == 0)
- {
- if(K1_FLAG == 0)
- {
- K1_FLAG = 1;
- }
- else
- {
- K1_FLAG = 0;
- }
- }
- while(K1 == 0)
- LCD_ClearLine(Line0);
- LCD_ClearLine(Line1);
- LCD_ClearLine(Line2);
- LCD_ClearLine(Line3);
- LCD_ClearLine(Line4);
- LCD_ClearLine(Line5);
- LCD_ClearLine(Line6);
- LCD_ClearLine(Line7);
- LCD_ClearLine(Line8);
- LCD_ClearLine(Line9);
- }
- if(K2 == 0 && K1_FLAG == 1)
- {
- Delay_Ms(10);
- if(K2 == 0 && K1_FLAG == 1)
- {
- if(K2_FLAG < 3)
- K2_FLAG++;
- else
- K2_FLAG=1;
- }
- while(K2 == 0);
- }
- if(K3 == 0)
- {
- Delay_Ms(10);
- if(K3 == 0)
- {
- if(K2_FLAG == 1)
- {
- if(Threshold_1 < Threshold_2)
- Threshold_1 +=5;
- else
- Threshold_1 = Threshold_2;
- }
- else if(K2_FLAG == 2)
- {
- if(Threshold_2<Threshold_3)
- Threshold_2 +=5;
- else
- Threshold_2 = Threshold_3;
- }
- else if(K2_FLAG == 3)
- {
- if(Threshold_3<90)
- Threshold_3 +=5;
- else
- Threshold_3 = 95;
- }
- }
- while(K3 == 0);
- }
- if(K4 == 0)
- {
- Delay_Ms(10);
- if(K4 == 0)
- {
- if(K2_FLAG == 1)
- {
- if(Threshold_1>5)
- Threshold_1 -=5;
- else
- Threshold_1 = 5;
- }
- else if(K2_FLAG == 2)
- {
- if(Threshold_2 >Threshold_1)
- Threshold_2 -=5;
- else
- Threshold_2 = Threshold_1;
- }
- else if(K2_FLAG == 3)
- {
- if(Threshold_3>Threshold_2)
- Threshold_3 -=5;
- else
- Threshold_3 = Threshold_2;
- }
- }
- while(K4 == 0);
- }
- }
- void _24c02_Write(u16 addr, u16 data)
- {
- I2CStart();
- I2CSendByte(0xa0);
- I2CSendAck();
- I2CSendByte(addr);
- I2CSendAck();
- I2CSendByte(data);
- I2CSendAck();
- I2CStop();
- }
- u16 _24c02_Read(u16 addr)
- {
- u16 temp;
- I2CStart();
- I2CSendByte(0xa0);
- I2CSendAck();
- I2CSendByte(addr);
- I2CSendAck();
-
- I2CStart();
- I2CSendByte(0xa1);
- I2CSendAck();
- temp = I2CReceiveByte();
- I2CSendAck();
- I2CStop();
- return temp;
-
- }
- void Delay_Ms(u32 nTime)
- {
- TimingDelay = nTime;
- while(TimingDelay != 0);
- }
- ```
- **第二部分:初始化配置**
- ```bash
- #define LED1 GPIO_Pin_8
- #define LED2 GPIO_Pin_9
- #define LED3 GPIO_Pin_10
- #define LED4 GPIO_Pin_11
- #define LED5 GPIO_Pin_12
- #define LED6 GPIO_Pin_13
- #define LED7 GPIO_Pin_14
- #define LED8 GPIO_Pin_15
- #define LEDALL GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15
- ```
- ```c
- #include "led.h"
- /**
- 功能:初始化LED管脚
- 注意:为了防止LCD LED显示的冲突对LCD写函数进行了寄存器的操作
- **/
- void LED_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = LEDALL;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- GPIO_SetBits(GPIOD,GPIO_Pin_2);
- GPIO_SetBits(GPIOC,LEDALL);
- GPIO_ResetBits(GPIOD,GPIO_Pin_2);
-
- }
- /**
- 功能:控制LED亮灭
- 入口参数ledx:LED1-LED8
- 入口参数led_sta:低电平点亮(根据原理图配置)
- **/
- void LED_Control(u16 ledx,u16 led_sta)
- {
- if(led_sta == 0)
- {
- GPIO_SetBits(GPIOD,GPIO_Pin_2);
- GPIO_ResetBits(GPIOC,ledx);
- GPIO_ResetBits(GPIOD,GPIO_Pin_2);
- }
- else
- {
- GPIO_SetBits(GPIOD,GPIO_Pin_2);
- GPIO_SetBits(GPIOC,ledx);
- GPIO_ResetBits(GPIOD,GPIO_Pin_2);
- }
- }
- ```
- ```bash
- #define K1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
- #define K2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
- #define K3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
- #define K4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)
- ```
- ```c
- #include "key.h"
- void KEY_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Configure TIM1_CH1 (PA8) as alternate function push-pull */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- ```
- ```c
- #include "usart.h"
- void USART2_Configuration(void)
- {
- USART_InitTypeDef USART_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- USART_Init(USART2, &USART_InitStructure);
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- /* Enable the USART2 */
- USART_Cmd(USART2, ENABLE);
- }
- /**
- 功能:发送字符串
- 入口参数:发送内容
- **/
- void Send_String(u8 *str)
- {
- u8 index = 0;
- do
- {
- USART_SendData(USART2, str[index]);
- while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
- index++;
- }
- while(str[index] != 0);
- }
- ```
- ```c
- #include "adc.h"
- void ADC_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC时钟分频,不能超过14M,所以72/6=12M
- /* ADC1 configuration ------------------------------------------------------*/
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfChannel = 1;
- ADC_Init(ADC1, &ADC_InitStructure);
- ADC_Cmd(ADC1, ENABLE);
-
- /* Enable ADC1 reset calibration register */
- ADC_ResetCalibration(ADC1);
- /* Check the end of ADC1 reset calibration register */
- while(ADC_GetResetCalibrationStatus(ADC1));
- /* Start ADC1 calibration */
- ADC_StartCalibration(ADC1);
- /* Check the end of ADC1 calibration */
- while(ADC_GetCalibrationStatus(ADC1));
-
- }
- /**
- 功能:获取模拟输入变量
- 入口参数:ADC的通道(因为板上配置ADC_Channel_8)
- 局部变量:u16 temp保存读取的模拟量
- 返回值:temp保存读取的模拟量
- **/
- u16 Get_ADC(u8 channel)
- {
- u16 temp;
- /* ADC1 regular channel14 configuration */
- ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
- ADC_SoftwareStartConvCmd(ADC1,ENABLE);
- while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0); //转换结束标志ADC_FLAG_EOC
- temp = ADC_GetConversionValue(ADC1);
- ADC_SoftwareStartConvCmd(ADC1,DISABLE);
- return temp;
- }
- ```
- **第三部分:中断处理**
- ```bash
- extern u32 TimingDelay;
- extern u8 RXBUF[20];
- extern u8 RXOVER;
- extern u8 RXCOUNT;
- extern u8 LED1_on;
- extern u8 LED1_off;
- extern u8 ADC_Flag;
- ```
- ```c
- void SysTick_Handler(void)
- {
- static u16 count1 = 0 ,count2 =0;
- TimingDelay--;
- if(++count1 == 1000)
- {
- count1 = 0;
- LED1_on = 1;
- ADC_Flag = 1;
- }
- if(++count2 == 2000)
- {
- count2 = 0;
- LED1_off = 1;
- }
- }
- void USART2_IRQHandler(void)
- {
- u8 temp;
- if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
- {
- USART_ClearITPendingBit(USART2,USART_IT_RXNE);
- temp = USART_ReceiveData(USART2);
- if(temp == '\n' || RXCOUNT ==20)
- {
- // RXBUF[RXCOUNT - 1] = 0; //防止最后出现乱码\r
- RXOVER = 1;
- RXCOUNT=0;
- USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
- }
- else
- {
- RXBUF[RXCOUNT] = temp;
- RXCOUNT++;
- }
- }
- }
复制代码
|