发帖数

50

原创数

50

关注者

12

阅读数

9745

点赞数

4

蔡琰

  • 单片机学习之基础篇

    寄存器

    寄存器,是集成电路中非常重要的一种存储单元,在集成电路设计中,寄存器可分为电路内部使用的寄存器和充当内外部接口的寄存器这两类。内部寄存器不能被外部电路或软件访问,只是为内部电路的实现存储功能或满足电路的时序要求。而接口寄存器可以同时被内部电路和外部电路或软件访问,CPU中的寄存器就是其中一种,作为软硬件的接口,为广泛的通用编程用户所熟知。

    我们举例STM32的一个寄存器:

    1.jpg 

    1. 关于学习资料

    对于学习一款单片机而言,资料不需要很多,最主要的还是芯片的手册,手册里面会体现出你想要的,有的人忽视手册,想要通过某种捷径直接去跳过这一步,在这里我想说,除非你有一定的了解,有信心前面的过程不会出现问题,否则还是老老实实的去啃手册,下面我们来介绍下学习STM32F373CCT6这款单片机我们用到的文档:

    1.STM32F373_Reference_Manual》是 ST 出的官方资料,有 STM32F3的详细介绍,包括了STM32F3 的各种寄存器定义以及功能等,是学习 STM32F3 的必备资料之一。

    2.STM32F373xx》也是 ST 出的官方资料,有关于芯片引脚定义,模块功能概括以及芯片的电气属性等介绍,是学习 STM32F3 的必备资料之一。

    3. STM32F3 F4 系列 Cortex M4 内核编程手册》 则是对 上述资料的补充, 很多关于 CortexM4 内核的介绍(寄存器等) ,都可以在这个文档找到答案,该文档同样是 ST 的官方资料,专门针对 ST Cortex M4 产品。4. Cortex M3 M4 权威指南》则针对 Cortex M4 内核进行了详细介绍,并配有简单实例,对于想深入了解 Cortex M4 内核的朋友,此文档是非常好的参考资料。


    2. 关于学习方法

    首先你要有个实验平台,不管资料再多这些资料的来源依据还是数据手册,一定要自己去对着数据手册仔细研读,自己独立动手配置,在平台上去做实验。只有不断的实验你才能理解。当遇到问题时不要在第一时间去网上搜索答案,再去研读数据手册,解决不了的时候,再试图去网上参考借鉴一下其他朋友的案例。


    3. MDK5软件的使用

    3.1 STM32  官方 标准 固件库简介

    ST(意法半导体)为了方便用户开发, 提供了一套丰富的 STM32 固件库。 到底什么是固件库?它与操作寄存器有什么区别?这一节,我们将讲解 STM32 固件库相关的基础知识, 希望能够让大家对 STM32固件库有一个初步的了解。

    3.1.1  库开发与寄存器开发的关系

    固件库就是函数的集合,固件库函数的作用是向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API) ,最终操作的还是寄存器。

    51 的开发中我们常常的做法是直接操作寄存器,比如要控制某些 IO 口的状态,我们直接操作寄存器:

    2.jpg 

    我们写成十六进表示:P0 = 0xAA;

    而在 STM32 的开发中,我们同样可以操作寄存器:

    GPIOA->BSRR=0x0001;

    为了省却麻烦, ST(意法半导体)推出了官方固件库, 固件库将这些寄存器底层操作都封装起来, 提供一整套接口 (API)。

    比如上面的控制 BSRR 寄存器实现对某一引脚的电平控制,官方库封装了一个函数:

    void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

    {

    GPIOx->BSRR = GPIO_Pin;

    }


    位操作

    C 语言位操作相信学过 C 语言的人都不陌生了,简而言之, 就是对基本类型变量可以在位级别进行操作。这里简单复习一下。我们讲解几种位操作符,然后讲解位操作使用技巧。

    运算符

    含义

    运算符

    含义

    &

    按位与

    ~

    取反

    |

    按位或

    <<

    左移

    ^

    按位异或

    >>

    右移

     

    1. 不改变其他位的值的情况下,对某几个位进行清0

    GPIOA-> BSRR = GPIOA-> BSRR & 0XFF0F;  //将第 4-7 位清 0

    不改变其他位的值的状况下,对某几个位进行置1

    GPIOA-> BSRRL = GPIOA-> BSRRL | 0X0040; //设置相应位第6位的值,不改变其他位的


    2. 移位操作

    GPIOx->ODR = 1 << 2; //1<<2 = 4 相当于把4给了ODR寄存器

    GPIOx->ODR = 4 >> 2; //4<<2 = 1 相当于把1给了ODR寄存器

    ~取反操作  //用来对一个二进制数按位取反,即0110

    GPIOx->ODR  = ~GPIOx->ODR


    3. ^按位异或 //若参加运算的两个二进制位值相同则为0,否则为1.

    GPIOx->ODR  = 0x05^GPIOx->ODR

    以上就是做单片机控制的基础知识,踏实学了可以节省时间和精力去做应用模块的逻辑和算法了。基础扎实了会让产品更稳定,不能模棱两可的设计,否则故障会意想不到的出现。


    收藏 0 回复 0 浏览 172
  • 回调函数的使用

    大家好!我是张飞实战电子蔡琰老师,今天给大家讲解回调函数的使用。

    回调函数(Callback Function)是程序中一种常用的函数调用方式。其特点是可以在下层软件模块(宏观上的被调用者)中,调用来自上层的软件模块(宏观中的调用者)中的函数,这和通常的调用顺序是相反的。

    程序调用的方式:

    软件模块的关系,从总体上看,有上层软件模块和下层软件模块之分。一般有三种调用方式:

    简单的同步调用

    带有回调的调用

    异步调用

    同步调用是最常用的调用方式,由上层模块调用下层模块。在调用过程中,上层模块将被阻塞,直至下层模块执行完毕并返回。在方向上,同步调用是单向的调用方式,如下图所示:

    图片1.jpg

    上图调用方式为A->B。即上层模块的函数A调用下层模块的函数B,在调用过程中函数A被阻塞,当函数B返回之后,函数A继续执行。在B执行过程中,A不能得到B执行的消息。同步调用是一种最简单的调用方式,在大多数的C语言库函数调用中,都使用这种方式。

    带有回调的调用方式是一种双向调用模式,在这种方式中,下层模块的函数在被调用的时候,将会调用上层模块的某个函数,如下图所示:

    图片2.jpg

    在带有回调的调用中,调用方式为A->B->C。位于上层模块的函数A调用下层模块的函数B,在B的执行过程中,将调用上层模块的函数C。在这里函数C被称为回调函数,它是被下层模块所调用的上层模块函数。B函数执行的过程中,可以通过调用C函数将信息返回给上层模块。对于上层模块,C函数至少有两个作用,其一是监视B的运行状态,其二是干预B的运行。在这种方式中,本质上的关系依然是上层调用下层,由于增加了回调函数C,这样可以在调用的过程中进行交互。

    异步调用一般基于消息或事件,下层模块接受上层模块的命令,当发生某个事件的时候,下层模块将调用上层模块的函数。异步调用方式一般基于回调函数的注册机制。异步调用如下图所示:

    图片3.jpg

    在异步的调用方式中,调用方式为A->B立刻返回,当某个事件发生后,进行D->C的动作。本来上层模块的A调用下层模块的B的时候,只是一个简单的同步调用,调用完后将立刻返回。在A->B的调用过程中,可以向下层模块注册某些信息,例如回调函数C,当下层模块的某个事件发生的情况下,调用上层模块的C函数。

    再来看下回调函数的作用:

    回调函数的表现形式是一个某种类型的函数指针,这个函数由上层的软件模块实现,将这个函数指针通过某种方式传递给下层的软件模块,由下层的软件模块在某个时刻调用这个函数。

    函数指针的本质是一个函数的地址,在32位的C语言系统中,本质上就是一个32位无符号的整型数。函数指针由上层软件模块到下层软件模块的传递方式可以是通过作为函数的参数传递,也可以是使用结构体的成员进行传递。调用回调函数的时刻一般有两种:一种是在上层模块调用的下层模块的函数中,直接调用回调函数;另一种是使用注册的方式,在某个事件发生的时候下层模块调用回调函数。


    收藏 0 回复 0 浏览 168
  • 单片机的时钟源

    大家好!我是张飞实战电子蔡琰老师,今天给大家分享单片机的时钟源


    在单片机中,比如我们常用的STM32是有五个时钟源的,分别是:HSI,LSI,HSE,LSE,PLL。


    这些时钟源都体现在时钟树,我们知道每个型号的单片机手册都有时钟树的展示,这样让我们能清楚知道应用到的外设是通过哪个时钟源分频或倍频得来的。我们以ST推出的STM32G030为例来看下:

    image.png

    1、HSI是高速内部时钟,RC振荡器,频率为16MHz。

    2、LSI是低速内部时钟,RC振荡器,频率为32KHz。

    3、HSE是高速外部时钟,可接晶体/陶瓷振荡器,或者接外部时钟源(Bypass模式),频率范围是4-48MHz。

    4、LSE是低速外部时钟,接频率为32.768KHz的石英或谐振器,或者使用旁路模式引入外部时钟源。

    5、PLL为锁相环倍频输出,其时钟输入源可选择为HSE、HSI。倍频可选择为1~8倍,但是其输出频率最大不得超过64MHz(注意单片机的最大频率)。


    我们看到LSI(32KHz)供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。


    当然我们看到RTC的时钟源还可以选择LSE,或者是HSE的32分频。当然选择哪个作为最终的时钟源就是通过寄存器来配置了。

    这个LSI(低速内部时钟)可以用于除Shutdown和VBAT模式之外的所有模式。


    系统时钟是可以提供绝大部分工作的时钟源,是可以通过LSE、LSI、HSE、PLL、HSI分频获得。系统时钟可以分频给到总线去分到各个外设上,还可以直接提供给外设,比如ADC和I2S。系统时钟、AHB总线的最大时钟可以是64MHz(单片机支持最大频率)。


    HSI时钟可以衍生HSISYS,HSISYS这个可以从Stop0和Stop1模式唤醒后被选为时钟源,也可以当做备份时钟源。


    I2C、UART、LPUART在Stop模式下如果探测到了从Stop模式下唤醒的序列则能够自动使能HSI16时钟。(HSI16时钟在Stop模式下保持关闭的状态,除非探测到了外设唤醒序列)


    HSE的时钟安全系统(CSS),自动检测到HSE失效时切换到HSI16。


    LSE的时钟安全系统适用于除了Shutdown和VBAT模式之外的所有模式,在复位状态下仍然有效。


    LSE可用于RTC, U(S)ARTs, LPUART, LPTIMs.

    PLL可以给到三路输出,是可以获得的最大频率不一样,给到的外设不一样,PLLPCLK是最大频率可以做到122MHz,可以给到ADC或者I2S。PLLQCLK最大频率是112MHz,是应用到定时器的。PLLRCLK最大频率是56MHz,主要是给到系统时钟。

    多个时钟源的好处是在选择时钟源的时候具有高度的灵活性,可满足功耗和精度的要求。


    许多独立的外设时钟允许在不影响通信波特率的情况下调整功耗,并在低功耗模式下保持一些外设有效。


    现在很多单片机都考虑到了低功耗,自然时钟也是其中很重要的部分了。


    对于应用外设时钟这块还是很重要的,需要会看时钟树,会对应用需要的时钟进行配置,这个就显得很重要了,比如想要高速时钟需要倍频,如果是低功耗需要分频,首先还是需要去看时钟的分布,才好再去应用的。




    收藏 0 回复 0 浏览 165
  • 白话文讲解STM32时钟树

    时钟就像是单片机的“心脏”,单片机正常工作离不开时钟的支持,下图是我们单片机的时钟树 ,它反映了单片机的时钟关系我们来详细描述一下时钟树的工作原理。
    1.jpg


        寄存器上电后有一个复位值,大家看我画红线的这个,这个是单片机上电默认使用时钟的配置线路默认使用的是内部默认的8M  RC振荡器有两条路可以选我们先看上面红色的第一条,到多路选择SW的时候,我们可以通过配置寄存器中的SW来决定HSI/PLLCLK/HSE哪一个输入信号从多路选择器通过,在默认的状态下SW选择的是HSI8M从多路选择器通过。


        通过了SW这个选择开关后,第一个是SYSCLK 一路朝上可以供I2C1选择时钟另外一个就是继续向后,通过AHB 这个方框,在这里我们可以配置寄存器选择这个8M是否分频默认是不分频 也就是经过这个方框后出来往后的还是8M,如果这里配置为2分频,方框出来后就是 4M 经过AHB分频出来后还是8M 这个8M 提供给了很多路大家可以从上面的图中看出来,那么继续向后是 APB 分频
        这里分了两个箭头指向,一个是朝上的给AHB总线 内核Memory  DMA内核定时器FCLK从这里我们可以看到 内核是8M时钟这个频率决定了单片机指令的执行时间,频率越小,指令执行速度越慢一路是向后给了APB分频器,这里可以配置你想要的分频系数,如果这里还是不分频出来的PCLK 还依然是8M,那么PCLK又给了 APB外设 还给了定时器、串口等外设。


    通过这个关系,我们可以清楚的知道,每个外设的工作频率,那可能就会有人问了,这有什么用呢?每个外设都需要时钟来提供振荡源来帮助完成工作,举个例子讲,比如说串口配置一个波特率,那么波特率(通信速率,表示每秒钟传送的数据的位数,即bit/s)是如何来配置呢,就是根据这个时钟频率来配置的,知道了时钟频率,厂家有一个计算公式,就能很容易的算出某一个波特率对应的寄存器值是多少。

    默认的我们知道了,M0支持最大48M内部RC振荡器只有8M,这个咋整呢?不要慌,我们继续往下看。


    2.jpg 

    既然HSI直接给SW多路选择器,不能到48M,那我不直接给通过SW了行不行,请看图中箭头处,HSI绕一下从 PLLSRC 多路选择器通过那么PLLSRC多路选择器也有两个选择可以通过寄存器配置,假设配置寄存器选择 HSI作为输入多路选择器输出后经过PREDIV分频器,假设 PREDIV 我们配置不分频这个分频器出来输入到PLL模块的时候还是8M


    3.jpg
    PLL模块起到 一个倍频的作用,大家可以看到方框里面是乘2 3...,如果这个时候我们配置寄存器设置PLLMUL6,那么出来的PLLCLK 48M,那么这个时候 SW多路开关选择 PLLCLK作为输入,后面出来的时钟就是48M了,再往后面就跟上面讲的情况一样了,可以自由去配置分频


    使用内部RC振荡器我们理解了,但是内部的振荡器往往会因为,精度低,受温度影响比较大等情况,不会被选择,这个时候工程师们就会选择使用外部晶振,外部晶振也是一样的配置方式,大家是否能根据上面讲的思路,配置出来呢?


    收藏 0 回复 0 浏览 159
  • 女工程师跟你分享和嵌入式的不解之缘

    ①邂逅

    女汉子是从小挂在我身上的标签,身体好,性格直。然而报志愿也是听亲戚推荐然后选择了计算机,话说计算机是没有嵌入式以及单片机的,只会学些计算机的语言(偏上位机),大学的所有懒惰的美好(通宵打游戏,谈恋爱等等)都体验了一番才发现是要毕业了,突然意识到自己能去干点啥,就在这个时候学校有合作的嵌入式培训,起初也是想着就业去的,而且当时看到师兄做了个机器人,又会唱歌又会跳舞,太好玩了,这个真的是激起了我的兴趣。就这样开启了学习嵌入式以及单片机的路程~

    图片1.png 

    ②笨手笨脚的第一次

    单片机,ARM一系列课程,当时感觉真的可以收获颇丰,也不会很难的吧。兴趣满满的去上课,认识元器件,画原理图,看程序。简直眼花缭乱啊,自信被打去了一大半,开始怀疑人生了,不知道自己是否能学会,就这样结束了学习的第一课。

    图片2.png 

    ③越挫越勇,继续奋斗

    当一个人想认真做一件事的时候,你会发现潜力无限啊,韧劲也是无限的呢。认真起来的样子也是很可爱的,每天充实的生活,学习,什么都不想了。当你坚持下来之后,回头看看那些坚持是收获了太多。单片机就这样在曲折的道路上学完了,有时候学了会自信满满,有时候会在崩溃的边缘,然鹅这都被我强大的内心压下去了。

    想来学完单片机真的自己会设计东西吗,记得第一次做交通灯的时候那个兴奋劲,从原理图设计,到PCB,再到程序设计,虽然做出来了,其实现在想想当时并没有完全理解了。

    从此开始对各种电子小产品有了兴趣,拆拆装装,虽然不是每次都能完全对上,但总归让自己觉得一只脚踏入了智能社会了。哇,那个心情啊~

    其实每个知识点的学习都是垫脚石,除了坚持不懈,还要不断的学习,不断的实践,买来开发板自己研究,去网上搜集各种资料,从多次失败中总结经验,每次踩过的坑都是经验的积累过程,学习的过程不就是把知识变成自己的嘛,能灵活运用了才是真的学到了。

    图片3.png 

    ④心得

    作为一个女汉子我想对那些想接触单片机以及嵌入式的萌新说,我一开始也是被嵌入式做的产品吸引才学的,也做了无数次的实验,经历过无数次的失败,也担心不是科班出身还想做电子产品,被质疑的眼神以及话语再退缩了。

    开始找工作确实很没有底气,总是觉得自己不行,不敢投简历,不敢去面试,一段时间的低迷让我整个人有点没了方向。谁让我还算强大呢,即使是兴趣是最好的老师,那也离不开对爱好的不离不弃啊~汗水下面永远都是会夹杂点泪水的呢,笑到最后的永远都是靠坚持的。

    我只是想告诉大家如果对嵌入式感兴趣就一定去试试,不管结果怎么样,爱好就去接触下,没准就能爱了呢,会有很大收获的。

    大家一定要有个记录的好习惯,好记性不如烂笔头,记录不仅可以鼓励自己,还能留下你的拼搏奋斗的脚印。回头发现原来自己还能如此优秀。

    行走江湖,技艺可多但是需精湛,每个项目的磨炼,每个日夜的奋斗都会给你留下美好的回忆。同为爱好者,我们有机会可以一起畅谈人生,畅谈理想~

    收藏 0 回复 0 浏览 150
×
蔡琰