#题目
一、应用模块
通过按键实现不同界面的切换,通过E2PRON实现数据的保存,通过串口实现PC端数据传输,通过定时器产生PWM。
二、各点突破
1.响应刷新时间
代码如下(示例):定时器刷新响应时间快,可以同时刷新多个事件,编程简单。
u8 Timers[4];//储存事件的数组
int main(void)
{
TIM4_Int_Init(50000,72);//定时器初始化
while(1)
{
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,操作更方便哦