蓝桥杯嵌入式第九届国赛程序----电子秤

第九届决赛题目主要考察了adc按键、串口、adc等。其中要用到两个adc通道(一个用于称重,一个用于测量adc按键)可以用2路规则通道(必须使用DMA),也可以1路使用规则通道,1路使用注入通道,这里采用后者。

工程结构

init.c

#include "stm32f10x.h"
#include "lcd.h"
#include "init.h"
#include "i2c.h"


void GPIO_Int(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef  ADC_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	//led
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
    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_Init(GPIOD, &GPIO_InitStructure);


	//key
	//led
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

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


	GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);


	//adc
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &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);

  /* ADC1 regular channel4、5 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_13Cycles5);
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_13Cycles5);

  ADC_AutoInjectedConvCmd(ADC1,ENABLE);

  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

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

  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_TXE, ENABLE);

  /* Enable the USART2 */
  USART_Cmd(USART2, ENABLE);

}



void LCD_Init(void)
{
    STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);

//	LCD_DisplayStringLine(Line0,"  Real-time Data    ");	
//	//LCD_DisplayStringLine(Line1,"Now Temp    -20C    ");	
//	LCD_DisplayStringLine(Line2,"                    ");
//	//LCD_DisplayStringLine(Line3,"Now Humi     60%    ");
//	LCD_DisplayStringLine(Line4,"                    ");
//	//LCD_DisplayStringLine(Line5,"Clock      12-50-00 ");
//	LCD_DisplayStringLine(Line6,"                    ");
//	//LCD_DisplayStringLine(Line7,"Number         20   ");	
//	LCD_DisplayStringLine(Line8,"                    ");
//	LCD_DisplayStringLine(Line9,"                    ");	
}






unsigned char I2C_Read(unsigned char add)
{
	unsigned char temp;

	I2CStart();
	I2CSendByte(0xa0);
	I2CSendAck();

	I2CSendByte(add);
	I2CSendAck();

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

	return temp;

}

void I2C_Write(unsigned char add,unsigned char dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CSendAck();

	I2CSendByte(add);
	I2CSendAck();

	I2CSendByte(dat);
	I2CSendAck();
	I2CStop();
		
}


主程序

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


u32 TimingDelay = 0;
u8 string[20];
unsigned char ucState=0,ucled=0,ucUart;
unsigned long ulTick_ms,ulAkey_Time,ucAkey_Long;



void Key_Scan(void);

void Delay_Ms(u32 nTime);
unsigned int ADC_InjConv(void);
unsigned int  ADC_Conv(void);
void LCD_Proc(void);
void USART_Send(u8 *str);


unsigned int uiGw,uiGt;
unsigned char ucNo=1,ucCnt;
unsigned int puiUw[4],puiUw_Old[4];	   //注意这里是100倍关系,原因是eeprom只能存0~255的整数
unsigned char AKEY_Read(void);
void AKEY_Proc(void);
void S1_Proc(void);
void S2_Proc(void);
void S3_Proc(void);
void LED_Disp(u16 led);
void UART_Proc(void);

int main(void)
{
	LCD_Init();
	GPIO_Int();
	i2c_init();
	
	Delay_Ms(5);
	if(I2C_Read(0x20)!=10)
	{

	Delay_Ms(5);
	I2C_Write(0x20,10);

	Delay_Ms(5);
	I2C_Write(0x00,0);
	Delay_Ms(5);
	I2C_Write(0x01,1);

	Delay_Ms(5);
	I2C_Write(0x02,0);
	Delay_Ms(5);
	I2C_Write(0x03,2);

	Delay_Ms(5);
	I2C_Write(0x04,0);
	Delay_Ms(5);
	I2C_Write(0x05,3);

	Delay_Ms(5);
	I2C_Write(0x06,0);
	}

	Delay_Ms(5);
	puiUw[1]=I2C_Read(0x01)*100;
	Delay_Ms(5);
	puiUw[1]+=I2C_Read(0x00);

	

	Delay_Ms(5);
	puiUw[2]=I2C_Read(0x03)*100;
	Delay_Ms(5);
	puiUw[2]+=I2C_Read(0x02);

	Delay_Ms(5);
	puiUw[3]=I2C_Read(0x05)*100;
	Delay_Ms(5);
	puiUw[3]+=I2C_Read(0x04);

	Delay_Ms(5);
	ucCnt=I2C_Read(0x06);


	 USART_Send("hello world!");
   	
	
	while(1)
	{
	//Key_Scan();
	LCD_Proc();
	AKEY_Proc();
	LED_Disp(ucled);
	UART_Proc();
//	sprintf((char*)string,"key :%1u",AKEY_Read());
//	LCD_DisplayStringLine(Line1,string);

	}
}

