蓝桥杯嵌入式第七届省赛-液位检测告警系统

一、题目
在这里插入图片描述在这里插入图片描述
二、解答
1.初始化代码
tx.h

#include "tx.h"

void LED_Init(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = 0xff00;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIOD->ODR|=(1<<2);
  GPIOC->ODR|=0xff00;
  GPIOD->ODR&=~(1<<2);

}

void KEY_Init(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

u8 key_status[4]={1,1,1,1};

void KEY_Driver(void){
  u8 i;
  static u8 backup[4]={1,1,1,1};
  for(i=0;i<4;i++){
    if(backup[i]!=key_status[i]){
	  if(backup[i]!=0){
	  	Key_action(i+1);
	  }
	  backup[i]=key_status[i];
	}	  
  }	  
}  

void KEY_Scan(void){
  u8 i;
  static u8 key_buf[4]={0xff,0xff,0xff,0xff};
  key_buf[0]=(key_buf[0]<<1)|KEY1;
  key_buf[1]=(key_buf[1]<<1)|KEY2;
  key_buf[2]=(key_buf[2]<<1)|KEY3;
  key_buf[3]=(key_buf[3]<<1)|KEY4;
  for(i=0;i<4;i++){
    if(key_buf[i]==0x00)
	  key_status[i]=0;
	else if(key_buf[i]==0xff)
	  key_status[i]=1;
  }	
}

void Tim4_Init(u16 arr,u16 psc){
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);

  TIM_TimeBaseStructure.TIM_Period = arr-1;
  TIM_TimeBaseStructure.TIM_Prescaler = psc-1;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  TIM_ITConfig(TIM4,  TIM_IT_Update, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM4, ENABLE);
}

void Adc1_Init(void){
  ADC_InitTypeDef ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  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));

}

u16 Get_adc(void){
  u16 temp;
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);
  temp=ADC_GetConversionValue(ADC1);
  ADC_SoftwareStartConvCmd(ADC1, DISABLE);
  return temp;
}

void Usart2_Init(void){
  USART_InitTypeDef USART_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_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);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_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;
  USART_Init(USART2, &USART_InitStructure);
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART2, ENABLE); 
}

void Send_string(u8 *str){
  u8 i=0;
  while(str[i]!=0){
  	USART_SendData(USART2,str[i]);
  	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==0);
	i++;
  }	 
}


tx.h

/*
  程序说明: CT117E嵌入式竞赛板LCD驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT117E嵌入式竞赛板
  日    期: 2011-8-9
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TX_H
#define __TX_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

#define KEY1 GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_8)
#define KEY3 GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_1)
#define KEY4 GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_2)

void LED_Init(void);
void KEY_Init(void);
void KEY_Driver(void);
void KEY_Scan(void);
void Tim4_Init(u16 arr,u16 psc);
void Adc1_Init(void);
u16 Get_adc(void);
void Usart2_Init(void);
void Send_string(u8 *str);
extern void Key_action(int code);



#endif /* __TX_H */

/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

2.主函数中
main.c

#include "stm32f10x.h"
#include "lcd.h"
#include "stdio.h"
#include "i2c.h"
#include "tx.h"

u32 TimingDelay = 0;

u8 ms200_flag=1;
u8 s1_flag=0;

u8 RXD_flag=0;
u8 RXD_buf[20];
u8 i;
u8 str[20];

float adc_value;
float height;//液位高度
u8 level; //液位等级

u8 level_buf=0;//缓存之前的液位,便于判断液位等级变化

u8 SET_flag=0;   //0 实时数据界面,1 设置界面
u8 Index_flag=1;//1-阈值1,2-阈值2 ,3-阈值3

u8 LED2_flag=0;
u16 LED2_count=0;
u8 LED3_flag=0;
u16 LED3_count=0;
u16 LED_MODE=0xffff;

u8 th1=30;//阈值
u8 th2=50;
u8 th3=70;
 
void Refresh(void);
void Level_change(void);
void Show_realdata(void);
void Show_setdata(void);
void Led_action(void);
void Usart2_action(void);
void Key_action(int code);
void In_data(void);
void De_data(void);
void Delay_Ms(u32 nTime);

//Main Body
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);

	Delay_Ms(200);
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LED_Init();
	KEY_Init();
	Tim4_Init(2000,72);
    Adc1_Init();
	Usart2_Init();
	i2c_init();

	th1=i2c_read(0x00);Delay_Ms(5);
	th2=i2c_read(0x01);Delay_Ms(5);
	th3=i2c_read(0x02);Delay_Ms(5);
	          
	
	while(1){
	  KEY_Driver();
	  if(s1_flag){
	  	s1_flag=0;
		LED_MODE^=(1<<8);
	    GPIOC->ODR=LED_MODE;
	    GPIOD->ODR|=(1<<2);
        GPIOD->ODR&=~(1<<2);
	  }
	  if(ms200_flag){
	  	ms200_flag=0;
		Refresh();
		if(SET_flag==0)
		  Show_realdata();
		else if(SET_flag==1)
		  Show_setdata(); 
		Level_change();
		Led_action();	
	  }
	  if(RXD_flag==1){
	    RXD_flag=0;
		Usart2_action();
	  }
	}
}

void Refresh(void){
   adc_value=Get_adc()*3.3/4096;
   height=100*adc_value/3.3;
   if(height<=th1)
     level=0;
  else if(height<=th2)
     level=1;
  else if(height<=th3)
     level=2;
  else
     level=3;
}

