蓝桥杯-嵌入式-旧版

这篇博客详细介绍了如何在STM32平台上实现PWM波形生成、EEPROM数据存储、按键长短检测以及LCD显示屏的高亮显示。通过实例代码展示了如何配置PWM定时器实现稳定波形输出,使用I2C初始化EEPROM进行数据保存,以及处理按键的短按和长按事件。同时,讲解了LCD显示屏的字符定位和高亮显示技巧,为嵌入式开发提供了实用的参考。
摘要由CSDN通过智能技术生成

蓝桥杯

  • 问题
  • 推荐博主

1.问题:

  • led

  • pwm

  • eeprom

  • LCD高亮显示

  • key长短按键

1、PWM

pwm 不能一直发, 一直发出来的波形是杂波。 可以总滴答定时器,用标志位,到100刷新一次。出来的波形很完美。

#include "pwm.h"

void Pwm_Init(u8 state,u8 ch1_en,u8 ch2_en)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	if(state)
	{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	}

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	if(ch1_en)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	else
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

  /* Output Compare Toggle Mode configuration: Channel2 */
  if(ch2_en)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	else
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
	
	TIM_Cmd(TIM3, ENABLE);
  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
}

/**
  * @brief  This function handles TIM3 global interrupt request.
  * @param  None
  * @retval None
  */
u8 PA6_flag = 0;
u8 PA7_flag = 0;
void TIM3_IRQHandler(void)
{

	uint16_t capture = 0;
  /* TIM3_CH1 toggling with frequency = 100 Hz */
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
    capture = TIM_GetCapture1(TIM3);
		if(PA6_flag)
			TIM_SetCompare1(TIM3, capture + 10000/100 * A6Duty);
		else
			TIM_SetCompare1(TIM3, capture + 10000/100 * (100 - A6Duty));
			PA6_flag = !PA6_flag;
  }

  /* TIM3_CH2 toggling with frequency = 200 Hz */
  if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    capture = TIM_GetCapture2(TIM3);
    if(PA7_flag)
			TIM_SetCompare2(TIM3, capture + 5000/100 * A7Duty);
		else
			TIM_SetCompare2(TIM3, capture + 5000/100 * (100 -A7Duty));
		PA7_flag = !PA7_flag;
  }
}
void SysTick_Handler(void)
{
	static u16 led_sum=0,key_sum=0,adc_sum=0,display_sum=0,output_sum=0;
	TimingDelay--;


	if(++output_sum==1000)
	{
		output_sum=0;
		output_flag=1;
	}
}
2、eeprom
在主程序中要调用i2c_Init();
3、KEY长短按键
void KEY2_control(void)
{
	if(KEY2 == 0)
	{
		Key_Flag = 1; 
		//Delay_Ms(10);
		while(!KEY2);
		if(key_Value >= 800)   
		{
			key_Long = 1;
			key_Value=0;
			Key_Flag = 0;
		}
		else if(key_Value < 800 && key_Value >= 10)
		{
			Key2_Flag++;
			key_Value=0;
			Key_Flag = 0;
		}
	}
}

中断函数

void TIM4_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM4, TIM_IT_Update))
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
		
		if(Key_Flag == 1)
		{
			key_Value++;
		}
		
	}
}
4.LCD高亮显示

这个函数有三个参数。
第一个参数是行选择。
第二个参数是列选择。由于官方没有给出每一列的宏定义,所以需要我们自己推一下。这里列选择需要了解一下我们这个lcd的分辨率。在官方给的参考资料里面介绍了分辨率是240RGBx320,我们知道我们的lcd一共分为10行,20列,所以一个字符的高实际上是24*16,所以我们可以看到lcd.h宏定义里面每一行之间的差值就是24,那么每一列之间的差值就是16啦,实际上表示一列的时候是反着来的,320表示第一列,320-16表示第二列,那么320-(16 * i)表示第i列。
第三个参数就是我们需要显示的字符了。下面举一个例子:

void highlight(uint8_t *str,uint8_t pos)
{
	int i = 0;
	LCD_SetBackColor(Yellow);
	//LCD_SetTextColor(Red);
	LCD_DisplayChar(Line4,(320 - (16 * pos)),str[pos]);
	LCD_DisplayChar(Line4,(320 - (16 * (pos + 1))),str[pos + 1]);
	LCD_SetBackColor(White);	
	//LCD_SetTextColor(Blue2);
	for(i = 0; i <= 19; i++)
	{
		if(i != pos && i != pos + 1)
			LCD_DisplayChar(Line4,(320 - (16 * i)),str[i]);
	}
}

推荐博主

开拓新世界
https://blog.csdn.net/weixin_51914919/article/details/123428512

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

VersionVersion

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

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

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

打赏作者

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

抵扣说明:

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

余额充值