【STM32】常用功能备忘录

这篇具有很好参考价值的文章主要介绍了【STM32】常用功能备忘录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 GPIO

GPIO_PinState
名称 功能

GPIO_PIN_RESET

低电平(0)

GPIO_PIN_SET

高电平(1)

定时器

        us延时函数实现:

HAL库:
	/**************************************没有操作系统**********************************/
	static uint16_t  g_fac_us = 0;      /* us延时倍乘数 */

	/**
	 * @brief       初始化延迟函数
	 * @param       sysclk: 系统时钟频率, 即CPU频率(HCLK)
	 * @retval      无
	 */
	void delay_init(uint16_t sysclk) 			//例如:g_fac_us = 72 / 8
	{
		SysTick->CTRL = 0;  /* 清Systick状态,以便下一步重设,如果这里开了中断会关闭其中断 */
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);   /* SYSTICK使用内核时钟源8分频,因systick的计数器最大值只有2^24 */
		g_fac_us = sysclk / 8;  /* g_fac_us作为1us的基础时基 */
	}

	/**
	 * @brief       延时nus
	 * @param       nus: 要延时的us数.
	 * @note        注意: nus的值,不要大于1864135us(最大值即2^24 / g_fac_us @g_fac_us = 9)
	 * @retval      无
	 */
	void delay_us(uint32_t nus)
	{
		uint32_t temp;
		SysTick->LOAD = nus * g_fac_us; /* 时间加载 */
		SysTick->VAL = 0x00;            /* 清空计数器 */
		SysTick->CTRL |= 1 << 0 ;       /* 开始倒数 */

		do
		{
			temp = SysTick->CTRL;
		} while ((temp & 0x01) && !(temp & (1 << 16))); /*判断temp的最低位(即CTRL.ENABLE位)是否为1,表示SysTick定时器使能;同时,判断temp的第16位是否为0,表示时间还未到达。*/

		SysTick->CTRL &= ~(1 << 0) ;    /* 关闭SYSTICK */
		SysTick->VAL = 0X00;            /* 清空计数器 */
	}

	/**
	 * @brief       延时nms
	 * @param       nms: 要延时的ms数 (0< nms <= 65535)
	 * @retval      无
	 */
	void delay_ms(uint16_t nms)
	{
		uint32_t repeat = nms / 1000;   /* 记录超出1000ms的值,即1s */
		uint32_t remain = nms % 1000;   /* 记录未超出1000ms的值 */

		while (repeat)
		{
			delay_us(1000 * 1000);      /* 利用delay_us 实现 1000ms 延时 */
			repeat--;
		}

		if (remain)
		{
			delay_us(remain * 1000);    /* 利用delay_us, 把尾数延时(remain ms)给做了 */
		}
	}

	/*******************************************加入操作系统************************/
	// 初始化定时器
	void TIM_Init(void)
	{
		TIM_HandleTypeDef htim;
		htim.Instance = TIM2;
		htim.Init.Period = 0xFFFF;
		htim.Init.Prescaler = HAL_RCC_GetPCLK1Freq() / 1000000 - 1; // 设置定时器时钟为1MHz
		htim.Init.ClockDivision = 0;
		htim.Init.CounterMode = TIM_COUNTERMODE_UP;
		HAL_TIM_Base_Init(&htim);
	}
	
	// 微秒级延时函数
	void Delay_us(uint32_t us)
	{
		__HAL_TIM_SET_COUNTER(&htim2, 0);  // 清空定时器计数器
		HAL_TIM_Base_Start(&htim2);  // 启动定时器
		while (__HAL_TIM_GET_COUNTER(&htim2) < us);  // 等待定时器计数器达到指定值
		HAL_TIM_Base_Stop(&htim2);  // 停止定时器
	}



标准库:
	/********************************没有操作系统************************************/
static u8 fac_us = 0;
static u16 fac_ms = 0;

void delay_init(void)
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); // 选择外部时钟 HCLK/8
    fac_us = SystemCoreClock / 8000000;
    fac_ms = (u16)fac_us * 1000;
}

void delay_us(u32 nus)
{
    u32 temp;
    SysTick->LOAD = nus * fac_us; // 延时时间加载
    SysTick->VAL = 0x00;          // 清空计数器
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开始倒数
    do
    {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16))); // 等待时间到达
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
    SysTick->VAL = 0x00;          // 清空计数器
}

