STM32中C语言的基础知识

发布者:Meshulun最新更新时间:2024-08-20 来源: elecfans关键字:STM32  C语言  基础知识 手机看文章 扫描二维码
随时随地手机看文章

C语言是单片机开发中的必备基础知识,本文列举了部分STM32学习中比较常见的一些C语言基础知识,希望能对大家有所帮助。


01位操作


下面我们先讲解几种位操作符,然后讲解位操作使用技巧。C语言支持以下六种位操作:

82cae4a0d2ae7f7b809fdada6a39ed84_wKgZomTnlP-AHcQiAAALS0ELSvk531.png

(六种位操作)


下面,重点讲解一下位操作在单片机开发中的一些实用技巧。


1.1 在不改变其他位的值的状况下,对某几个位进行设值。


这个场景在单片机开发中经常使用,方法就是我们先对需要设置的位用&操作符进行清零操作,然后用 | 操作符设值。


比如,我要改变GPIOA的状态,可以先对寄存器的值进行&清零操作:

9da3c207f277d4a60b6225d7ece595fb_wKgZomTnlP-ACG5DAAAMumgcyZ8069.png

然后再与需要设置的值进行|或运算:

6397f29bbf4766c5160ad9bf2d8bd9aa_wKgZomTnlP-ANgDIAAASEivnhTk127.png

1.2 移位操作提高代码的可读性。


移位操作在单片机开发中非常重要,下面是delay_init函数的一行代码:


SysTick->CTRL |= 1 << 1;


这个操作就是将CTRL寄存器的第1位(从0开始算起)设置为1,为什么要通过左移而不是直接设置一个固定的值呢?


其实这是为了提高代码的可读性以及可重用性。这行代码可以很直观明了的知道,是将第1位设置为1。如果写成:

SysTick->CTRL |= 0X0002;


这个虽然也能实现同样的效果,但是可读性稍差,而且修改也比较麻烦。


1.3 ~按位取反操作使用技巧


按位取反在设置寄存器的时候经常被使用,常用于清除某一个/某几个位。下面是delay_us函数的一行代码:

SysTick->CTRL &= ~(1 << 0) ;    /* 关闭SYSTICK */

该代码可以解读为:仅设置CTRL寄存器的第0位(最低位)为0,其他位的值保持不变。


同样我们也不使用按位取反,将代码写成:

SysTick->CTRL &= 0XFFFFFFFE;        /* 关闭SYSTICK */


可见,前者的可读性及可维护性都要比后者好很多。


1.4 ^按位异或操作使用技巧


该功能非常适合用于控制某个位翻转,常见的应用场景就是控制LED闪烁,如下:

GPIOB->ODR ^= 1 << 5;

执行一次该代码,就会使PB5的输出状态翻转一次,如果我们的LED接在PB5上,就可以看到LED闪烁了。


02define宏定义


define是C语言中的预处理命令,它用于宏定义(定义的是常量),可以提高源代码的可读性,为编程提供方便。常见的格式:


60c67a7745ed52013e1300443a58ea95_wKgZomTnlP-AMsfvAAAGwG9tkBo688.png

“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。例如:

f17f8fef6ddeaeb4f5f89b4a08576d1e_wKgZomTnlP-AbRs8AAAFWBHgVG0267.png

定义标识符HSE_VALUE的值为8000000,数字后的U表示unsigned的意思。至于define宏定义的其他一些知识,比如宏定义带参数,这里就不多讲解了。


03ifdef条件编译


单片机程序开发过程中,经常会遇到一种情况,当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。


条件编译命令最常见的形式为:


#ifdef 标识符    程序段1#else    程序段2#endif

它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。


其中#else部分也可以没有,即:

  #ifdef

    程序段1

    #endif

条件编译在HAL库里面是用得很多,在stm32mp1xx_hal_conf.h这个头文件中经常会看到这样的语句:

   #if !defined  (HSE_VALUE)      #define HSE_VALUE            24000000U    #endif



