蓝桥杯嵌入式第十届省赛

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

#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 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 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);
  TIM_Cmd(TIM4, ENABLE);   
}


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"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/


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

extern void Key_action(int code);
void LED_Init(void);
void KEY_Init(void);
void KEY_Driver(void);
void KEY_Scan(void);
void Adc1_Init(void);
u16 Get_adc(void);
void Tim4_Init(u16 arr,u16 psc);



#endif /* __TX_H */

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

i2c.c中

void i2c_write(u16 add,u8 data){
  I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(add);
  I2CWaitAck();
  I2CSendByte(data);
  I2CWaitAck();
  I2CStop();
}
u8 i2c_read(u16 add){
  u8 temp;
  I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(add);
  I2CWaitAck();

  I2CStart();
  I2CSendByte(0xa1);
  I2CWaitAck();
  temp=I2CReceiveByte();
  I2CSendAck();
  I2CStop();
  return temp;
}

2.中断函数
stm32f10x_it.h

extern u8 ms200_flag;
extern u8 ms500_flag;
extern u8 s1_flag;
void TIM4_IRQHandler(void)
{
  static u16 ms200_count=0;
  static u16 ms500_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++;
    ms500_count++;
	s1_count++;
	if(ms200_count>=100){
	  ms200_count=0;
	  ms200_flag=1;
	}
	if(ms500_count>=100){
	  ms500_count=0;
	  ms500_flag=1;
	}
	if(s1_count>=500){
	  s1_count=0;
	  s1_flag=1;
	}	
  }
}

3.主函数
main.c

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

u32 TimingDelay = 0;

u8 ms200_flag=1;
u8 ms500_flag=0;
u8 s1_flag=0;

u8 SET_flag=0;//0-数据显示界面,1-设置界面
u8 Index_flag=0;//参数选择
u8 Status_flag=0;//0-Upper,1-Lower,2-Normal

float adc_value;//实时电压
float adc_min=1.2;//最小电压
float adc_max=2.4;//最大电压

u8 Led_flag=0; //0-上限提示灯为LD1,下限为LD2,1-上限LD2,下限LD1
u8 Led1_flag=0;//LD1标志
u8 Led2_flag=0;//LD2标志
u16 LED_MODE=0xffff;

u8 str[20];
void Delay_Ms(u32 nTime);
void Refresh(void);
void Key_action(int code);
void Show_real(void);
void Show_set(void);

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

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

	adc_max=i2c_read(0x00)*1.0/10;Delay_Ms(5);
	adc_min=i2c_read(0x01)*1.0/10;Delay_Ms(5);
	Led_flag=i2c_read(0x02);Delay_Ms(5);

	while(1){
	  KEY_Driver();
	  if(ms200_flag){
	  	ms200_flag=0;
	    Refresh();
		if(SET_flag==0)
		  Show_real();
		else if(SET_flag==1)
		  Show_set();	  
	  }		 	
	}
}

void Refresh(void){
  adc_value=Get_adc()*3.3/4096;
  if(adc_value>=adc_max)
    Status_flag=0; //上限
  else if(adc_value<=adc_min)
    Status_flag=2; 	 //下限
  else 
    Status_flag=1;
  
  if(Status_flag==0){ //上限
  	if(Led_flag==0){
	  Led1_flag=1;
	  Led2_flag=0;
	}
	else if(Led_flag==1){
	  Led1_flag=0;
	  Led2_flag=1;
	}
  }
  if(Status_flag==1){ //正常
  	Led1_flag=0;
	Led2_flag=0;
  }
  
  if(Status_flag==2){ //下限
  	if(Led_flag==0){
	  Led1_flag=0;
	  Led2_flag=1;
	}
	else if(Led_flag==1){
	  Led1_flag=1;
	  Led2_flag=0;
	}
  }
  
  if(Led1_flag)
    LED_MODE^=(1<<8);
  else 
    LED_MODE|=(1<<8); 
  GPIOC->ODR=LED_MODE;
  GPIOD->ODR|=(1<<2);  
  GPIOD->ODR&=~(1<<2);

  if(Led2_flag)
    LED_MODE^=(1<<9);
  else 
    LED_MODE|=(1<<9); 
  GPIOC->ODR=LED_MODE;
  GPIOD->ODR|=(1<<2);  
  GPIOD->ODR&=~(1<<2);
}