void delay_ms(u16 nms)
{
    u32 temp;
    SysTick->LOAD = (u32)nms * fac_ms; // 时间加载(SysTick->LOAD为24bit)
    SysTick->VAL = 0x00;          // 清空计数器
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开始倒数
    do
    {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16))); // 等待时间到达
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
    SysTick->VAL = 0x00;          // 清空计数器
}
	
	/*********************************加入操作系统************************************/
	void TIM_Init(void)
	{
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // Enable the clock for TIM2

		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
		TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
		TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 1000000 - 1; // Set timer clock to 1MHz
		TIM_TimeBaseStructure.TIM_ClockDivision = 0;
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
		TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

		TIM_Cmd(TIM2, ENABLE);  // Enable TIM2
	}

	void Delay_us(uint32_t us)
	{
		TIM_SetCounter(TIM2, 0);  // Clear the timer counter
		while (TIM_GetCounter(TIM2) < us);  // Wait until the timer counter reaches the specified value
	}
	

标准库:

        需要使能TIM_Cmd(TIM8, ENABLE); 和 TIM3_IRQHandler中断服务函数

HAL库:

        要手动开启和关闭定时器及其中断:

HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)

HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) 

HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)

         中断回调函数 -- 名字不能错误 && 一定要先开定时器中断,再开定时器

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == &htimx)
    {
    }
}

         PWM输出通道

                单路输出

         标准库:           

                        开启     TIM_CtrlPWMOutputs(TIM8, ENABLE);

                        设置比较值     TIM_SetCompare1(TIM8, pwm);

         HAL库:

                        开启
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
                        设置比较值(设置占空比)
__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)  

             互补输出

        高级定时器特有,电机控制常用。分频和单路相同

        DMA模式 

                开启DMA

HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)

                关闭DMA

        DMA中断里调用,不然可能出现少了脉冲

HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)

                PWM+DMA中断回调函数

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == &htimx)
    {
    }
}

从内存到外设        普通模式        建议设置为字(word)模式

 外部中断

需要自己写,名字不能错误

 标准库:

        对GPIO进行EXTI和NVIC的配置,手写EXTI中断服务函数

HAL库:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_x)
    {
        
    }
}

低功耗停止模式(STOP)

        这个是最常用的低功耗模式 -- 由外部中断唤醒

标准库:

HAL库:

void stop_mode(void)
{
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//清除标志
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//进入停止模式
 
    //这里放HAL生成的那些初始化函数
}

退出停止模式后默认使用是内部RC震荡,系统频率可能会改变。懒人方法是将HAL库在main前面的初始化函数放到这个停止模式的后面即可,退出停止模式后回到这个地方继续执行

串口

        阻塞模式

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 
#define printf(...) \
        HAL_UART_Transmit(&huart5,(uint8_t *)u_buf,sprintf((char *)u_buf,__VA_ARGS__),0xffff)

uint8_t u_buf[128];

        中断模式

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

中断回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart == &huart1)
    {
        HAL_UART_Receive_IT(&huart1, &Uart_BUF, 1);
    }
}

                空闲中断(不定长数据接收)

        当总线没有数据一段时间后,认为总线空闲,触发空闲中断

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

空闲中断回调函数

uint8_t BUF[100] = {0};
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart == &huart2)
    {
        HAL_UARTEx_ReceiveToIdle_IT(&huart1,BUF,100);
    }
}

建议使用空闲中断时,使用DMA模式发送数据

        DMA模式

DMA发送

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

DMA的初始化需要在UART之前

停止DMA发送

HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)

                DMA空闲接收 (有点复杂......)

实现的功能是 使用DMA接收数据,接收到超过指定数量时,或者数据接收完成(触发空闲状态)

SPI

 IIC

        硬件IIC:

#define ADDR_AT24C512_Write 0xA0
#define ADDR_AT24C512_Read 0xA1

int16_t AT24C512_Write_nBytes(uint8_t *data, uint16_t addr, uint16_t length)
{
    if( HAL_I2C_Mem_Write( &hi2c1, ADDR_AT24C512_Write, addr, I2C_MEMADD_SIZE_16BIT, data, length, 1000 ) == HAL_OK )
        return 0;
    else
        return -1;
}
 
int16_t AT24C512_Read_nBytes(uint8_t *data, uint16_t addr, uint16_t length)
{
    if( HAL_I2C_Mem_Read( &hi2c1, ADDR_AT24C512_Write, addr, I2C_MEMADD_SIZE_16BIT, data, length, 1000 ) == HAL_OK )
        return 0;
    else
        return -1;
}

CAN 

术语定义

               扩展帧 -- 规范中定义的使用 29 位标志符的 CAN 数据帧;

               标准帧 -- 规范中定义的使用 11 位标识符的 CAN 数据帧;

               数据域 -- 数据帧中包含应用层定义的 0-64 位数据;

【STM32】常用功能备忘录,单片机,stm32,mcu,嵌入式硬件

