【蓝桥杯嵌入式备赛】2.快速编写LED驱动及闪烁不受控制问题解决(流水灯的一种思路)

第一个例程

参考
STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\GPIO\IOToggle

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

LED点亮

蓝桥杯板子LED和LCD的引脚共用,所以为了解决冲突加入了一个锁存器,所以只有LE引脚即D2拉高才能更改LED寄存器的值。所以需要操作时候要 先拉高D2再操作最后拉低D2锁存。
在这里插入图片描述

LED闪烁不受控制

这是由于LED引脚和LCD共用引起的,LCD在操作过程中会引起LED寄存器值更改,一种简单的方法是在写函数开头用变量保存LED寄存器的数值,执行完后再恢复。
在这里插入图片描述
在这里插入图片描述
三个函数添加这三句代码即可。

LED实现流水灯效果

写一个移位函数,传入参数为移位的位数。在while内调用移位位数加减和延时即可实现。这里演示延时直接用的delay函数,实际并不建议这样。可以考虑用定时器进行延时。

#include "stm32f10x.h"
#include "lcd.h"
#include "led.h"

void delay_ms(u32 nTime);
static __INLINE uint32_t SysTick_Config1(uint32_t ticks);

int main(void)
{
	u8 i=1;
	SysTick_Config1(SystemCoreClock/1000);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	STM3210B_LCD_Init();
	LED_Init();

	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line4 ,(unsigned char *)"    Hello,world.   ");

//	LED_flow(1);

	while(1)
	{
		while(1)
		{
			if(i==9)	i=1;	
			LED_flow(i);
			delay_ms(50);
			i++;
		}
	}
}

static __INLINE uint32_t SysTick_Config1(uint32_t ticks)
{ 
  if (ticks > SYSTICK_MAXCOUNT)  return (1);                                             /* Reload value impossible */

  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;                                      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, 1);                            /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   =  (0x00);                                                              /* Load the SysTick Counter Value */
  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                                            /* Function successful */
}

另一种方法使用定时器标志位(不占用资源)
在这里插入图片描述

代码

#ifndef _LED_H_
#define _LED_H_

#include "stm32f10x.h"

#define	  ledall   GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15
#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


void LED_Init(void);
void LED_Show(u16 led,u8 state);
void LED_flow(u8 n);

#endif

上面进行了LED进行预编译使操作更方便

#include "led.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = ledall;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIO_SetBits(GPIOC,ledall);
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}

void LED_Show(u16 led,u8 state)
{
	if(state==0)
	{
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_ResetBits(GPIOC,led);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	}
	else
	{
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_SetBits(GPIOC,led);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);	
	}
}

void LED_flow(u8 n)
{
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIOC->ODR |= 0xff00;
	GPIOC->ODR &= ~(0x01<<(7+n));
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);	
}

常见错误

1.未添加自己写的.c文件到工程
报错:
在这里插入图片描述
解决:
在这里插入图片描述
2.添加了中断分组库函数但是报错
在这里插入图片描述
解决:
在这里插入图片描述
如果其它函数需要用到也要取消注释

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值