void Key_action(int code){
  if(code==1){
    SET_flag^=1;
	if(SET_flag==0){
	  i2c_write(0x00,adc_max*10);Delay_Ms(5);
	  i2c_write(0x01,adc_min*10);Delay_Ms(5);
	  i2c_write(0x02,Led_flag);Delay_Ms(5);
	}
  }
  else if(code==2){
    if(SET_flag==1){
	  Index_flag++;
	  if(Index_flag>3)
	    Index_flag=0;
	}
  }
  else if(code==3){
    if(SET_flag==1){
	  if(Index_flag==0) {
	    adc_max+=0.3;
		if(adc_max>=3.3)
		  adc_max=3.3;
	  }
	  else if(Index_flag==1) {
	    adc_min+=0.3;
		if(adc_min>=3.3)
		  adc_min=3.3;
	  }	
	  else if(Index_flag==2){
		 Led_flag=1;
	  }
	  else if(Index_flag==3){
		 Led_flag=0;
	  }
	}
  }
  else if(code==4){
    if(SET_flag==1){
	  if(Index_flag==0) {
	    adc_max-=0.3;
		if(adc_max<=0.0)
		  adc_max=0.0;
	  }
	  else if(Index_flag==1) {
	    adc_min-=0.3;
		if(adc_min<=0.0)
		  adc_min=0.0;
	  }	
	  else if(Index_flag==2){
		 Led_flag=0;
	  }
	  else if(Index_flag==3){
		 Led_flag=1;
	  }
	}   
  }
}
void Show_real(void){
  sprintf((char*)str,"        Main      ");
  LCD_DisplayStringLine(Line1, str);
  sprintf((char*)str,"                     ");
  LCD_DisplayStringLine(Line3, str);
  sprintf((char*)str,"    Volt: %.2fV     ",adc_value);
  LCD_DisplayStringLine(Line5, str);
  switch(Status_flag){
    case 0:
	  sprintf((char*)str,"    Status: Upper     ");
	  break;
	case 1:
	  sprintf((char*)str,"    Status: Normal     ");
	  break;
	case 2:
	  sprintf((char*)str,"    Status: Lower     ");
	  break;
	default:
	  break;
  }
  LCD_DisplayStringLine(Line7, str);
  sprintf((char*)str,"                     ");
  LCD_DisplayStringLine(Line9, str); 
}

void Show_set(void){
  sprintf((char*)str,"       Setting      ");
  LCD_DisplayStringLine(Line1, str);

  if(Index_flag==0)
    LCD_SetTextColor(Green);
  else 
    LCD_SetTextColor(White);
  sprintf((char*)str,"   Max Volt: %.1fV     ",adc_max);
  LCD_DisplayStringLine(Line3, str);
  LCD_SetTextColor(White);

  if(Index_flag==1)
    LCD_SetTextColor(Green);
  else 
    LCD_SetTextColor(White);
  sprintf((char*)str,"   Min Volt: %.1fV     ",adc_min);
  LCD_DisplayStringLine(Line5, str);
  LCD_SetTextColor(White);

  if(Index_flag==2)
    LCD_SetTextColor(Green);
  else 
    LCD_SetTextColor(White);
  if(Led_flag==0)
    sprintf((char*)str,"   Upper: LD1    ");
  else
    sprintf((char*)str,"   Upper: LD2     ");
  LCD_DisplayStringLine(Line7, str);
  LCD_SetTextColor(White);

  if(Index_flag==3)
    LCD_SetTextColor(Green);
  else 
    LCD_SetTextColor(White);
  if(Led_flag==0)
    sprintf((char*)str,"   Lower: LD2    ");
  else
    sprintf((char*)str,"   Lower: LD1    ");
  LCD_DisplayStringLine(Line9, str);
  LCD_SetTextColor(White);	   
}

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

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值