暑假自学嵌入式Day4 & Day5

这几天的碎碎念

这两天还在捣鼓单片机,以及esp8266wifi模块,每次在学这些东西以及想上手的时候,总有几个知识点是我卡住的,包括我在看视频的时候也种有几个知识点是up主理所当然以为我们知道的,但是我却会因为这一块的知识点不理解而卡住,所以我现在还没有正式将esp8266连接上云。

今天看了会儿《纳瓦尔宝典》这本书,里面一句话给我的启发很大

“只有掌握好基础知识,才能不忌惮任何书籍。如果在图书馆找到一本自己无法理解的书,那么你先要了解读懂这本书需要那些基础知识,打好基础后再深入研究。基础是极为重要的。”

 从大二上册开始,我觉得学习任何东西直接上手就行了,我觉得很多东西不需要经过太多的路径才说适合我们去做,就是“项目式学习”,所以那个时候起,我学习乐器,学习代码都是直接上手的,这也使我在学习的过程中,学习的耐心逐渐变得急躁,很多东西开始选择忽略,只是大概了解一下或者还没有完全理解就跳过,导致我在后面的学习碰壁。

我不想否认我的学习方式,对我的影响就是,得承认基础很重要,重视每一个我没弄明白的知识,重视每一个模糊的地方,要基于我想实现的目标来弥补我的基础。

知识是网状的,但网也是分层的

 说多了,简单分享一下最近的学习。

一. STM32学习(PWM代码篇)

前几天更新了PWM的原理暑假嵌入式自学笔记 Day1-CSDN博客),还有STM32的定时器外设是如何输出PWM信号的暑假嵌入式自学笔记 Day2-CSDN博客),今天学习的重点在“怎么通过代码来控制单片机输出PWM信号”

今天做的项目是跟着江科大的STM32的教程“PWM驱动呼吸灯”实现的,同时在这次学习中,我还发现手册还是很有用的。

今天这个项目要实现的目标是这样的

PWM驱动呼吸灯

我们可以看到LED灯是暗亮变化的,这个就是今天要是实现的很简单的项目(感觉代码还挺复杂的)

提前申明一下,后面很多出现的图片都出自江科大的PPT,以及他们所分享的资料,感谢江科大的教程QvQ(避免每次用图片的时候都要声明)

  1.大致思路讲解

这个是我们STM32的外设TIM(定时器)的原理图

 其中主要控制着PWM输出的就是我红色框框圈住的那一块,我们用这幅图来简化一下这一块,这幅图也是我们编写PWM的一个重要参照。

 对照着原理图,上面是时基单元,下面是输出比较单元(都连接在时基单元的CNT下)

所以我们的思路是这样,

1,开启片上外设的时钟:GPIO,TIM等(基本上这都是第一步)

2,配置TIM的时基单元

3,配置输出比较单元

4,配置GPIO口的模式

5,运行控制



对应接线图如下:实物接线图如下

2.代码详解及分析

首先,我假如大家之前的课都听过了,或者有一些些用keil编写STM32的基础。

那么我们要编写PWM这一块的代码,肯定不会在main函数里面去编写,会创建两个同名文件,一个C文件(PWM.c)负责编写主代码,一个库文件(PWM.h)负责存放我们C文件的代码,后面我们在main.c文件里面直接调用就好了,同时我们将这两个文件存放进Hardware文件里面。

首先在C文件里面编写代码,在我们导入了STM32标准库函数以后,首先初始化一个函数,

void PWM_Init(void)

{

     代码内容

}

而后根据我们的思路来写代码,

第一,开启片上外设的时钟:GPIO,TIM等

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟

第二,配置TIM的时基单元

/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;					//计数周期,即ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元

第三,配置输出比较单元

/*输出比较初始化*/
	TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值
																	//则最好执行此函数,给结构体所有成员都赋一个默认值
																	//避免结构体初值不确定的问题
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//输出比较模式,选择PWM模式1
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//输出极性,选择为高,若选择极性为低,则输出高低电平取反
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//输出使能
	TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1

第四,配置GPIO口的模式

/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出	
																	//受外设控制的引脚,均需要配置为复用模式	

第五,运行控制

/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行

这是我们大致的代码,其实我们能发现,在配置很多外设上的时候,我们都会用到结构体来配置,在我们写代码的时候,我们最多只需要知道要做什么,平时常用到哪些代码,能够通过我们的库函数来找到并调用就好了,以及我们可以查询我们的函数库文件,了解每一个函数具体是怎么用的,现在很多模块封装得比较好,我们大部分会用就好

PS:托更了好几天,就是我这几天懒了,同时在写这篇文章的时候草稿已经打好了,想写得长一点,但是最后还是因为自己没有维持好这个习惯而脱了好久

这几天也确实在学习,但是并没有整理成博客,导致我感觉这几天学了什么也不太清楚,后面得坚持下来了,每天留点固定时间来整理博客试一试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夕止.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值