突击蓝桥杯嵌入式(五)——EEPROM、RTC时钟、PWM输出和捕获和点灯改进版

突击蓝桥杯嵌入式(五)——EEPROM、RTC时钟、PWM输出和捕获和点灯改进版

一、PWM捕获频率和占空比

PWM捕获,首先我们看新板子上的2个信号发生器 分别占用PB4和PA15

在这里插入图片描述

然后我们配置CUBEMX,先选中PB4,TIM_CH1.
在这里插入图片描述

然后左面选择定时器3,选择PWM Input on CH1,时钟源选择内部时钟

在这里插入图片描述

配置预分频,然后开启定时器3终端。

在这里插入图片描述

然后配置时钟80MHZ,生成代码,然后我们介绍一下怎么获取占空比和频率。

先开启中断:

	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);

然后请上我们的主角

__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); //捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	static uint32_t ic1_value;
	static uint32_t ic2_value;
	if(htim->Instance == htim3.Instance)	//当触发定时器3时
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)//通道一
		{
			ic1_value = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1);
			feq_r39 = 1000000/ic1_value;
			HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
		}
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)//通道二
		{
			ic2_value = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2);
			duty_r39 = ic2_value*100/ic1_value;
			HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
		}
	}
}

二、点灯改进版

void LED_Disp(uint8_t uc_led)	//uc_led 对应灯的位数,例如0x55就是让第0 2 4 6号灯亮起 0101 0101 
{
	HAL_GPIO_WritePin(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_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,uc_led<<8,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	
}

三、RTC时钟

CUBE配置,开启时钟,选中RTC时钟,然后将上面2个都勾选,之后填入年份日期等信息

在这里插入图片描述
时钟树配置
在这里插入图片描述

//定义接受变量
RTC_TimeTypeDef TIME;
RTC_DateTypeDef DATE;
void RTC_Proc()
{
	if(uwTick - uwtickRTC_Speed < 100) return;
	else uwtickRTC_Speed = uwTick;
	HAL_RTC_GetTime(&hrtc,&TIME,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc,&DATE,RTC_FORMAT_BIN);
}
//之后调用结构体就可以取出数值
void LCD_Proc()
{
	sprintf((char *)str," %d.  %d.  %d  ",DATE.Year,DATE.Month,DATE.Date);
	LCD_DisplayStringLine(Line3,str);
	sprintf((char *)str," %d.  %d.  %d  ",TIME.Hours,TIME.Minutes,TIME.Seconds);
	LCD_DisplayStringLine(Line4,str);
}

四、EEPROM

EEPROM分为以下几步:

1.添加i2c文件

资料包里有,把i2c_hal.c放到工程Core里面的Src,把i2c_hal.h放到Inc里面。

2.配置CUBEMX

把PA6PA7设置成output模式。

3.进入工程,

添加i2c_hal.c,写头文件,准备写代码。

4.写代码

首先我们要编写i2c_write和i2c_read函数。

void i2c_write(u8 add ,u8 reg ,u8 data)	
{
//写 参数是设备地址和寄存器地址,以及要存的数据。
	I2CStart();
	
	I2CSendByte(add);
	I2CWaitAck();
	
	I2CSendByte(reg);
	I2CWaitAck();
	
	I2CSendByte(data);
	I2CWaitAck();
	
	I2CStop();
	
}
uint8_t i2c_read(u8 add ,u8 reg)
{
//读取,参数是设备地址和寄存器地址
	u8 data ;
	I2CStart();
	I2CSendByte(add);
	I2CWaitAck();
	
	I2CSendByte(reg);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(add+1);
	I2CWaitAck();
	data =I2CReceiveByte();
	I2CWaitAck();

	I2CStop();
	return data;
}

这两个函数使用之后,尽量延时5ms,不然会发现蜜汁bug。

下面来个例子,将ab的值保存下来,并在启动的时候赋值给flag,先来个定义。

uint8_t flag=0;
uint8_t ab;
//然后写一个IIC的子程序:每过1s把ab的值+1,并存到eeprom中。
void I2C_Proc()
{
	if(uwTick - uwtickCnt_Speed < 1000) return;
	else	uwtickCnt_Speed = uwTick;
	ab++;
	i2c_write(0xa0,1,ab);
	HAL_Delay(5);			//注意这个延时!
}
//初始化,然后读取存储的值。
	I2CInit();
	flag = i2c_read(0xa0,1);
	HAL_Delay(5);

之后我们可以写一个LCD显示程序,就可以看到现象了。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路人甲YYH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值