STM32基础入门学习笔记:内部高级功能应用

这篇具有很好参考价值的文章主要介绍了STM32基础入门学习笔记:内部高级功能应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录:

一:低功耗模式

1.睡眠模式测试程序

NVIC.h

NVIC.c

key.h

key.c

main.c

2.停机模式测试程序

main.c

3.待机模式测试程序

main.c

二:看门狗

1.独立看门狗测试程序

iwdg.h

iwdg.c

main.c

2.窗口看门狗测试程序

wwdg.h

wwdg.c

main.c

三:TIM定时器

tim.h

tim.c

main.c

四:CRC循环冗余校验计算单元与芯片ID

1.CRC功能测试程序

main.c

2.芯片ID读取程序

main.c

五:还需要补充的知识


这些是单片机的辅助功能

一:低功耗模式

单片机内部功率是各功能部分功率的总和

低功耗模式是通过关掉部分内部功能达到省电

STM32F103单片机共有3种低功耗模式

不同模式会对系统正常工作有一定影响,需要按实际情况选择

低功耗模式只针对单片机内部功能,外接电路产生的功耗不在其内



单片机最小系统电路功耗,不精确测量值
    √正常模式:10mA
    √睡眠模式:2mA
    √停机模式:20uA
    √待机模式:2uA


睡眠模式
    在ARM内核无事可做的时候,可以进入睡眠模式
    例如:电脑的CPU空闲状态就是单片机睡眠模式

    睡眠模式的应用不多,因只关闭ARM内核,节能有限,很少在非操作系统程序(裸机)中使用
    在嵌入式操作系统中,会采用睡眠模式

    优点:对系统影响最小
    缺点:节能效果最差


停机模式
    因SRAM内容不消失,程序不复位,可在唤醒后继续运行
    节能效果与待机模式近似,却有着更多优势

    主要用于电池供电的设备上,提高电池寿命
    在电池供电的产品中必须使用,在外部供电的产品中没必要使用

    优点:节能效果好,程序不会复位
    缺点:恢复时间较长



待机模式
    由于SRAM内容消失,唤醒后程序必须复位,从头开始运行

    因为待机和停机之间的功耗差别是uA级的,几乎没有差别,所以开发者大多使用停机模式,待机模式极少使用
    在一些偶尔需要工作的场合,且工作量不大、不复杂的情况下,待机模式可以保证最低的功耗
    比如应用在室外温度测量产品上,每1小时测量一次。可用RTC闹钟唤醒,测量完再待机。、

    优点:最节能
    缺点:程序会复位,只有少数条件可唤醒

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

1.睡眠模式测试程序

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

NVIC.h

#ifndef __NVIC_H
#define __NVIC_H	 
#include "sys.h"


extern u8 INT_MARK;//中断标志位


void KEY_INT_INIT (void);

#endif

NVIC.c

#include "NVIC.h"

u8 INT_MARK;//中断标志位

void KEY_INT_INIT (void){	 //按键中断初始化
	NVIC_InitTypeDef  NVIC_InitStruct;	//定义结构体变量
	EXTI_InitTypeDef  EXTI_InitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)     
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);  //定义 GPIO  中断
	
	EXTI_InitStruct.EXTI_Line=EXTI_Line0;  //定义中断线
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发
	
	EXTI_Init(& EXTI_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;   //中断线     
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_Init(& NVIC_InitStruct);

}

void  EXTI0_IRQHandler(void){
	if(EXTI_GetITStatus(EXTI_Line0)!=RESET){//判断某个线上的中断是否发生 
		INT_MARK=1;//标志位置1,表示有按键中断
		EXTI_ClearITPendingBit(EXTI_Line0);   //清除 LINE 上的中断标志位
	}     
}


key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"

//#define KEY1 PAin(0)// PA0
//#define KEY2 PAin(1)// PA1

#define KEYPORT	GPIOA	//定义IO接口组
#define KEY1	GPIO_Pin_0	//定义IO接口
#define KEY2	GPIO_Pin_1	//定义IO接口


void KEY_Init(void);//初始化

		 				    
#endif

key.c

#include "key.h"

