第九届决赛题目主要考察了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;
}
}
}