第十一届蓝桥杯嵌入式组别底层驱动程序-标准板

  1. main.c

#include "project.h"

float ADC_Dat = 0;

//Main Body
int main(void)
{
	uint8_t i = 0;
	SysTick_Config(SystemCoreClock/1000);
	KEY_Init();
	LED_Init();
	BEEP_Init();
	i2c_init();
	USART2_Init();
	Timer_Init(1000,72);//1ms
	RTC_Init(23,59,55);
	ADC1_Init();
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	while(1)
	{
		LED_Control(LED_All,1);//全灭
		RTC_Display();//时钟显示
		if(KeyScan_flag)//按键扫描间隔
		{
			KEY_Conrtol();
			KeyScan_flag= 0;
		}
		sprintf((char *)str, "     %d    ", num);
		
		LCD_DisplayStringLine(Line5, str);
		ADC_Dat = Get_ADC()/4095.0*3.3;	//显示adc值
		
		Wire_EEPORM(1,ADC_Dat*10.0);	//存eeprom
		sprintf((char *)str, " ADC:   %0.1fV   ", ADC_Dat);	//显示adc值
		LCD_DisplayStringLine(Line6, str);
		sprintf((char *)str, " num_dat:   %0.1f    ", num_dat/10);//显示eeprom读取的数据
		LCD_DisplayStringLine(Line1, str);
		num_dat = Read_EEPROM(1);	//读取eeprom
		
		if(RxdOver)//上位机发给单片机
		{
			RxdOver = 0;
			num ++;
			sprintf((char *)str, "   数字:  %d  \r\n  ", num);//显示数字并发送给上位机
			USART2_SendString(str);//单片机发送数据给上位机
			LCD_ClearLine(Line5);//清除LCD的对应行
			LCD_DisplayStringLine(Line3, RxdBuf);
			USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//接收的数据处理完毕后打开接收中断
			for(i=0; i<20; i++)//清空缓冲区
				RxdBuf[i] = 0;
		}
	}
}

  1. project.c

#include "project.h"

uint8_t str[20];
uint8_t num = 0;
uint8_t KeyScan_flag = 0;
s32 BeepTimer = 0;
u32 TimingDelay = 0;
float num_dat = 0,num_s = 0;
uint8_t RTC_Flag= 0;
/**********************/
u8 RxdCnt = 0;
u8 RxdOver = 0;
u8 RxdBuf[20];
/**********************/
//
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

  1. project.h

#ifndef __PROJECT_H__
#define __PROJECT_H__

#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_can.h"
#include "stm32f10x_cec.h"
#include "stm32f10x_crc.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_dbgmcu.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_iwdg.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_sdio.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_it.h"
#include "misc.h"
#include "timer.h"
#include "key.h"
#include "beep.h"
#include "lcd.h"
#include "led.h"
#include "rtc.h"
#include "adc.h"
#include "i2c.h"
#include "eeprom.h"
#include "stdio.h"	//sprintf函数在这个里面。。。。。。。。bug
#include "uart.h"

void Delay_Ms(u32 nTime);
extern uint8_t num;
extern uint8_t KeyScan_flag ;
extern s32 BeepTimer;
extern uint8_t str[20];
extern uint8_t RTC_Flag;
extern float num_dat,num_s;
/**************************/
extern u8 RxdCnt;
extern u8 RxdOver;
extern u8 RxdBuf[20];
/***************************/
#endif

  1. key.c

#include "project.h"

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_Speed = GPIO_Speed_10MHz;
	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);
}

uint8_t KEY_Scan(void)
{
	static uint8_t key_clear = 0;  
	static uint8_t key_state = 0;
	uint8_t key_value = 0xff;
	if(B1 == 0 || B2 == 0 || B3 == 0 || B4 == 0)
	{
		key_clear++;
		if(key_clear >= 40)
		{
			key_state  = 1;	//长按
			key_clear = 2+1;//防止再进入短按
		}
		if(key_state == 1)
		{
			if(B1 == 0)key_value = '5';
			if(B2 == 0)key_value = '6';
			if(B3 == 0)key_value = '7';
			if(B4 == 0)key_value = '8';
		}
		else if(key_clear == 2)//短按
		{
			if(B1 == 0)key_value = '1';
			if(B2 == 0)key_value = '2';
			if(B3 == 0)key_value = '3';
			if(B4 == 0)key_value = '4';
		}
	}
	else 
	{
		key_state = 0;
		key_clear = 0;
	}
	return key_value;
}