void KEY_Init(void){ //微动开关的接口初始化
	GPIO_InitTypeDef  GPIO_InitStructure; //定义GPIO的初始化枚举结构	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2; //选择端口号(0~15或all)                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻       
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    
	GPIO_Init(KEYPORT,&GPIO_InitStructure);			
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "NVIC.h"    //中断向量控制器


int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化
	OLED_DISPLAY_8x16_BUFFER(0,"   SLEEP TEST   "); //显示字符串

	INT_MARK=0;//标志位清0
	NVIC_Configuration();//设置中断优先级
	KEY_INT_INIT();//按键中断初始化(PA0是按键中断输入)

	NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,DISABLE);	//SEVONPEND: 0:只有使能的中断或事件才能唤醒内核。1:任何中断和事件都可以唤醒内核。(0=DISABLE,1=ENABLE) 
	NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,DISABLE);	//SLEEPDEEP: 0:低功耗模式为睡眠模式。1:进入低功耗时为深度睡眠模式。
    NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,DISABLE); //SLEEPONEXIT: 0: 被唤醒进入线程模式后不再进入睡眠模式。1:被唤醒后执行完相应的中断处理函数后进入睡眠模式。

	while(1){

		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
		OLED_DISPLAY_8x16_BUFFER(4,"  CPU SLEEP!    "); //显示字符串
		delay_ms(500); //

		__WFI(); //进入睡眠模式,等待中断唤醒
//		__WFE(); //进入睡眠模式,等待事件唤醒

		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
		OLED_DISPLAY_8x16_BUFFER(4,"  CPU WAKE UP!  "); //显示字符串
		delay_ms(500); //
	}

}

2.停机模式测试程序

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "NVIC.h"


int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化
	OLED_DISPLAY_8x16_BUFFER(0,"   STOP  TEST   "); //显示字符串

	INT_MARK=0;//标志位清0
	NVIC_Configuration();//设置中断优先级
	KEY_INT_INIT();//按键中断初始化(PA0是按键中断输入)
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);  //使能电源PWR时钟

	while(1){
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
		OLED_DISPLAY_8x16_BUFFER(4,"  CPU STOP!     "); //显示字符串
		delay_ms(500); //

		PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式

		RCC_Configuration(); //系统时钟初始化(停机唤醒后会改用HSI时钟,需要重新对时钟初始化) 

		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
		OLED_DISPLAY_8x16_BUFFER(4,"  CPU WAKE UP!  "); //显示字符串
		delay_ms(500); //
	}

}

3.待机模式测试程序

对开发板跳线进行设置

触摸按键将最上方的PA0跳线断开

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"


int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化
	OLED_DISPLAY_8x16_BUFFER(0," STANDBY TEST   "); //显示字符串

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);  //使能电源PWR时钟
	PWR_WakeUpPinCmd(ENABLE);//WKUP唤醒功能开启(待机时WKUP脚PA0为模拟输入)

	GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
	OLED_DISPLAY_8x16_BUFFER(4,"  CPU RESET!    "); //显示字符串
	delay_ms(500); //

	GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
	OLED_DISPLAY_8x16_BUFFER(4,"   STANDBY!     "); //显示字符串
	delay_ms(500); //

	PWR_EnterSTANDBYMode();//进入待机模式

	//因为待机唤醒后程序从头运行,所以不需要加while(1)的主循环体。
}

二:看门狗

是单片机系统功能的一个辅助功能:帮助单片机自我检查、 监控单片机程序是否正常工作

看门狗定时器(WDT,Watch Dog Timer)是单片机的一个组成部分
    它实际上是一个计数器,一般给看门狗计数值,程序开始运行后看门狗开始倒计数
    如果程序运行正常,过一段时间CPU应发出指令让看门狗复位,重新开始倒计数
    如果看门狗减到0就认为程序没有正常工作,强制整个系统复位

    看门狗是一个计数器
    启动后开始倒计时
    每过一段时间CPU要重新写入计数值(喂狗)
    CPU能重写计数值,表示程序运行正常
    如果程序运行出错或死机,则不能重写计数值
    当计数值减到O时,看门狗会让整个单片机复位



看门狗的作用
    看门狗的主要目的是监控单片机程序
    如果程序不断喂狗,就证明单片机工作正常
    如果程序没有喂狗,就说明单片机出了问题
    看门狗不能检查问题的原因,只能通过复位单片机,让程序重新开始运行



类型:独立看门狗、窗口看门狗

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

独立看门狗可在计数到O前随时喂狗

用于监控程序是否正常运行

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

窗口看门狗必须在规定的时间范围内喂狗