如果没有定义HSE_VALUE这个宏,则定义HSE_VALUE宏,并且HSE_VALUE的值为24000000U。条件编译也是C语言的基础知识吧。


这里提一下,24000000U中的U表示无符号整型,常见的,UL表示无符号长整型,F表示浮点型。


这里加了U以后,系统编译时就不进行类型检查,直接以U的形式把值赋给某个对应的内存,如果超出定义变量的范围,则截取。

04extern变量申明


C语言中extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。


这里面要注意,对于extern申明变量可以多次,但定义只有一次。在我们的代码中你会看到看到这样的语句:


extern uint16_t g_usart_rx_sta;

这个语句是申明g_usart_rx_sta变量在其他文件中已经定义了,在这里要使用到。


所以,你肯定可以找到在某个地方有变量定义的语句:

 uint16_t g_usart_rx_sta;

extern的使用比较简单,但是也会经常用到,需要掌握。

05typedef类型别名


typedef用于为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。typedef在HAL库用得最多的就是定义结构体的类型别名和枚举类型了。


    struct _GPIO

    {

        __IO uint32_t CRL;

        __IO uint32_t CRH;

        …

};

定义了一个结构体GPIO,这样我们定义结构体变量的方式为:

struct  _GPIO  gpiox;       /* 定义结构体变量gpiox */

但这样很繁琐,HAL库中有很多这样的结构体变量需要定义。


这里我们可以为结体定义一个别名GPIO_TypeDef,这样我们就可以在其他地方通过别名GPIO_TypeDef来定义结构体变量了,方法如下:

    typedef struct

    {

            __IO uint32_t CRL;

            __IO uint32_t CRH;

            …

    } GPIO_TypeDef;

Typedef为结构体定义一个别名GPIO_TypeDef,这样我们可以通过GPIO_TypeDef来定义结构体变量:GPIO_TypeDef gpiox;

这里的GPIO_TypeDef就跟struct _GPIO是等同的作用了,但是GPIO_TypeDef使用起来方便很多。


关键字:STM32  C语言  基础知识 引用地址:STM32中C语言的基础知识

上一篇:STM32单片机引脚介绍及功能 STM32单片机的工作原理和基本组成
下一篇:如何使用代码清除STM32单片机上的PCROP

推荐阅读最新更新时间:2024-11-17 13:17