//void Key_Scan(void)
//{
// if(RB1==0)
// {
// Delay_Ms(5);
// if(RB1==0)
// {
//  
// }while(!RB1);
// }
//
// else if(RB2==0)
// {
// Delay_Ms(5);
// if(RB2==0)
// {
// 
// }while(!RB2);
// }
//
// else if(RB3==0)
// {
// Delay_Ms(5);
// if(RB3==0)
// {
// 
//  
// }while(!RB3);
// }
//
// else if(RB4==0)
// {
// Delay_Ms(5);
// if(RB4==0)
// {
//  
//  
// }while(!RB4);
// }
//
//}

unsigned char AKEY_Read(void)
{
 unsigned char ucAkey_Val=0;
 unsigned int uiAdc_Val=ADC_Conv();
 if(uiAdc_Val<4095)
 {
 Delay_Ms(2);
 uiAdc_Val=ADC_Conv();
 if(uiAdc_Val<4095)
	 {
	 if(uiAdc_Val>4000)
	 ucAkey_Val=8;
	 else if(uiAdc_Val>3500)
	 ucAkey_Val=7;
	 else if(uiAdc_Val>2800)
	 ucAkey_Val=6;
	 else if(uiAdc_Val>2066)
	 ucAkey_Val=5;
	 else if(uiAdc_Val>1608)
	 ucAkey_Val=4;
	 else if(uiAdc_Val>1201)
	 ucAkey_Val=3;
	 else if(uiAdc_Val>498)
	 ucAkey_Val=2;
	 else
	 ucAkey_Val=1;
    
	 }

 }
 return ucAkey_Val;

}

void AKEY_Proc(void)
{
unsigned char ucAkey_Val;
ucAkey_Val=AKEY_Read();
if(ucAkey_Val!=ucAkey_Long)
{
  ucAkey_Long=ucAkey_Val;
  ulAkey_Time=ulTick_ms;
}
else 
ucAkey_Val=0;
switch(ucAkey_Val)
{
case 1:
S1_Proc();break;
case 2:
S2_Proc();break;
case 3:
S3_Proc(); break;
case 4:
if(ucState)
	if(++ucState==4)
	ucState=1;
break;
case 5:
if(!ucState)
ucNo=1;break;
case 6:
if(!ucState)
ucNo=2;break;
case 7:
if(!ucState)
ucNo=3;break;
case 8:
if(!ucState)
{
ucUart=1;			  //计费标志
uiGt=uiGw*puiUw[ucNo];
}

}			  

	if(ulTick_ms-ulAkey_Time>800)
	{
		switch(ucAkey_Long)
		{
		case 2:
		S2_Proc();break;
		case 3:
		S3_Proc();break;
		}
	}

}


void S1_Proc(void)
{
	if(!ucState)
	{
	ucState=1;//设置状态
	puiUw_Old[1]=puiUw[1];
	puiUw_Old[2]=puiUw[2];
	puiUw_Old[3]=puiUw[3];
	}
	else 
	{
	ucState=0;  //称重状态
	ucUart=2;
	
	if((puiUw[1]!=puiUw_Old[1])||(puiUw[2]!=puiUw_Old[2])||(puiUw[3]!=puiUw_Old[3]))
	{
	Delay_Ms(5);
	I2C_Write(0x00,puiUw[1]%100);
	Delay_Ms(5);
	I2C_Write(0x01,puiUw[1]/100);

	Delay_Ms(5);
	I2C_Write(0x02,puiUw[2]%100);
	Delay_Ms(5);
	I2C_Write(0x03,puiUw[2]/100);

	Delay_Ms(5);
	I2C_Write(0x04,puiUw[3]%100);
	Delay_Ms(5);
	I2C_Write(0x05,puiUw[3]/100);

	Delay_Ms(5);
	I2C_Write(0x06,++ucCnt);
	
	}
	}		  

}

void S2_Proc(void)
{
if(ucState)
{
 if(puiUw[ucState]<1000)
 puiUw[ucState]++;
}
}

void S3_Proc(void)
{
if(ucState)
{
 if(puiUw[ucState]>0)
 puiUw[ucState]--;
}
}