作用是监控单片机运行时效是否精确

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

1.独立看门狗测试程序

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 新建文件夹

Basic文件夹——>iwdg文件夹——>iwdg.c  iwdg.h

iwdg.h

#ifndef __IWDG_H
#define __IWDG_H	 
#include "sys.h"

//看门狗定时时间计算公式:Tout=(预分频值*重装载值)/40 (单位:ms)
//当前pre为64,rlr为625,计算得到Tout时间为1秒(大概值)。

#define pre		IWDG_Prescaler_64 //分频值范围:4,8,16,32,64,128,256
#define rlr		625 //重装载值范围:0~0xFFF(4095)


void IWDG_Init(void);
void IWDG_Feed(void);
		 				    
#endif

iwdg.c

#include "iwdg.h"


void IWDG_Init(void){ //初始化独立看门狗
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作
    IWDG_SetPrescaler(pre); //设置IWDG预分频值
    IWDG_SetReload(rlr); //设置IWDG重装载值
    IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
    IWDG_Enable(); //使能IWDG
}

void IWDG_Feed(void){ //喂狗程序
    IWDG_ReloadCounter();//固件库的喂狗函数
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "iwdg.h"

int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化---------------"
	OLED_DISPLAY_8x16_BUFFER(0,"   IWDG TEST    "); //显示字符串
	OLED_DISPLAY_8x16_BUFFER(4,"    RESET!      "); //显示字符串
	delay_ms(800); //
	OLED_DISPLAY_8x16_BUFFER(4,"                "); //显示字符串

	IWDG_Init(); //初始化并启动独立看门狗

	while(1){

		IWDG_Feed(); //喂狗

		if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
			delay_s(2);	//延时2秒,使程序不能喂狗而导致复制
		}
	}
}

2.窗口看门狗测试程序

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 新建文件夹

Basic文件夹——>wwdg文件夹——>wwdg.c  wwdg.h

wwdg.h

#ifndef __WWDG_H
#define __WWDG_H	 
#include "sys.h"

//窗口看门狗定时时间计算公式:
//上窗口超时时间(单位us) = 4096*预分频值*(计数器初始值-窗口值)/APB1时钟频率(单位MHz)
//下窗口超时时间(单位us) = 4096*预分频值*(计数器初始值-0x40)/APB1时钟频率(单位MHz)

#define WWDG_CNT	0x7F //计数器初始值,范围:0x40~0x7F
#define wr		0x50 //窗口值(上窗口边界),范围:0x40~0x7F
#define fprer	WWDG_Prescaler_8 //预分频值,取值:1,2,4,8

//如上三个值是:0x7f,0x50,8时,上窗口48MS,下窗口64MS。

void WWDG_Init(void);
void WWDG_NVIC_Init(void);
void WWDG_Feed(void);
		 				    
#endif

wwdg.c

#include "wwdg.h"


void WWDG_Init(void){ //初始化窗口看门狗
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
	WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值
	WWDG_SetWindowValue(wr); //设置窗口值
	WWDG_Enable(WWDG_CNT); //使能看门狗,设置 counter
	WWDG_ClearFlag(); //清除提前唤醒中断标志位
	WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC
	WWDG_EnableIT(); //开启窗口看门狗中断
}

void WWDG_NVIC_Init(void){ //窗口看门狗中断服务程序(被WWDG_Init调用)
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 3 组 2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 2
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure); //NVIC 初始化
}

void WWDG_Feed(void){ //窗口喂狗程序
    WWDG_SetCounter(WWDG_CNT); //固件库的喂狗函数
}

void WWDG_IRQHandler(void){	//窗口看门狗中断处理程序
	WWDG_ClearFlag(); //清除提前唤醒中断标志位

	//此处加入在复位前需要处理的工作或保存数据
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "wwdg.h"

int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化---------------"
	OLED_DISPLAY_8x16_BUFFER(0,"   WWDG TEST    "); //显示字符串
	OLED_DISPLAY_8x16_BUFFER(4,"    RESET!      "); //显示字符串
	delay_ms(800); //
	OLED_DISPLAY_8x16_BUFFER(4,"                "); //显示字符串

	WWDG_Init(); //初始化并启动独立看门狗

	while(1){
		delay_ms(54); //用延时找到喂狗的窗口时间    避开计数初始值到上窗口边界这段时间
		WWDG_Feed(); //喂狗

		if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
			delay_s(2);	//延时2秒,使程序不能喂狗而导致复制
		}
	}
}

