2019蓝桥杯嵌入式寒假学习记录(1)LED与SysTick
为了有一个好的展示特地去学了一下如何用Markdonw写博客,因为有以前的基础昨天搞了搞软件然后上网搜了一下关于LED的代码看了看,自己打了一遍很快就成功实现了,但是昨天不太顺利的事我打开keil4的时候总是要打开很多次才能成功,最后都成功打开了我就没在意,可是今天打开了一两次之后就完全打不开了,上网上搜了搜原来keil5和keil4它们之间的兼容有问题,我就把他们两个全卸了,重新装了keil4,然后打开工程就没问题了。
GPIO-LED
学习32接触的第一个外设就是GPIO(GPIO其实和51中的P1...那些引脚差不多,不过只是功能复杂了一些),LED是通过GPIO控制最简单的一个,当灯成功的亮起来还是会带来一些成就感的。
观看原理图可知LED0到7对应的32上的引脚为PC8-15,但是要注意它是通过74h573锁存芯片连接起来的其中,片选端NLE的引脚为PD2,只有NLE为高电平LED才能接收到GPIO发来的高低电平
代码编写
led.c
-----------------------------------------------------------------------------
#include"led.h"
void LED_Config()
{
//定义一个GPIO结构体
GPIO_InitTypeDef GPIO_InitStructure;
//打开与LED相关的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2 ; //选择控制GPIO引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //引脚设为通用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚速录为50MHZ
GPIO_Init(GPIOD,&GPIO_InitStructure); //调用库函数,初始化GPIO
GPIO_InitStructure.GPIO_Pin=LEDALL; //选择控制GPIO引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //引脚设为通用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚速录为50MHZ
GPIO_Init(GPIOC,&GPIO_InitStructure); //调用库函数,初始化GPIO
}
void LED_Control(u16 LED,u8 state ) //LED点亮控住函数
{
if(state==1) //点亮led
{
GPIO_ResetBits(GPIOC,LED); //共阳极接法低电平点亮
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
if(state==0) //熄灭led
{
GPIO_SetBits(GPIOC,LED);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
if(state==2) //闪烁led
{
change;
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
void LED_Init(void)
{
LED_Config(); //初始化GPIO
LED_Control(LEDALL,0); //初始化LED状态
}
led.h
------------------------------------------------------------------------------
#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
#define off 0
#define on 1
#define toggle 2
#define LEDChange(p,i) {p->ODR ^=i;} //操作寄存器,具体可以参考手册GPIOODR
#define change LEDChange(GPIOC,LED1)
void LED_Config(void); //设置GPIO
void LED_Init(void); //初始化led
void LED_Control(u16 LED,u8 state); //led状态控制
#endif
SysTick-系统定时器
SysTick属于内核的外设,内嵌在NVIC中,在文件core_cm3.h中。系统定时器是一个24bit的向下递减的计数器,计数器每次计数一次的时间为1/sysclk,一般sysclk为AHB总线时钟为72M。SysTick有4个寄存器,CTRL为SysTick控制及状态寄存器,LOAD为Systick重装载数值寄存器,VAL为SysTick当前数值寄存器,CALIB为SysTick当前校准寄存器,详细寄存器的设置可以查阅手册。
代码编写
SysTick.c
------------------------------------------------------------------------------------
#include"SysTick.h"
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/
if (SysTick_Config1(SystemCoreClock / 1000)) // ST3.5.0库版本
{
while (1);
}
}
static __INLINE uint32_t SysTick_Config1(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* MSK为2^24,判断输入的tick值是否小于2^24 */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* 装载初始值 */
NVIC_SetPriority (SysTick_IRQn, (1<<4 - 1)); /* 设置内核中NVIC的Systick优先级为15,BIT为5,1<<4-1,1111为15 */
SysTick->VAL = 0; /*设置为当前数值*/
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | /*设置系统定时器时钟源为AHBCLK=72M*/
SysTick_CTRL_TICKINT_Msk | /*使能系统定时器中断*/
SysTick_CTRL_ENABLE_Msk; /* 使能定时器 */
return (0);
}
void Delayms( __IO uint32_t ms)
{
uint32_t i;
SysTick_Config1(SystemCoreClock/1000);
for(i=0;i<ms;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
-----------------------------------------------------------------------------------
SysTick.h
-----------------------------------------------------------------------------------
#ifndef _SYSTICK_H
#define _SYSTICK_H
#include"stm32f10x.h"
#include"core_cm3.h"
#include "misc.h"
void SysTick_Init(void);
static __INLINE uint32_t SysTick_Config1(uint32_t ticks);
void Delayms( __IO uint32_t ms);
#endif
然后在.c文件中初始化系统时钟SysTick_Init( ),就可以使用毫秒延时功能了。
main函数
-----------------------------------------------------------------------------
#include"led.h"
#include"SysTick.h"
int main()
{
unsigned int j;
int LED[10]={LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8};
SysTick_Init( );
LED_Init();
while(1)
{
// LED_Control(LED1, toggle); //LED1闪烁
// Delayms(1000);
for(j=0;j<8;j++) //LED1-8,实现流水
{
LED_Control(LED[j],on);
Delayms(200);
LED_Control(LED[j],off);
Delayms(200);
}
j=0;
}
}
(以上是本人个人观点,如有错误欢迎交流QQ;1186672409,Mr.shi)