void KEY_Conrtol(void)
{
	static uint8_t key_temp;
	key_temp = KEY_Scan();
	switch(key_temp)
	{
		case '1': num = 1;Beep(100);break;
		case '2': num = 2;Beep(100);break;
		case '3': num = 3;Beep(100);break;
		case '4': num = 4;Beep(100);break;
		
		case '5': num = 5;break;
		case '6': num = 6;break;
		case '7': num = 7;break;
		case '8': num = 8;break;
	}
	key_temp = 0;
}

  1. key.h

#ifndef __KEY_H__
#define __KEY_H__

#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)
void KEY_Conrtol(void);
void KEY_Init(void);

#endif

  1. Beep.c

#include "project.h"

void BEEP_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用IO口时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE); //PB4引脚的重映射成普通GPIO

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void BEEP_Sacn(uint8_t ms)
{
	if(BeepTimer > 0)
	{
		BeepTimer -= ms;
		if(BeepTimer <= 0)
		{
			BEEP_OFF();
			BeepTimer = 0;
		}
	}
}
void Beep(s32 time)
{
	BeepTimer = time;
	if(BeepTimer == 0)BEEP_OFF();
		else	BEEP_ON();
}


  1. Beep.h

#ifndef __BEEP_H__
#define __BEEP_H__

#define  BEEP_ON() GPIO_ResetBits(GPIOB ,GPIO_Pin_4)
#define  BEEP_OFF() GPIO_SetBits(GPIOB ,GPIO_Pin_4)

void BEEP_Init(void);
void Beep(s32 time);
void BEEP_Sacn(uint8_t ms);
 
#endif

  1. uart.c

#include "project.h"

void USART2_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;	//中断初始化结构体
	GPIO_InitTypeDef GPIO_InitStructure;	//GPIO引脚初始化结构体
	USART_InitTypeDef USART_InitStructure;	//串口初始化结构体
		
	//开启GPIOA和USART2时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//串口时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);//时钟复用,,,,bug
										//-IO时钟的使用需要用到外设的重映射功能时才需要使能AFIO的时钟
	//USART2的中断向量配置
	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);								//配置好之后初始化
	
	//RXD-PA3 设置为浮空模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;					//A3串口引脚初始化
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//TXD-PA2 设置为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;					//A2串口引脚初始化
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;				//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//USART2的配置
	USART_InitStructure.USART_BaudRate = 9600;					//置串口通信时的波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//字长为 8 位数据格式
	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_Cmd(USART2, ENABLE);//开启USART2
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启USART2接收中断
	
}

void USART2_SendString(u8 *str)
{
	u8 index = 0;//数组位数
	
	while(str[index++] != 0)
	{
		USART_SendData(USART2, str[index]);//发送数据调用函数
		while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == 0);//等待发送发送完成
	}
}


void USART2_IRQHandler(void)
{
	u16 tmp;
	
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == 1)
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);//中断用IT
		tmp = USART_ReceiveData(USART2);
		if(tmp == 'n')
		{
			RxdBuf[RxdCnt-1] = 0;//避免\r显示在LCD发生的乱码
			RxdCnt = 0;
			RxdOver = 1;
			USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//接收完毕后关闭,防止处理过程发生干扰。
		}
		else
		{
			RxdBuf[RxdCnt++] = tmp;
		}
	}
}

  1. uart.h

#ifndef __UART_H__
#define __UART_H__

void USART2_Init(void);
void USART2_SendString(u8 *str);
#endif

  1. timer.c

#include "project.h"

void Timer_Init(uint16_t arr,uint16_t psc)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

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

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//开启定时器更新中断
	TIM_Cmd(TIM4, ENABLE);
}


  1. timer.h

#ifndef __TIMER_H__
#define __TIMER_H__

void Timer_Init(uint16_t arr,uint16_t psc);
#endif

  1. rtc.c

#include "project.h"

void RTC_Init(uint16_t HH,uint16_t MM,uint16_t SS)
{
		NVIC_InitTypeDef NVIC_InitStructure;
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

		NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
	
		PWR_BackupAccessCmd(ENABLE);
		BKP_DeInit();
		RCC_LSICmd(ENABLE);
		while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
		RCC_RTCCLKCmd(ENABLE);
		RTC_WaitForSynchro();
		RTC_WaitForLastTask();
		RTC_ITConfig(RTC_IT_SEC, ENABLE);
		RTC_WaitForLastTask();
		RTC_SetPrescaler(40000-1);
		RTC_WaitForLastTask();

		RTC_SetCounter(HH * 3600 + MM * 60 + SS);//设置RTC时间
		RTC_WaitForLastTask();

}