void Level_change(void){
  if(level_buf!=level){
  	LED2_flag=1;
	if(level_buf<level){  //升高
	  sprintf((char*)str,"H%.0f+L%d+U\r\n",height,level);
	  Send_string(str);
	}
	else{
	  sprintf((char*)str,"H%.0f+L%d+D\r\n",height,level);
	  Send_string(str);
	}
	level_buf=level;
	for(i=0;i<20;i++)
      RXD_buf[i]=0;
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  }	   
}

void Show_realdata(void){
  sprintf((char*)str,"    Liquid Level    ");
  LCD_DisplayStringLine( Line2, str);

  sprintf((char*)str,"   Height:   %.0fcm      ",height);
  LCD_DisplayStringLine( Line4, str);
  sprintf((char*)str,"   VR37:     %.2fV    ",adc_value);
  LCD_DisplayStringLine( Line6, str);
  sprintf((char*)str,"   Level:    %d       ",level);
  LCD_DisplayStringLine( Line8, str);
}

void Show_setdata(void){
  LCD_SetTextColor(White);
  sprintf((char*)str,"  Threshold Setup    ");
  LCD_DisplayStringLine( Line2, str);

  if(Index_flag==1)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  sprintf((char*)str," Threshold 1:%dcm      ",th1);
  LCD_DisplayStringLine( Line4, str);
  LCD_SetTextColor(White);

  if(Index_flag==2)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  sprintf((char*)str," Threshold 2:%dcm      ",th2);
  LCD_DisplayStringLine( Line6, str);
  LCD_SetTextColor(White);

  if(Index_flag==3)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  sprintf((char*)str," Threshold 3:%dcm      ",th3);
  LCD_DisplayStringLine( Line8, str);
  LCD_SetTextColor(White);

}

void Led_action(void){
  if(LED2_flag==1){
  	LED2_count++;
	LED_MODE^=(1<<9);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);   

	if(LED2_count>=10){
	  LED2_count=0;
	  LED2_flag=0;	   	  
	}    
  }
  if(LED3_flag==1){
  	LED3_count++;
	LED_MODE^=(1<<10);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);

	if(LED3_count>=10){
	  LED3_count=0;
	  LED3_flag=0;	  	  
	}  
  }	 
}

void Usart2_action(void){
  if(RXD_buf[0]=='C'){
  	LED3_flag=1;
	sprintf((char*)str,"H%.0f+L%d\r\n",height,level);
	Send_string(str);
  }
  if(RXD_buf[0]=='S'){
  	LED3_flag=1;
	sprintf((char*)str,"TL%d+TM%d+TH%d\r\n",th1,th2,th3);
	Send_string(str);
  }
  for(i=0;i<20;i++)
    RXD_buf[i]=0;
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}

void Key_action(int code){
  if(code==1){
  	SET_flag^=1;
	if(SET_flag==0){
	  i2c_write(0x00,th1);Delay_Ms(5);
	  i2c_write(0x01,th2);Delay_Ms(5);
	  i2c_write(0x02,th3);Delay_Ms(5);
	}   
  }
  else if(code==2){
  	if(SET_flag==1){
	  Index_flag++;
	  if(Index_flag>3)
	    Index_flag=1;
	}  
  }
  else if(code==3){
    if(SET_flag==1)
	  In_data();
  }
  else if(code==4){
    if(SET_flag==1)
	  De_data();
  }
}

void In_data(void){
  if(Index_flag==1){
  	th1+=5;
	if(th1>=95)
	  th1=95;
  }
  else if(Index_flag==2){
  	th2+=5;
	if(th2>=95)
	  th2=95;
  }
  else if(Index_flag==3){
  	th3+=5;
	if(th3>=95)
	  th3=95;
  }
}

void De_data(void){
  if(Index_flag==1){
  	th1-=5;
	if(th1<=5)
	  th1=5;
  }
  else if(Index_flag==2){
  	th2-=5;
	if(th2<=5)
	  th2=5;
  }
  else if(Index_flag==3){
  	th3-=5;
	if(th3<=5)
	  th3=5;
  }
}	

void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

3.中断
stm32f10x_it.c

void SysTick_Handler(void)
{
	TimingDelay--;
}

extern u8 ms200_flag;
extern u8 s1_flag;
void TIM4_IRQHandler(void)
{
  static u16 ms200_count=0;
  static u16 s1_count=0;
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	KEY_Scan();
	ms200_count++;
	s1_count++;
	if(s1_count>=500){
	  s1_count=0;
	  s1_flag=1; 
	}
	if(ms200_count>=100){
	   ms200_flag=1;
	   ms200_count=0;
	}
  }
}

extern u8 RXD_flag;
extern u8 RXD_buf[20];
u16 RXD_count=0;
void USART2_IRQHandler(void)
{
  u16 temp;
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    temp= USART_ReceiveData(USART2);
	USART_ClearITPendingBit(USART2,USART_IT_RXNE);
	if(temp=='\n'){
      RXD_flag=1;
	  RXD_count=0;
      USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    }
	else {
	  RXD_buf[RXD_count++]=temp;
	}
  }
}
发布了26 篇原创文章 · 获赞 9 · 访问量 2915

猜你喜欢

转载自blog.csdn.net/fancyZT/article/details/105385457