蓝桥杯嵌入式第六届省赛试题——电压监控设备
有一段时间没有更新蓝桥杯的赛题,最近蓝桥杯国赛也结束了,准备把自己学习调试的各届试题的代码分享出来(现在有的代码格式不规范),但是基本功能是实现的,希望对大家有所帮助。
一、试题要求
二、试题解析
用的还是那几个模块,RTC,ADC,USART等,驱动代码写好,逻辑可以进一步思考。
.c文件
#include "mysource.h"
extern u8 trg;
extern u8 cont;
extern uint32_t THH1, TMM1 , TSS1 ;
extern float v1;
extern u8 k;
extern u8 string[20];
//模式选择
extern _Bool mode;
//led初始化
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
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);
}
//led灯的控制
void led_control( u8 data )
{
GPIOD->ODR |= GPIO_Pin_2;
GPIOC->ODR = ~(data<<8);
GPIOD->ODR &= ~GPIO_Pin_2;
}
//按键初始化
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//按键扫描
void key_scan(void)
{
unsigned char readate=(keyport)^0xff;
trg=readate&(readate^cont);
cont=readate;
}
//串口初始化
void usart_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Enable the USARTz Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
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;
/* Configure USARTy */
USART_Init(USART2, &USART_InitStructure);
/* Enable the USARTz Receive Interrupt */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
/* Enable USARTy */
USART_Cmd(USART2, ENABLE);
}
//串口打印
int fputc(int ch,FILE*f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART2, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
{}
return ch;
}
//串口打印(不用微包)
void usart_string(u8*str)
{
u8 index=0;
do
{
USART_SendData(USART2, str[index]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
index++;
}
while(str[index]!=0);
}
//RTC初始化
void rcc_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(39999);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//RTC时间实时刷新显示
void Time_Display(uint32_t TimeVar)
{
uint32_t THH = 0, TMM = 0, TSS = 0;
/* Reset RTC Counter when Time is 23:59:59 */
if (RTC_GetCounter() == 0x0001517F)
{
RTC_SetCounter(0x0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/* Compute hours */
THH = TimeVar / 3600;
/* Compute minutes */
TMM = (TimeVar % 3600) / 60;
/* Compute seconds */
TSS = (TimeVar % 3600) % 60;
if(THH==THH1)
{
if(TMM==TMM1)
{
if(TSS==TSS1)
{
printf("%1.2f+0.%1d+%0.2d%0.2d%0.2d\n",v1,k,THH1,TMM1,TSS1);
}
}
}
if(mode==1)
{
sprintf((char*)string,"T: %0.2d-%0.2d-%0.2d",THH, TMM, TSS);
LCD_DisplayStringLine(Line7 ,string);
}
//printf("Time: %0.2d:%0.2d:%0.2d\r", THH, TMM, TSS);
}
//写EEPROM
void w_04c02(unsigned char adess,unsigned char date)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(adess);
I2CWaitAck();
I2CSendByte(date);
I2CWaitAck();
I2CStop();
}
//读EEPROM
unsigned char r_04c02(unsigned char adess)
{
unsigned char temp;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(adess);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
temp=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return temp;
}
//ADC初始化
void ad_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* Enable ADC1 */
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));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
//读取ADC的值
float adc_read(void)
{
float ad_value=0;
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
ad_value=ADC_GetConversionValue(ADC1)*3.30/0xfff;
if(mode==1)
{
sprintf((char*)string,"V1:%1.2f",ad_value);
LCD_DisplayStringLine(Line1 ,string);
}
return ad_value;
}
.h文件
#ifndef __MYSOURCE_H
#define __MYSOURCE_H
#include "stm32f10x.h"
#include "i2c.h"
#include "stdio.h"
#include "lcd.h"
//初始化RTC时间
#define Tmp_HH 23
#define Tmp_MM 59
#define Tmp_SS 55
#define led1 GPIO_Pin_8
#define b1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define b2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
#define b3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define b4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)
//按键读出值
#define keyport b1|(b2<<1)|(b3<<2)|(b4<<3)|0xf0
void led_init(void);
void led_control( u8 data );
void key_init(void);
void key_scan(void);
void usart_init(void);
void usart_string(u8*str);
void rcc_init(void);
void Time_Display(uint32_t TimeVar);
void w_04c02(unsigned char adess,unsigned char date);
unsigned char r_04c02(unsigned char adess);
void ad_init(void);
float adc_read(void);
#endif
主函数
.c文件
#include "stm32f10x.h"
#include "lcd.h"
#include "mysource.h"
u32 TimingDelay = 0;
uint32_t THH1 = 0, TMM1 = 0, TSS1 =0;
/******key******/
u8 trg;
u8 cont;
u8 string[20];
__IO uint32_t TimeDisplay = 0;
float v1;
float vdd=3.3;
u8 k=1;
_Bool led_warn=0;
_Bool uart_flag=0;
_Bool shi=0;
_Bool fen=0;
_Bool miao=0;
u8 k_str;
void Delay_Ms(u32 nTime);
_Bool led_switch=1;
_Bool mode=1;
u8 i=0;
u8 j;
//Main Body
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SysTick_Config(SystemCoreClock/1000);
/* Configure one bit for preemption priority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
i2c_init();
ad_init();
usart_init();
rcc_init();
led_init();
key_init();
/*****************lcd_init***********************/
v1=adc_read();
k=r_04c02(0x01);
Delay_Ms(5);
sprintf((char*)string,"V1:%1.2f",v1);
LCD_DisplayStringLine(Line1 ,string);
sprintf((char*)string,"k:0.%1d",k);
LCD_DisplayStringLine(Line3 ,string);
LCD_DisplayStringLine(Line5 ,(unsigned char *)"LED:ON");
sprintf((char*)string,"T: %0.2d-%0.2d-%0.2d",23,59 ,55);
LCD_DisplayStringLine(Line7 ,string);
LCD_DisplayStringLine(Line9 ,(unsigned char *)" 1");
/*********************RTC_Time_adjust*************************/
/*****************eeporam*********************/
if(r_04c02(0x30)!=39)
{
Delay_Ms(5);
w_04c02(0x01,1);
Delay_Ms(5);
w_04c02(0x30,39);
}
led_control(0x00);//0000 0011
while(1)
{
if(TimeDisplay==1)
{
///*******************ADC******************/
Time_Display(RTC_GetCounter());
TimeDisplay=0;
v1=adc_read();
}
if(v1>(vdd*k*0.1))
{
led_warn=1 ;
}
else
{
led_warn=0;
}
// /*******************key_mode_switch**********************/
key_scan();
if(trg==0x01)
{
LCD_ClearLine(Line5);
led_switch=!led_switch;
if(led_switch)
{
LCD_DisplayStringLine(Line5 ,(unsigned char *)"LED:ON");
}
else
{
LCD_DisplayStringLine(Line5 ,(unsigned char *)"LED:OFF");
}
}
else if(trg==0x02)
{
mode=!mode;
LCD_Clear(Blue);
if(mode)
{
if(led_switch)
{
LCD_DisplayStringLine(Line5 ,(unsigned char *)"LED:ON");
}
else
{
LCD_DisplayStringLine(Line5 ,(unsigned char *)"LED:OFF");
}
sprintf((char*)string,"k:0.%1d",k);
LCD_DisplayStringLine(Line3 ,string);
}
}
else if(trg==0x04)
{
i++;
if(i==1)
{
shi=1;
fen=0;
miao=0;
}
if(i==2)
{ shi=0;
fen=1;
miao=0;
}
if(i==3)
{ shi=0;
fen=0;
miao=1;
i=0;
}
}
else if(trg==0x08)
{
if((shi==1)&&(fen==0)&&(miao==0))
{
THH1=THH1+1;
if(THH1>=24)
{
THH1=0;
}
}
if((shi==0)&&(fen==1)&&(miao==0))
{
TMM1=TMM1+1;
if(TMM1>=60)
{
TMM1=0;
}
}
if((shi==0)&&(fen==0)&&(miao==1))
{
TSS1=TSS1+1;
if(TSS1>=60)
{
TSS1=0;
}
}
}
// /*******************usart_r******************/
if(uart_flag)
{
uart_flag=0;
if(((k_str-0x30)>=1)&&((k_str-0x30)<=9))
{
k=k_str-0x30;
w_04c02(0x01,k);
Delay_Ms(5);
printf("ok\n");
}
sprintf((char*)string,"k:0.%1d",k);
LCD_DisplayStringLine(Line3 ,string);
// USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
///***************************usart_send******************/
// /**********************RTC**********************/
///**********************lcd show******************************/
if(mode)
{
}
else
{
LCD_DisplayStringLine(Line3 ,(unsigned char *)" Setting ");
if((shi==1)&&(fen==0)&&(miao==0))
{
LCD_DisplayStringLine(Line7 ,(unsigned char *)" ~~ ");
}
else if((shi==0)&&(fen==1)&&(miao==0))
{
LCD_DisplayStringLine(Line7 ,(unsigned char *)" ~~ ");
}
else if((shi==0)&&(fen==0)&&(miao==1))
{
LCD_DisplayStringLine(Line7 ,(unsigned char *)" ~~ ");
}
sprintf((char*)string," %0.2d-%0.2d-%0.2d ",THH1, TMM1, TSS1);
LCD_DisplayStringLine(Line6 ,string);
LCD_DisplayStringLine(Line9 ,(unsigned char *)" 2");
}
}
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
中断服务函数写在了stm32f10x_it.c里面
/**
******************************************************************************
* @file I2S/SPI_I2S_Switch/stm32f10x_it.c
* @author MCD Application Team
* @version V3.5.0
* @date 08-April-2011
* @brief Main Interrupt Service Routines.
* This file provides template for all exceptions handler and peripherals
* interrupt service routine.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
u8 cont1=0;
extern u32 TimingDelay;
extern __IO uint32_t TimeDisplay;
extern _Bool led_warn;
extern _Bool uart_flag;
extern _Bool mode;
extern u8 k_str;
extern _Bool led_switch;
extern void led_control( u8 data );
u8 time=0;
u8 right=0;
u8 flag=0;
u8 led_kai=1;
/** @addtogroup STM32F10x_StdPeriph_Examples
* @{
*/
/** @addtogroup I2S_SPI_I2S_Switch
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/******************************************************************************/
/* Cortex-M3 Processor Exceptions Handlers */
/******************************************************************************/
/**
* @brief This function handles NMI exception.
* @param None
* @retval None
*/
void NMI_Handler(void)
{
}
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{}
}
/**
* @brief This function handles Memory Manage exception.
* @param None
* @retval None
*/
void MemManage_Handler(void)
{
/* Go to infinite loop when Memory Manage exception occurs */
while (1)
{}
}
/**
* @brief This function handles Bus Fault exception.
* @param None
* @retval None
*/
void BusFault_Handler(void)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{}
}
/**
* @brief This function handles Usage Fault exception.
* @param None
* @retval None
*/
void UsageFault_Handler(void)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{}
}
/**
* @brief This function handles Debug Monitor exception.
* @param None
* @retval None
*/
void DebugMon_Handler(void)
{
}
/**
* @brief This function handles SVCall exception.
* @param None
* @retval None
*/
void SVC_Handler(void)
{
}
/**
* @brief This function handles PendSV_Handler exception.
* @param None
* @retval None
*/
void PendSV_Handler(void)
{
}
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
TimingDelay--;
if(mode)
{
if(led_warn)
{
if(led_switch)
{
if(++time==200)
{
time=0;
if(led_kai)
{
led_control(0x01);
led_kai=0;
}
else
{
led_control(0x00);
led_kai=1;
}
}
}
else
{
led_control(0x00);
}
}
else
{
led_control(0x00);
}
}
else{
led_control(0x00);
}
}
void USART2_IRQHandler(void)
{
uint8_t temp;
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET){
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
temp = USART_ReceiveData(USART2);
if((temp=='k')||(temp=='K'))
{
flag++;
right=1;
}
else if(right==1)
{
flag++;
if(flag==2)
{
if(temp!='0')
{right=0;
flag=0;
}
}
if(flag==3)
{
if(temp!='.')
{right=0;
flag=0;
}
}
if(flag==4)
{
k_str=temp;
right=0;
flag=0;
uart_flag=1;
}
}
}
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
/* Enable time update */
TimeDisplay = 1;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
//void TIM2_IRQHandler(void)
//{
// if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
// {
// TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
//}
// }
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handler's name please refer to the startup */
/* file (startup_stm32f10x_xx.s). */
/******************************************************************************/
/**
* @brief This function handles PPP interrupt request.
* @param None
* @retval None
*/
/*void PPP_Switch_IRQHandler(void)
{
}*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
需要完整工程可评论留下邮箱