三:TIM定时器

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

定时器的3种功能
    捕获器:测量波形的频率和宽度
    比较器:分为模拟比较器和输出比较器
        模拟比较器:比较两组输入电压的大小(STM32F103无此功能)
        输出比较器:产生可调频率和可调占空比的脉冲波形
    PWM:脉宽调制器,产生固定频率但占空比可调的脉冲波形



普通定时器
    定时器可以用于独立时间计时功能,原理和嘀嗒定时器、看门狗基本相同
    定时时间到时,可等待CPU检查标志位(查寻方式),或产生“定时器中断”
    —般都是让定时器产生中断



捕获器
    捕获什么?    输入接口的电平变化(上升沿或下降沿)
        上升沿:从低电平到高电平
        下降沿:从高电平到低电平

    有什么用?    可测量脉冲的宽度,或者测量脉冲频率
        宽度
            T1是上沿捕获的定时器值
            T2是下沿捕获的定时器值
            T2-T1=高电平宽度值
        频率
            T1是第1次上沿捕获值
            T2是第2次上沿捕获值
            T2-T1=一个周期时间值(频率)

    工作过程!    当接口产生上升沿或下降沿时,将当前定时器值保存




输出比较器
    可输出脉冲,可调占空比和频率
        每一个周期的长度都可以不同
        每一个周期内的占空比都可以不同

    PWM只能调占空比(也是可以通过程序调频率,但不方便随时调)
    输出比较器可随时调占空比和频率

    输出比较器主要用于步进电机、伺服电机的控制

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

定时器中断测试程序

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 新建文件夹

Basic文件夹——>tim文件夹——>tim.c  tim.h

tim.h

#ifndef  __PWM_H
#define  __PWM_H
#include "sys.h"

void TIM3_Init(u16 arr,u16 psc);
void TIM3_NVIC_Init (void);


#endif

tim.c

#include "led.h" //因在中断处理函数中用到LED驱动

#include "tim.h"

//定时器时间计算公式Tout = ((重装载值+1)*(预分频系数+1))/时钟频率;
//例如:1秒定时,重装载值=9999,预分频系数=7199

void TIM3_Init(u16 arr,u16 psc){  //TIM3 初始化 arr重装载值 psc预分频系数
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3
    TIM3_NVIC_Init (); //开启TIM3中断向量
	      
    TIM_TimeBaseInitStrue.TIM_Period=arr; //设置自动重装载值
    TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数
    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数器向上溢出
    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); //TIM3初始化设置
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能TIM3中断    
    TIM_Cmd(TIM3,ENABLE); //使能TIM3
}

void TIM3_NVIC_Init (void){ //开启TIM3中断向量
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;	
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3;	//设置抢占和子优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void TIM3_IRQHandler(void){ //TIM3中断处理函数
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){	//判断是否是TIM3中断
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

        //此处写入用户自己的处理程序
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
    }
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "tim.h"


int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化---------------"
	OLED_DISPLAY_8x16_BUFFER(0,"   TIM TEST     "); //显示字符串

	TIM3_Init(9999,7199);//定时器初始化,定时1秒(9999,7199)

	while(1){

	//写入用户的程序
	//LED1闪烁程序在TIM3的中断处理函数中执行


	}
}

四:CRC循环冗余校验计算单元与芯片ID

1.CRC功能测试程序

CRC(循环冗余校验)计算单元
    使用一个固定的多项式发生器,从一个32位的数据字产生一个CRC码在众多的应用中,基于CRC的技术被用于验证数据传输或存储的一致性
    在EN/IEC 60335-1标准的范围内,它提供了一种检测闪存存储器错误的手段,CRC计算单元可以用于实时地计算软件的签名,并与在链接和生成该软件时产生的签名对比。
        √CRC是用于数据正确性校验的
        √由一个32位的数据字产生√可应用在FALSH检测
        √可用于软件签名及对比
    特点:写入和读出都是同一个寄存器,但内容却不同

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"