ADC

        阻塞查询

HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)

等待ADC转化完成

HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)

(可选)关闭ADC

HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)

        DMA模式

扫描模式开启(多通道)

ADC到内存(默认设置)  模式选择正常模式  内存地址自增,半字节

ADC校准(在初始化函数之后,DMA调用之前) 文章来源地址https://www.toymoban.com/news/detail-812939.html

HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)

HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData,

中断回调函数 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
  if (hadc == &hadcx)
  {
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&Buf, 4);//如需多次采集则使用这句
  }
}

软件复位

__set_FAULTMASK(1);//关中断 
NVIC_SystemReset();//复位

到了这里,关于【STM32】常用功能备忘录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 快速搭建linux centos 部署环境及常用命令-备忘录,以防丢失

    一. gcc 安装 yum install gcc-c++ 安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装: 二. PCRE pcre-devel 安装 PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所

    2024年02月08日
    浏览(37)
  • WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口

    1、新建MenoDto.cs 2、添加映射关系 3、新建服务接口IMemoService 4、新建服务MemoService 5、新增MemoController控制器 6、在program.cs添加服务 7、F5运行项目      8、针对查询数据可以做个优化,增加查询的页数、内容、数据量等,新建查询参数类    9、在IToDoService.cs和IMemoService.cs中添

    2024年02月11日
    浏览(39)
  • 手机备忘录怎么设置提醒 备忘录提醒设置方法

    具备提醒功能的手机备忘录有很多,比如云便签的提醒功能十分好用,不仅可设置单次定时提醒,还能添加重复提醒、重要事项提醒或到期延时提醒等,而且提醒方式也支持应用、微信、短信、电话、邮箱及手机系统日历等多种。那这款手机备忘录怎么设置提醒?备忘录提醒

    2024年02月12日
    浏览(41)
  • 手机备忘录如何批量导出来,备忘录整体导出方法介绍

    手机备忘录如何批量导出来?一些品牌的手机上有自带的备忘录,大多手机自带备忘录都不支持直接批量导出,只能通过分享或复制类的功能逐条导出,手动进行整理。 除了手机自带备忘录,一些朋友会选择在自己的手机上使用云便签备忘录,不仅可以在线添加备忘录提醒事

    2024年02月16日
    浏览(49)
  • 苹果备忘录如何转移?备忘录怎么转移到新手机?

    对于很多苹果手机的用户而言,想必都有使用备忘录的习惯吧?但是,经过长期的使用,当需要更换手机设备时,您考虑过如何转移这些记录吗? 苹果备忘录怎么转移到新手机? 如您使用的是苹果手机内置的备忘录,并且需要更换的新设备依然是苹果手机,其解决方案非常

    2024年02月13日
    浏览(59)
  • 苹果手机备忘录如何导入新手机?手机备忘录怎么转移?

    一般来说,大多数手机用户更换手机的频率是3—5年,在一部手机使用了几年之后,就会出现内存不足、系统卡顿、电池续航时间较短等问题,这时候就需要更换新的手机了。有不少苹果手机用户在更换新手机的时候,都很发愁一个问题,这就是手机备忘录如何导入新手机。

    2024年01月25日
    浏览(44)
  • stata备忘录

    1. 画图 (1)时间趋势图 等价命令 字体大小 option 字体大小option description zero no size whatsoever, vanishingly small minuscule smallest quarter_tiny third_tiny half_tiny tiny vsmall small medsmall medium medlarge large vlarge huge vhuge largest tenth one-tenth the size of the graph quarter one-fourth the size of the graph third one-thi

    2024年02月03日
    浏览(42)
  • 博文备忘录

    https://blog.csdn.net/ZQ_KING/article/details/80320080 (链接层)MAC地址——ARP协议 (网络层)IP地址——IP协议 (传输层)端口——UDP协议、TCP协议 (应用层)域名——HTTP协议、HTTPS协议 https://github.com/xiaomuzhu/front-end-interview/blob/master/docs/guide/http.md (http) https://github.com/xiaomuzhu/front-

    2024年02月08日
    浏览(43)
  • 备忘录模式(Memento)

    备忘录模式是一种行为设计模式,在不破坏封装性的前提下,允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。 一个备忘录(memento)是一个对象,它存储另一个对象在某个瞬间的内部状态,而后者称为备忘录的原发器(originator)。当需要设置原发器的检查点时,取

    2024年02月13日
    浏览(37)
  • 备忘录模式

    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 1.1 撤销操作: 例如,在文本编辑器中,当我们对文本进行修改时,可以使用备忘录模式来实现撤销操作。每次对文本进行修改时,就保存当

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包