void RTC_Display(void)
{
	static uint32_t time = 0;
	static uint8_t hour, min, sec;
	if(RTC_Flag)
	{
		
		RTC_Flag = 0;
		time = RTC_GetCounter();
		RTC_WaitForLastTask();
		
		if(time == (23 * 3600 + 59 * 60 + 60))
		{
			RTC_SetCounter(0);
			RTC_WaitForLastTask();
			sprintf((char *)str, " Timer:  %.2d:%.2d:%.2d   ",00,00,00);
			LCD_DisplayStringLine(Line9, str);
		}
		else
		{
			hour = time / 3600;
			min = time % 3600 / 60;
			sec = time % 3600 % 60;
			sprintf((char *)str, " Timer:  %.2d:%.2d:%.2d   ", hour, min, sec);
			LCD_DisplayStringLine(Line9, str);
		}			
	}
}

void RTC_IRQHandler(void)
{
  if (RTC_GetITStatus(RTC_IT_SEC) == 1)
  {
	RTC_Flag = 1;
    RTC_ClearITPendingBit(RTC_FLAG_SEC);
  }
}


  1. rtc.h

#ifndef __RTC_H__
#define __RTC_H__

void RTC_Init(uint16_t HH,uint16_t MM,uint16_t SS);
void RTC_Display(void);
#endif 

  1. adc.c

#include "project.h"

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_CR1位8:SCAN位 
		ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//单次转换OR连续转换:ADC_CR2的位1:CONT
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//触发方式:ADC_CR2的位[19:17] :EXTSEL[2:0]  触发软件           
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//对齐方式:左对齐还是右对齐:ADC_CR2的位11:ALIGN   
		ADC_InitStructure.ADC_NbrOfChannel = 1;//规则通道序列长度:ADC_SQR1的位[23:20]: L[3:0]   顺序进行规则转换的ADC通道的数目
		ADC_Init(ADC1, &ADC_InitStructure);

		ADC_Cmd(ADC1, ENABLE);
		ADC_ResetCalibration(ADC1);
		while(ADC_GetResetCalibrationStatus(ADC1));
		ADC_StartCalibration(ADC1);
		while(ADC_GetCalibrationStatus(ADC1));
}

uint16_t Get_ADC(void)
{
	uint16_t temp = 0;
	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);//转换时间239.5个周期
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0);//等待转换完成
	temp = ADC_GetConversionValue(ADC1);//获取转换结果(读取转换结果会自动清0-EOC标志位)
	ADC_SoftwareStartConvCmd(ADC1, DISABLE);//启动下一次软件转换
	return temp;
}	

  1. adc.h

#ifndef __ADC_H__
#define __ADC_H__

void ADC1_Init(void);
uint16_t Get_ADC(void);

#endif


#include “stm32f10x_it.h”

#include "project.h"
extern u32 TimingDelay;

void SysTick_Handler(void)
{
	
	TimingDelay--;

}

void TIM4_IRQHandler(void)	//2ms
{
	static u8 num_20ms=1;
	  if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
	  {
			TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
			BEEP_Sacn(2);
	  }
  	if(++num_20ms >= 10)
	{
	 	num_20ms = 0;
		KeyScan_flag = SET;
	}
 
}


  1. led.c

#include "project.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD,ENABLE);//使能GPIOB时钟

	GPIO_InitStructure.GPIO_Pin = LED_All;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void LED_Control(uint16_t led,uint8_t mode)
{
	if(mode == 0)//liang
	{
		GPIO_ResetBits(GPIOC,led);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	}
	else //mie
	{
		GPIO_SetBits(GPIOC,led);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	}
}

  1. led.h

#ifndef __LED_H__
#define __LED_H__

#define LED1 GPIO_Pin_8
#define LED2 GPIO_Pin_9
#define LED3 GPIO_Pin_10
#define LED4 GPIO_Pin_11
#define LED5 GPIO_Pin_12
#define LED6 GPIO_Pin_13
#define LED7 GPIO_Pin_14
#define LED8 GPIO_Pin_15
#define LED_All GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15

void LED_Control(uint16_t led,uint8_t mode);
void LED_Init(void);

#endif

你可能感兴趣的:(#,嵌入式)