第十三届——蓝桥杯嵌入式第二场


#题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、应用模块

通过按键实现不同界面的切换,通过E2PRON实现数据的保存,通过串口实现PC端数据传输,通过定时器产生PWM。

二、各点突破

1.响应刷新时间

代码如下(示例):定时器刷新响应时间快,可以同时刷新多个事件,编程简单。

u8  Timers[4];//储存事件的数组
int main(void)
{
TIM4_Int_Init(50000,72);//定时器初始化
 while1{
		if(xDelay(0,1)==1)//0号事件每1*50ms=50ms刷新一次
		{			
			//执行的事件。
			
		}
		if(xDelay(1,2)==1)//1号事件每2*50ms=100ms刷新一次
		{			
			//执行的事件。
			
		}
		if(xDelay(2,1)==1)//2号事件每3*50ms=150ms刷新一次
		{			
			//执行的事件。
			
		}
		if(xDelay(3,1)==1)//3号事件每4*50ms=200ms刷新一次
		{			
			//执行的事件。
			
		}
	}
}
void TIM4_Int_Init(u16 arr,u16 psc)
  {
     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
     NVIC_InitTypeDef NVIC_InitStructure;

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
     //定时器TIM4初始化
     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
     TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断
 
     //中断优先级NVIC设置
     NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM3中断
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级3级
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
     NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
 

     TIM_Cmd(TIM4, ENABLE); //使能TIMx
 }
 
uint8_t xDelay(uint8_t xIndex,uint8_t xTime)// 响应事件:xIndex,响应时间:xTime
{
	uint8_t RetValue=0;

	if(Timers[xIndex]==0)//判断指定软件定时器的计数器是否为 0
	{
		Timers[xIndex]=xTime;//得装计数器的值
		RetValue=1;	//时间到到标志位 
	}
	return(RetValue);
}
 void TIM4_IRQHandler(void) 
{
	

      static uint8_t Index;
     if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) 
   {
         TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); 
  				  for(Index=0;Index<RefreshEvent;Index++)
						if(Timers[Index]>0)
						Timers[Index]--;
		 //进入定时器中断每一个响应事件都会减少一个50ms
	
  }

}

2.E2PRON

代码如下(示例):题目上电显示初始化。如果一上电就读取E2PRON,我们无法知道官方板子储存数据是什么,读出数据还有进行判断,在给他赋值。于是我换了一个思路,利用E2PRON其他位来判断,E2PRON0到3位是否是我储存的数据。
解决方法:上电判断第一次判断第6位和第7位是否储存6和7。是读取E2PRON0到3位并显示。否,将初始数据保存到E2PRON0到3位,并在第6位和第7位储存6和7。

int main(void)
{
if(i2c_read(0x05)==6&&i2c_read(0x06)==7)
 {
     Xkuce=i2c_read(0x00);
	 Ykuce=i2c_read(0x01);
	 Xjiage=(float)i2c_read(0x02)/10; 
	 Yjiage=(float)i2c_read(0x03)/10;
 } 

	while(1)
	{ 
    	if(xDelay(2,1)==1)
		{
				 if(Xkuce!=Xkuce_temp)
				 {			 
				 i2c_write(0x00,Xkuce);
					 Xkuce_temp=Xkuce;
				 }
				 if(Ykuce!=Ykuce_temp)
				 {
				 i2c_write(0x01,Ykuce);
					 Ykuce_temp=Ykuce;
				 }
				 if(Xjiage!=Xjiage_temp)
				 {
					 Xjiage_temp1=Xjiage*10;
				 i2c_write(0x02,Xjiage_temp1);
					 Xjiage_temp=Xjiage;
				 }
				 if(Yjiage!=Yjiage_temp)
				 {
					  Yjiage_temp1=Yjiage*10;
				 i2c_write(0x03,Yjiage_temp1);
					Yjiage_temp=Yjiage;		 
				 }	
				i2c_write(0x05,6); 
				i2c_write(0x06,7);
				 
		}	
    }
}


3.三行按键

代码如下(示例):三行按键是通过异或实现的按键,无阻塞延时。方便又好用。

#ifndef _KEY_H
#define _KEY_H


#include "stm32f10x.h"

#define				B1								0x01
#define				B2								0x02
#define				B3								0x04
#define				B4								0x08

#define				KEY_STATE_GET			GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) << 0 | \
																GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) << 1 | \
																GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) << 2 | \
																GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2) << 3;

extern uint8_t key_state;
extern uint8_t key_falling;
extern uint8_t key_rising;

void Key_Init(void);
void Key_refresh(void);


#endif 
#include "key.h"


uint8_t key_state = 0;
uint8_t key_falling = 0;
uint8_t key_rising = 0;



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_Init(GPIOB, &GPIO_InitStructure);
}

void Key_refresh(void)
{
	uint8_t key_temp = 0xF0;
	key_temp |= KEY_STATE_GET;
	key_temp ^= 0xFF;
//	key_falling = key_temp & (key_state ^ key_temp);
	key_rising = (!key_state) * (key_temp ^key_state);
	key_state = key_temp;
}

在这里插入图片描述

总结

链接:https://pan.baidu.com/s/1YFieWqTmYNh52e-3I_NqvQ?pwd=abds
提取码:abds
复制这段内容后打开百度网盘手机App,操作更方便哦

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值