void UART_Proc(void)
{
float temp;
if(ucUart==1)
{
temp=(float)puiUw[ucNo]/100.0;
sprintf((char*)string,"U.W.%1u:%5.2f\r\n",ucNo,temp);
USART_Send(string);

temp=(float)uiGw/1000.0;
sprintf((char*)string,"G.W  :%5.2f\r\n",temp);
USART_Send(string);

temp=(float)uiGt/100000;
sprintf((char*)string,"TOTAL:%5.2f\r\n",temp);
USART_Send(string);
}

if(ucUart==2)
{
temp=(float)puiUw[1]/100.0;
sprintf((char*)string,"U.W.1:%5.2f\r\n",temp);
USART_Send(string);

temp=(float)puiUw[2]/100.0;
sprintf((char*)string,"U.W.2:%5.2f\r\n",temp);
USART_Send(string);

temp=(float)puiUw[3]/100.0;
sprintf((char*)string,"U.W.3:%5.2f\r\n",temp);
USART_Send(string);
}
ucUart=0;

}




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

unsigned int  ADC_Conv(void)
{
/* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);

  return ADC_GetConversionValue(ADC1);
}

unsigned int ADC_InjConv(void)
{
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
 while(ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC)==RESET);
 ADC_ClearFlag(ADC1,ADC_FLAG_JEOC);

 return ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
}

void LCD_Proc(void)
{
	float temp;
	uiGw=ADC_InjConv()*10000/0xfff;

	if(!ucState)
	{
    LCD_DisplayStringLine(Line0,"  Weight & Charge   ");
	//LCD_DisplayStringLine(Line1,"                    ");



	sprintf((char*)string,"Number: %1u           ",ucNo);	
	LCD_DisplayStringLine(Line2,string);	
	
	LCD_DisplayStringLine(Line3,"                    ");

    temp=(float)puiUw[ucNo]/100.0;
	sprintf((char*)string,"Price : %5.2fYuan/kg ",temp);
	LCD_DisplayStringLine(Line4,string);

	LCD_DisplayStringLine(Line5,"                    ");

	temp=uiGw/1000.0;
	sprintf((char*)string,"Weight: %5.2fkg      ",temp);	
	LCD_DisplayStringLine(Line6,string);

	LCD_DisplayStringLine(Line7,"                    ");
	
	temp=(uiGw/1000.0)*(puiUw[ucNo]/100.0);
	sprintf((char*)string,"Total :  %5.2fYuan    ",temp);	
	LCD_DisplayStringLine(Line8,string);

	LCD_DisplayStringLine(Line9,"                    ");
	}

	else 							  //设置
	{
	 LCD_DisplayStringLine(Line0," Parameter Setting  ");

	 temp=(float)puiUw[1]/100;
	 sprintf((char*)string,"Price 1:%5.2fYuan/kg",temp);
	 if(ucState==1)LCD_SetBackColor(Red);
	 LCD_DisplayStringLine(Line2,string);
	 LCD_SetBackColor(Blue);

	 temp=(float)puiUw[2]/100.0;
	 sprintf((char*)string,"Price 2:%5.2fYuan/kg",temp);
	 if(ucState==2)LCD_SetBackColor(Red);
	 LCD_DisplayStringLine(Line4,string);
	 LCD_SetBackColor(Blue);

	 temp=(float)puiUw[3]/100.0;
	 sprintf((char*)string,"Price 3:%5.2fYuan/kg",temp);
	 if(ucState==3)LCD_SetBackColor(Red);
	 LCD_DisplayStringLine(Line6,string);
	 LCD_SetBackColor(Blue);

	 sprintf((char*)string,"Count  :%2u         ",ucCnt);
	 LCD_DisplayStringLine(Line8,string);
		
	}
		
}


void LED_Disp(u16 led)
{
GPIO_Write(GPIOC,~led<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}

void USART_Send(u8 *str)
{
u8 index=0;
do{
  USART_SendData(USART2,str[index++]);
  while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
}while(str[index]!=0);
}


 void SysTick_Handler(void)
{
	TimingDelay--;
	ulTick_ms++;
	if(!ucState)
	{
	if(ulTick_ms%800==0)
	{
	ucled^=1;
	}
	}

	else 
	{
	if(ulTick_ms%400==0)
	{
	ucled^=1;
	}
	}
}
发布了61 篇原创文章 · 获赞 145 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qqGHJ/article/details/105308415