#include "stm32f10x.h"
#include "lcd.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "i2c.h"
#include "adc.h"
typedef unsigned char uchar;
typedef unsigned int uint;
uint uiAdc_Val; //R37模拟液位传感器的ADC值
uchar ucHeight,ucLevel,ucLevel1; //液位高度、液位等级
uchar ucState,pucStr[21],pucTh[3],pucRcv[1]; //LCD显示缓冲区、液位阈值、串口缓冲区
uchar ucLed,ucLd2,ucLd3,ucNum = 10; //点亮LED
uchar ucSec,ucSec1,ucKey_Long; //保存ms、s,长按标志位
unsigned long ulTick_ms; //滴答定时器的计数
void KEY_Proc(void);
void LCD_Proc(void);
void ADC_Proc(void);
void UART_Proc(void);
//Main Body
int main(void)
{
SysTick_Config(SystemCoreClock/1000); //设置系统滴答时钟1ms并使能中断
KEY_Init(); //按键初始化
LED_Init(); //LED初始化
STM3210B_LCD_Init(); //LCD初始化
LCD_Clear(Blue); //把屏幕刷新为蓝色
LCD_SetBackColor(Blue); //设置字体背景为蓝色
LCD_SetTextColor(White); //字体设置为白色
USART2_Init(9600); //串口初始化
i2c_init(); //IIC初始化
ADC1_Init(); //ADC初始化
i2c_read(pucTh,0,3); //AT24C02读取从地址0开始的3个字节的数据
if(pucTh[0] > 100)
pucTh[0] = 10;
if(pucTh[1] > 100)
pucTh[0] = 20;
if(pucTh[2] > 100)
pucTh[0] = 30;
while(1)
{
KEY_Proc(); //按键相对应的功能
LCD_Proc(); //LCD相对应的功能
ADC_Proc(); //ADC采集相对应的功能
UART_Proc(); //串口相对应的功能
}
}
/**********************************************************************************************
*函数:void KEY_Proc(void)
*功能:按键B1设置键,B2切换键,B3加键,B4减键
*输入:无
*输出:无
*特殊说明:各按键互不影响
**********************************************************************************************/
void KEY_Proc(void)
{
uchar ucKey_Val;
ucKey_Val = KEY_Scan(); //检测那个按键按下
if(ucKey_Val != ucKey_Long)
ucKey_Long = ucKey_Val;
else
ucKey_Val = 0; //防止长按
switch(ucKey_Val)
{
case 1: //B1:设置键
if(!ucState)
ucState = 1;
else
{
if((pucTh[0]) < pucTh[1] && pucTh[1] < pucTh[2])
{
LCD_DisplayStringLine(Line3,(u8*)" ");
i2c_write(pucTh , 0 , 3); //pucTh阈值存到AT24C02
ucState = 0;
}
else
{
LCD_SetTextColor(Red);
LCD_DisplayStringLine(Line3,(u8*)" Threshold Error "); //设置阈值有误
LCD_SetTextColor(White);
}
}
break;
case 2: //B2:切换键
if(ucState)
if(++ucState == 4)
ucState = 1;
break;
case 3: //B3:阈值加
if(ucState)
if(pucTh[ucState-1] < 95)
pucTh[ucState-1] +=5;
break;
case 4: //B3:阈值减
if(ucState)
if(pucTh[ucState-1] > 5)
pucTh[ucState-1] -=5;
break;
}
}
/**********************************************************************************************
*函数:void LCD_Proc(void)
*功能:LCD屏幕显示函数
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void LCD_Proc(void)
{
float temp;
if(!ucState) //0显示状态界面,不等于0显示设置界面
{
LCD_DisplayStringLine(Line1,(u8*)" Liquid Level ");
sprintf((char*)pucStr," Height:%03ucm ",ucHeight);
LCD_DisplayStringLine(Line4,pucStr);
temp = (float)uiAdc_Val * 3.3 /4095;
sprintf((char*)pucStr," VR37: %4.3fV ",temp);
LCD_DisplayStringLine(Line6,pucStr);
sprintf((char*)pucStr," Level: %01u ",ucLevel);
LCD_DisplayStringLine(Line8,pucStr);
}
else
{
LCD_DisplayStringLine(Line1,(u8*)" Threshold Setup ");
//索引在第1个阈值设置
sprintf((char*)pucStr," Threshold 1: %02ucm ",pucTh[0]);
if(ucState == 1)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line4,pucStr);
LCD_SetBackColor(Blue);
//索引在第2个阈值设置
sprintf((char*)pucStr," Threshold 2: %02ucm ",pucTh[1]);
if(ucState == 2)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line6,pucStr);
LCD_SetBackColor(Blue);
//索引在第3个阈值设置
sprintf((char*)pucStr," Threshold 3: %02ucm ",pucTh[2]);
if(ucState == 3)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line8,pucStr);
LCD_SetBackColor(Blue);
}
}
/**********************************************************************************************
*函数:void ADC_Proc(void)
*功能:ADC采集电位器R37的电压信号
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void ADC_Proc(void)
{
if(!ucState && ucSec != ucSec1)
{
ucSec1 = ucSec;
uiAdc_Val = ADC1_Conv(); //获取装换值
ucHeight = uiAdc_Val*100/4095; //计算液位高度 ADC_Val = V * 4095 / 3.3
if(ucHeight < pucTh[0])
ucLevel = 0;
else if(ucHeight < pucTh[1])
ucLevel = 1;
else if(ucHeight < pucTh[2])
ucLevel = 2;
else
ucLevel = 3;
if(ucLevel != ucLevel1)
{
if(ucLevel > ucLevel1) //液位升高
printf("A:H%02u+L%01u+U\r\n",ucHeight,ucLevel);
else //液位减低
printf("A:H%02u+L%01u+D\r\n",ucHeight,ucLevel);
ucLevel1 = ucLevel;
ucLd2 = 1; //等级改变
}
}
}
/**********************************************************************************************
*函数:void UART_Proc(void)
*功能:串口查询与发送函数
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void UART_Proc(void)
{
if(pucRcv[0] == 'C')
printf("C:H%02u+L%01u\r\n",ucHeight,ucLevel);
if(pucRcv[0] == 'S')
printf("S:TL%02u+TM%02u+TH%02u\r\n",pucTh[0],pucTh[1],pucTh[2]);
if(pucRcv[0] == 'C' || pucRcv[0] == 'S')
ucLd3 = 1; //串口查询
pucRcv[0] = 0;
}
/**********************************************************************************************
*函数:void SysTick_Handler(void)
*功能:滴答定时器中断函数
*输入:无
*输出:无
*特殊说明:每1模式进入一次
**********************************************************************************************/
void SysTick_Handler(void)
{
ulTick_ms++;
if(ulTick_ms%1000 == 0)
{
ucSec++;
ucLed ^=1; //LD1闪烁
}
if(ucLd2)
{
if(ulTick_ms%200 == 0)
{
if(ucNum--)
ucLed ^= 2; //LD2闪烁5次
else
{
ucLd2 = 0;
ucNum = 10;
}
}
}
if(ucLd3)
{
if(ulTick_ms%200 == 0)
{
if(ucNum--)
ucLed ^= 4; //LD3闪烁5次
else
{
ucLd3 = 0;
ucNum = 10;
}
}
}
LED_Disp(ucLed);
}
/**********************************************************************************************
*函数:void USART2_IRQHandler( void )
*功能:接收串口2的数据
*输入:无
*输出:无
*特殊说明:接收串口2的中断服务函数
**********************************************************************************************/
void USART2_IRQHandler(void)
{
pucRcv[0] = USART_ReceiveData(USART2);
}
主函数分析:❤️ ❤️ ❤️
/**********************************************************************************************
*函数:void KEY_Proc(void)
*功能:按键B1设置键,B2切换键,B3加键,B4减键
*输入:无
*输出:无
*特殊说明:各按键互不影响
**********************************************************************************************/
void KEY_Proc(void)
{
uchar ucKey_Val;
ucKey_Val = KEY_Scan(); //检测那个按键按下
if(ucKey_Val != ucKey_Long)
ucKey_Long = ucKey_Val;
else
ucKey_Val = 0; //防止长按
switch(ucKey_Val)
{
case 1: //B1:设置键
if(!ucState)
ucState = 1;
else
{
if((pucTh[0]) < pucTh[1] && pucTh[1] < pucTh[2])
{
LCD_DisplayStringLine(Line3,(u8*)" ");
i2c_write(pucTh , 0 , 3); //pucTh阈值存到AT24C02
ucState = 0;
}
else
{
LCD_SetTextColor(Red);
LCD_DisplayStringLine(Line3,(u8*)" Threshold Error "); //设置阈值有误
LCD_SetTextColor(White);
}
}
break;
case 2: //B2:切换键
if(ucState)
if(++ucState == 4)
ucState = 1;
break;
case 3: //B3:阈值加
if(ucState)
if(pucTh[ucState-1] < 95)
pucTh[ucState-1] +=5;
break;
case 4: //B3:阈值减
if(ucState)
if(pucTh[ucState-1] > 5)
pucTh[ucState-1] -=5;
break;
}
}
按键KEY简要分析:❤️ ❤️
/**********************************************************************************************
*函数:void LCD_Proc(void)
*功能:LCD屏幕显示函数
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void LCD_Proc(void)
{
float temp;
if(!ucState) //0显示状态界面,不等于0显示设置界面
{
LCD_DisplayStringLine(Line1,(u8*)" Liquid Level ");
sprintf((char*)pucStr," Height:%03ucm ",ucHeight);
LCD_DisplayStringLine(Line4,pucStr);
temp = (float)uiAdc_Val * 3.3 /4095;
sprintf((char*)pucStr," VR37: %4.3fV ",temp);
LCD_DisplayStringLine(Line6,pucStr);
sprintf((char*)pucStr," Level: %01u ",ucLevel);
LCD_DisplayStringLine(Line8,pucStr);
}
else
{
LCD_DisplayStringLine(Line1,(u8*)" Threshold Setup ");
//索引在第1个阈值设置
sprintf((char*)pucStr," Threshold 1: %02ucm ",pucTh[0]);
if(ucState == 1)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line4,pucStr);
LCD_SetBackColor(Blue);
//索引在第2个阈值设置
sprintf((char*)pucStr," Threshold 2: %02ucm ",pucTh[1]);
if(ucState == 2)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line6,pucStr);
LCD_SetBackColor(Blue);
//索引在第3个阈值设置
sprintf((char*)pucStr," Threshold 3: %02ucm ",pucTh[2]);
if(ucState == 3)
LCD_SetBackColor(Red);
LCD_DisplayStringLine(Line8,pucStr);
LCD_SetBackColor(Blue);
}
}
LCD屏幕简要分析:❤️ ❤️
/**********************************************************************************************
*函数:void ADC_Proc(void)
*功能:ADC采集电位器R37的电压信号
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void ADC_Proc(void)
{
if(!ucState && ucSec != ucSec1)
{
ucSec1 = ucSec;
uiAdc_Val = ADC1_Conv(); //获取装换值
ucHeight = uiAdc_Val*100/4095; //计算液位高度 ADC_Val = V * 4095 / 3.3
if(ucHeight < pucTh[0])
ucLevel = 0;
else if(ucHeight < pucTh[1])
ucLevel = 1;
else if(ucHeight < pucTh[2])
ucLevel = 2;
else
ucLevel = 3;
if(ucLevel != ucLevel1)
{
if(ucLevel > ucLevel1) //液位升高
printf("A:H%02u+L%01u+U\r\n",ucHeight,ucLevel);
else //液位减低
printf("A:H%02u+L%01u+D\r\n",ucHeight,ucLevel);
ucLevel1 = ucLevel;
ucLd2 = 1; //等级改变
}
}
}
ADC模拟液位电压简要分析:❤️ ❤️
/**********************************************************************************************
*函数:void UART_Proc(void)
*功能:串口查询与发送函数
*输入:无
*输出:无
*特殊说明:无
**********************************************************************************************/
void UART_Proc(void)
{
if(pucRcv[0] == 'C')
printf("C:H%02u+L%01u\r\n",ucHeight,ucLevel);
if(pucRcv[0] == 'S')
printf("S:TL%02u+TM%02u+TH%02u\r\n",pucTh[0],pucTh[1],pucTh[2]);
if(pucRcv[0] == 'C' || pucRcv[0] == 'S')
ucLd3 = 1; //串口查询
pucRcv[0] = 0;
}
串口UART简要分析:❤️ ❤️
/**********************************************************************************************
*函数:void SysTick_Handler(void)
*功能:滴答定时器中断函数
*输入:无
*输出:无
*特殊说明:每1模式进入一次
**********************************************************************************************/
void SysTick_Handler(void)
{
ulTick_ms++;
if(ulTick_ms%1000 == 0)
{
ucSec++;
ucLed ^=1; //LD1闪烁
}
if(ucLd2)
{
if(ulTick_ms%200 == 0)
{
if(ucNum--)
ucLed ^= 2; //LD2闪烁5次
else
{
ucLd2 = 0;
ucNum = 10;
}
}
}
if(ucLd3)
{
if(ulTick_ms%200 == 0)
{
if(ucNum--)
ucLed ^= 4; //LD3闪烁5次
else
{
ucLd3 = 0;
ucNum = 10;
}
}
}
LED_Disp(ucLed);
}
系统滴答定时器简要分析:❤️ ❤️
/**********************************************************************************************
*函数:void USART2_IRQHandler( void )
*功能:接收串口2的数据
*输入:无
*输出:无
*特殊说明:接收串口2的中断服务函数
**********************************************************************************************/
void USART2_IRQHandler(void)
{
pucRcv[0] = USART_ReceiveData(USART2);
}
简要分析:❤️ ❤️
①如何定义全局变量,使各个外设功能耦合在一起!
❤️ ❤️ ❤️ ❤️ ❤️ ❤️