int main (void){//主程序
	u32 a,b;
	u8 c;
	u32 y[3]={0x87654321,0x98765432,0x09876543};
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化---------------"
	OLED_DISPLAY_8x16_BUFFER(0,"   CRC TEST     "); //显示字符串

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//开启CRC时钟

	while(1){
		CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
		CRC_CalcCRC(0x12345678);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
		CRC_CalcCRC(0x23456789);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
		a = CRC_CalcCRC(0x34567890);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果

		CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
		b = CRC_CalcBlockCRC(y,3);//CRC计算一个32位数组。参数:32位数组名,数组长度。返回值:32位计算结果

		CRC_SetIDRegister(0x5a);//向独立寄存器CRC_IDR写数据。参数:8位数据。
		c = CRC_GetIDRegister();//从独立寄存器CRC_IDR读数据。返回值:8位数据。

		//此时,a存放的是3个独立数的CRC结果。(32位)
		//b存放的是数组y中3个数据CRC计算结果。(32位)
		//c存放的是我们写入的独立寄存器数据0x5a。(8位)
	}
}

//	以下是CRC固件库函数,可在主程序中直接调用  //

//	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//开启CRC时钟,主程序开始时调用
//	CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
//	uint32_t CRC_CalcCRC(uint32_t Data);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
//	uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);//CRC计算一个32位数组。参数:32位数组名,数组长度。返回值:32位计算结果
//	uint32_t CRC_GetCRC(void);//从CRC中读出计算结果。返回值:32位计算结果。

//	void CRC_SetIDRegister(uint8_t IDValue);//向独立寄存器CRC_IDR写数据。参数:8位数据。
//	uint8_t CRC_GetIDRegister(void);//从独立寄存器CRC_IDR读数据。返回值:8位数据。

stm32f10x_crc. c包含了CRC的固件库函数

2.芯片ID读取程序

芯片ID
    √ 96位ID编码
    √可读出3个32位数据,或8个8位数据
    √可以以字节(8位)为单位读取,也可以以半字(16位)或者全字(32位)读取
    √每个芯片编码是唯一的,出厂时固化,不可修改
    √ 可用于产品序列号
    √用来作为密码,提高安全性    
    √用来保护程序的不可复制

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

 STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记

STM32基础入门学习笔记:内部高级功能应用,# STM32,学习,笔记文章来源地址https://www.toymoban.com/news/detail-637298.html

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "led.h"
#include "key.h"

#include "usart.h"

int main (void){//主程序
	u32 ID[3];
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	RELAY_Init();//继电器初始化
	LED_Init();//LED 
	KEY_Init();//KEY

	USART1_Init(115200); //串口初始化(参数是波特率)
	I2C_Configuration();//I2C初始化

	OLED0561_Init(); //OLED初始化---------------"
	OLED_DISPLAY_8x16_BUFFER(0,"  CHIP ID TEST  "); //显示字符串

	ID[0] = *(__IO u32 *)(0X1FFFF7E8); //读出3个32位ID 高字节
	ID[1] = *(__IO u32 *)(0X1FFFF7EC); // 
	ID[2] = *(__IO u32 *)(0X1FFFF7F0); // 低字节

    //08表示后面的数据不足8位就补0显示
	printf("ChipID: %08X %08X %8X \r\n",ID[0],ID[1],ID[2]); //从串口输出16进制ID

	if(ID[0]==0x066EFF34 && ID[1]==0x3437534D && ID[2]==0x43232328){ //检查ID是否匹配
		printf("chipID OK! \r\n"); //匹配
	}else{
		printf("chipID error! \r\n"); //不同
	}

	while(1){

	}
}

五:还需要补充的知识

1.仿真
    仿真接口有JTAG、SW接口,仿真器又有ST-LINK、J-LINK等
    还有纯软件仿真Proteus等


2.HEL库


3.内置USB接口
    USB鼠标、键盘、U盘


4.显示屏
    除OLED之外,还能外扩LCD1602、12864等
    显示屏的类型还有VOG屏、TFT屏等
    每种屏的接口也分好多种


5.定时器的复杂功能
    TIM1高级定时器的使用
    单脉冲模式
    输出比较器的使用
    捕获器的使用
    定时器的DMA设置


6.中断的复杂功能
    中断嵌套应用与优先级问题
    外部中断的端口映射问题


7.单片机内部功能
    WIFI、蓝牙、GPS模块、2.4G模块、彩屏的人机界面、RTOS嵌入式操作系统....

到了这里,关于STM32基础入门学习笔记:内部高级功能应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32基于CubeIDE和HAL库 基础入门学习笔记:物联网项目开发流程和思路

    文章目录: 第一部分:项目开始前的计划与准备 1.项目策划和开发规范  1.1 项目要求文档 1.2 技术实现文档 1.3 开发规范 2.创建项目工程与日志 第二部分:调通硬件电路与驱动程序 第三部分:编写最基础的应用程序 第四部分:完成最终要求、反复调试 第五部分:程序优化、

    2024年02月13日
    浏览(48)
  • STM32 学习笔记(六)定时器中断:内部时钟模式,外部时钟模式

    定时器是功能最强大,内容最复杂的32结构。 之前51用过的功能,定时产生中断。 输出比较,常用于产生 PWM 波形,驱动电机等。 输入捕获,测量方波频率。 编码器,读取正交编码器的波形。 最大定时时间:72M/65536/65536=中断频率,中断频率取倒数是最大定时时间。 定时器可

    2024年02月08日
    浏览(52)
  • STM32CubeMX学习笔记(47)——USB接口使用(MSC基于内部Flash模拟U盘)

    USB(Universal Serial BUS)通用串行总线 ,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、Microsoft 等多家公司联合提出的。 USB 发展到现在已经有 US

    2024年02月15日
    浏览(44)
  • C/C++|物联网开发入门+项目实战|空间读写|非字符空间|返回值内部实现|嵌入式C语言高级|C语言函数的使用(2)-学习笔记(12)

    参考: 麦子学院-嵌入式C语言高级-C语言函数的使用 空间的读写 void fun(char *p); const char *p 只读空间,只为了看 char *p;该空间可能修改,几乎都要变 strcpy(); 定义:char *strcpy(char *dest,const char *src); sprintf(); 作用 1、修改 int * short * long * 2、空间传递 2.1 子函数看看空间里的情况

    2023年04月22日
    浏览(62)
  • STM32学习笔记(4) 高级定时器-两路互补的PWM输出(带死区和刹车控制)

    目录 1.实验目的 2.实验效果 3.理论部分 3.1时钟源 3.2时基单元 3.3输入捕获 4.程序流程 4.1GPIO初始化结构体 4.2时基初始化结构体 4.3输出比较结构体 4.4刹车和死区结构体的初始化 5.程序源码 使用高级定时器,输出两路互补的PWM输出,需要有带死区和不带死区两种情况 图1:不带

    2024年02月13日
    浏览(40)
  • STM32单片机入门学习笔记——MPU6050

    笔记整理自B站UP主江科大自化协教程《[10-2] MPU6050简介_哔哩哔哩_bilibili》,所用单片机也为教程推荐单片机。 如果芯片里再集成一个3轴的磁场传感器,测量XYZ轴的磁场强度,那就叫做9轴姿态传感器,如果再集成一个气压传感器,测量气压大小,那就叫做10轴姿态传感器,一

    2024年02月08日
    浏览(49)
  • 嵌入式学习笔记——STM32硬件基础知识

    上一篇中我们重点是讲了一下怎么搭建开发环境以及怎么下载烧录的过程,这都是解决的电脑端的开发环境问题,还没有到实际的开发板上,我们的单片机是都是焊接在开发板上的,PCB上有着它所需的工作电路。并不是直接给供电电压就可以让其工作的,本文主要是简介一下

    2024年01月22日
    浏览(68)
  • 【正点原子】STM32电机应用控制学习笔记——8.FOC简介

    FOC是适用于无刷电机的,而像有刷电机,舵机,步进电机是不适用FOC的。FOC是电机应用控制难度最大的部分了。 FOC(Filed Oriented Control)即磁场定向控制,又称磁场矢量控制(VC,Vector Control),也就是控制磁场的方向以及大小。 无刷电机的无感控制是六步换向,设定初始电流

    2024年01月22日
    浏览(46)
  • 【STM32&RT-Thread零基础入门】 7. 线程创建应用(多线程运行机制)

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 本章进一步研究多线程的运行机制。要求实现功能如下:创建2个线程,线程名称分别为LED和BEEP。两个线程的任务是连续5次打印本线程的名字后退出线程(注意:线程不执行

    2024年02月03日
    浏览(35)
  • STM32单片机入门学习笔记——定时器TIM第二部分

    笔记整理自B站UP主 江科大自化协 教程 《STM32入门教程-2023持续更新中》 ,所用单片机也为教程推荐单片机。 第一部分:定时器基本定时的功能,定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算

    2024年02月08日
    浏览(50)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包