STM32端口复用和端口重映射?什么是端口复用重映射?
对于单片机而言,GPIO引脚配置是最基本的,也是最重要的,因为所有的(信号)输入和(控制)输出都是通过这些配置起作用的。这里就不得不提到单片机的复用功能AF(Alternate Function),这篇文章我们说一说复用功能。 STM32Fxx系列单片机的GPIO可以配置为浮空输入(input floating)、上拉输入(input pull-up)、下拉输入(input pull-down)、模拟输入(analog)、开漏输出(output open-drain)、推挽输出(ouput push-pull)、复用开漏输出(alternate function open-drain)、复用推挽输出(alternate fun
[单片机]
<font color='red'>STM32</font>端口复用和端口重映射?什么是端口复用重映射?
STM32定时器有什么功能?STM32的用法详解
2.2 计数器模式 TI M2-TIM5可以由向上计数、向下计数、向上向下双向计数。向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器内容),然后重新从0开始计数并且产生一个计数器溢出事件。 在向下模式中,计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。而中央对齐模式(向上/向下计数)是计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。 2.3 编程 步骤 1. 配置系统 时钟 ; 2. 配置NVIC; 3. 配置GPIO; 4. 配置TIMER; 其中
[单片机]
<font color='red'>STM32</font>定时器有什么功能?<font color='red'>STM32</font>的用法详解
PIC单片机:温感器ds18B20 C语言代码
/*温感器 采用天祥温度转换模块算法 程序完整版本的下载地址: http://www.51hei.com/f/ds1820pic.rar */ #include pic.h __CONFIG(0X3B31); #define uint unsigned int #define uchar unsigned char #define DQ RC1 #define DQ_DIR TRISC1 #define DQ_HIGH() TRISC1=1 #define DQ_LOW() DQ=0;TRISC1=0 unsigned char shi; //整数十位 unsigned char ge; //整数个位 uns
[单片机]
LCD12864 C语言驱动
#include reg52.h sbit RS=P2^0; sbit RW=P2^1; sbit EN=P2^2; sbit CS1=P2^3; sbit CS2=P2^4; sbit RST=P2^5; #define databus P0 #define uchar unsigned char #define startline 0xc0 #define displayon 0x3f #define startcolumn 0x40 #define page 0xb8 void init(); void clearscreen(uchar); void readbusy(); void writecmd(uchar); v
[单片机]
LCD12864 <font color='red'>C语言</font>驱动
STM32单片机中OBG调试接口的介绍
OBG在单片机中的解释STM32单片机的内核(Cortex-M3)含有硬件调试模块,支持多种复杂的调试操作,硬件调试模块允许内核在取地址或者访问数据时停止-这就是我们在单片机开发和过程中可以在线仿真的保障。内核在停止时,其内部的状态与外部状态都是可以进行查询的,- 在单片机仿真调试中受到中断,通常为人为设置的断点,此时单片机中所有的变量,以及程序指针,CP,等地址指针都可以查询到状态。在调试过程中,设置了断点,当程序停止运行时,我们可以接着进行单步执行,跳出函数,进入函数等操作。还可以进行复位,使寄存器都回归到初始复位状态。 OBG调试接口 串行接口 JTAG调试接口 OBG调试框图 SWJ(serial wire and
[单片机]
<font color='red'>STM32</font>单片机中OBG调试接口的介绍
STM32中断控制的流程
对于 STM32 讲(还是以Timer2例),外部中断通道位置 28(35 号优先级)是给外部设备 TIME2 的,但 TIME2本身能够引起中断的中断源或事件有好多个,比如更新事件(上溢/下溢) 、输入捕获、输出匹配、DMA 申请等。所有TIME2 的中断事件都是通过一个 TIME2 的中断通道向 STM32 内核提出中断申请,那么 STM32 中如何处理和控制 TIME2 和它众多的、不同的、中断申请呢? 1.因为cortex_m3 内核对于每一个外部中断通道都有相应的控制字和控制位,用于单独的和总的控制该中断通道。它们包括有: 中断优先级控制字:PRI_n(前面有提到过) 中断允许设置位:在 ISER 寄存器中 中断允许
[单片机]
STM32基本定时器延时函数
注:本文实践用到的芯片是cortex-m3系列的STM32F103VET6,文中涉及内容覆盖整个STM32F1系列M3单片机。 本文适合学习STM32的初学者阅读。 STM32定时器包含基本定时器、通用定时器和高级定时器,其中TIM6和TIM7是STM32当中的基本定时器,作为初学者,先从最基本的学起最容易,下面我们用这个定时器实现毫秒延时函数来入门STM32定时器的应用。 学习单片机,就是学习使用它的寄存器。即便你用库函数,寄存器也是必须要学习的。 TIM6 TIM7的寄存器如下所示: 先略览一下寄存器,CR1和CR1是控制寄存器,SR是状态寄存器,ARR就是溢出值寄存器,CNT就是计数器的当前值,PSC是预分频寄存器。预分
[单片机]
<font color='red'>STM32</font>基本定时器延时函数
STM32-串口程序
学习各种硬件,串口是必不可少的也是首要学习的外设,因为有了串口之后,就可以和硬件进行简单的交互,也能更加方便的验证所写的程序的正确性。 STM32拥有多个USART,支持多种模式的配置,具体的可以参照STM32的相关手册进行学习 再来看一下USART的功能框图: 在使用任何一个外设功能之前,都要看看它所对应的功能框图,这样有助于理解功能的使用。 接下来看一下关于USART的相关寄存器和可操作的库函数。 最后还需要看一张关于GPIO的USART的引脚复用: 因为USART与外界沟通是用控制器的GPIO引脚的复用功能,所以在使用USART功能之前需要把GPIO配置成相应的输入输出模式。 同时如果需要开启中断,还要进
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved