• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
刘鑫磊up
帮助1

文章目录:

一:低功耗模式

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

五:还需要补充的知识


这些是单片机的辅助功能

一:低功耗模式

  1.  
    单片机内部功率是各功能部分功率的总和
  2.  
     
  3.  
    低功耗模式是通过关掉部分内部功能达到省电
  4.  
     
  5.  
    STM32F103单片机共有3种低功耗模式
  6.  
     
  7.  
    不同模式会对系统正常工作有一定影响,需要按实际情况选择
  8.  
     
  9.  
    低功耗模式只针对单片机内部功能,外接电路产生的功耗不在其内
  10.  
     
  11.  
     
  12.  
     
  13.  
    单片机最小系统电路功耗,不精确测量值
  14.  
    √正常模式:10mA
  15.  
    √睡眠模式:2mA
  16.  
    √停机模式:20uA
  17.  
    √待机模式:2uA
  18.  
     
  19.  
     
  20.  
    睡眠模式
  21.  
    在ARM内核无事可做的时候,可以进入睡眠模式
  22.  
    例如:电脑的CPU空闲状态就是单片机睡眠模式
  23.  
     
  24.  
    睡眠模式的应用不多,因只关闭ARM内核,节能有限,很少在非操作系统程序(裸机)中使用
  25.  
    在嵌入式操作系统中,会采用睡眠模式
  26.  
     
  27.  
    优点:对系统影响最小
  28.  
    缺点:节能效果最差
  29.  
     
  30.  
     
  31.  
    停机模式
  32.  
    因SRAM内容不消失,程序不复位,可在唤醒后继续运行
  33.  
    节能效果与待机模式近似,却有着更多优势
  34.  
     
  35.  
    主要用于电池供电的设备上,提高电池寿命
  36.  
    在电池供电的产品中必须使用,在外部供电的产品中没必要使用
  37.  
     
  38.  
    优点:节能效果好,程序不会复位
  39.  
    缺点:恢复时间较长
  40.  
     
  41.  
     
  42.  
     
  43.  
    待机模式
  44.  
    由于SRAM内容消失,唤醒后程序必须复位,从头开始运行
  45.  
     
  46.  
    因为待机和停机之间的功耗差别是uA级的,几乎没有差别,所以开发者大多使用停机模式,待机模式极少使用
  47.  
    在一些偶尔需要工作的场合,且工作量不大、不复杂的情况下,待机模式可以保证最低的功耗
  48.  
    比如应用在室外温度测量产品上,每1小时测量一次。可用RTC闹钟唤醒,测量完再待机。、
  49.  
     
  50.  
    优点:最节能
  51.  
    缺点:程序会复位,只有少数条件可唤醒
  52.  
     
学新通

学新通

 学新通

1.睡眠模式测试程序

学新通学新通

NVIC.h

  1.  
    #ifndef __NVIC_H
  2.  
    #define __NVIC_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
     
  6.  
    extern u8 INT_MARK;//中断标志位
  7.  
     
  8.  
     
  9.  
    void KEY_INT_INIT (void);
  10.  
     
  11.  
    #endif

NVIC.c

  1.  
    #include "NVIC.h"
  2.  
     
  3.  
    u8 INT_MARK;//中断标志位
  4.  
     
  5.  
    void KEY_INT_INIT (void){ //按键中断初始化
  6.  
    NVIC_InitTypeDef NVIC_InitStruct; //定义结构体变量
  7.  
    EXTI_InitTypeDef EXTI_InitStruct;
  8.  
     
  9.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)
  10.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟
  11.  
     
  12.  
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //定义 GPIO 中断
  13.  
     
  14.  
    EXTI_InitStruct.EXTI_Line=EXTI_Line0; //定义中断线
  15.  
    EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中断使能
  16.  
    EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中断模式为 中断
  17.  
    EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
  18.  
     
  19.  
    EXTI_Init(& EXTI_InitStruct);
  20.  
     
  21.  
    NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn; //中断线
  22.  
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中断
  23.  
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //抢占优先级 2
  24.  
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子优先级 2
  25.  
    NVIC_Init(& NVIC_InitStruct);
  26.  
     
  27.  
    }
  28.  
     
  29.  
    void EXTI0_IRQHandler(void){
  30.  
    if(EXTI_GetITStatus(EXTI_Line0)!=RESET){//判断某个线上的中断是否发生
  31.  
    INT_MARK=1;//标志位置1,表示有按键中断
  32.  
    EXTI_ClearITPendingBit(EXTI_Line0); //清除 LINE 上的中断标志位
  33.  
    }
  34.  
    }
  35.  
     
  36.  
     
学新通

key.h

  1.  
    #ifndef __KEY_H
  2.  
    #define __KEY_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
    //#define KEY1 PAin(0)// PA0
  6.  
    //#define KEY2 PAin(1)// PA1
  7.  
     
  8.  
    #define KEYPORT GPIOA //定义IO接口组
  9.  
    #define KEY1 GPIO_Pin_0 //定义IO接口
  10.  
    #define KEY2 GPIO_Pin_1 //定义IO接口
  11.  
     
  12.  
     
  13.  
    void KEY_Init(void);//初始化
  14.  
     
  15.  
     
  16.  
    #endif
学新通

key.c

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

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "NVIC.h" //中断向量控制器
  10.  
     
  11.  
     
  12.  
    int main (void){//主程序
  13.  
    delay_ms(500); //上电时等待其他器件就绪
  14.  
    RCC_Configuration(); //系统时钟初始化
  15.  
    RELAY_Init();//继电器初始化
  16.  
    LED_Init();//LED
  17.  
    KEY_Init();//KEY
  18.  
     
  19.  
    I2C_Configuration();//I2C初始化
  20.  
     
  21.  
    OLED0561_Init(); //OLED初始化
  22.  
    OLED_DISPLAY_8x16_BUFFER(0," SLEEP TEST "); //显示字符串
  23.  
     
  24.  
    INT_MARK=0;//标志位清0
  25.  
    NVIC_Configuration();//设置中断优先级
  26.  
    KEY_INT_INIT();//按键中断初始化(PA0是按键中断输入)
  27.  
     
  28.  
    NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,DISABLE); //SEVONPEND: 0:只有使能的中断或事件才能唤醒内核。1:任何中断和事件都可以唤醒内核。(0=DISABLE,1=ENABLE)
  29.  
    NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,DISABLE); //SLEEPDEEP: 0:低功耗模式为睡眠模式。1:进入低功耗时为深度睡眠模式。
  30.  
    NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,DISABLE); //SLEEPONEXIT: 0: 被唤醒进入线程模式后不再进入睡眠模式。1:被唤醒后执行完相应的中断处理函数后进入睡眠模式。
  31.  
     
  32.  
    while(1){
  33.  
     
  34.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
  35.  
    OLED_DISPLAY_8x16_BUFFER(4," CPU SLEEP! "); //显示字符串
  36.  
    delay_ms(500); //
  37.  
     
  38.  
    __WFI(); //进入睡眠模式,等待中断唤醒
  39.  
    // __WFE(); //进入睡眠模式,等待事件唤醒
  40.  
     
  41.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
  42.  
    OLED_DISPLAY_8x16_BUFFER(4," CPU WAKE UP! "); //显示字符串
  43.  
    delay_ms(500); //
  44.  
    }
  45.  
     
  46.  
    }
学新通

2.停机模式测试程序

学新通学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "NVIC.h"
  10.  
     
  11.  
     
  12.  
    int main (void){//主程序
  13.  
    delay_ms(500); //上电时等待其他器件就绪
  14.  
    RCC_Configuration(); //系统时钟初始化
  15.  
    RELAY_Init();//继电器初始化
  16.  
    LED_Init();//LED
  17.  
    KEY_Init();//KEY
  18.  
     
  19.  
    I2C_Configuration();//I2C初始化
  20.  
     
  21.  
    OLED0561_Init(); //OLED初始化
  22.  
    OLED_DISPLAY_8x16_BUFFER(0," STOP TEST "); //显示字符串
  23.  
     
  24.  
    INT_MARK=0;//标志位清0
  25.  
    NVIC_Configuration();//设置中断优先级
  26.  
    KEY_INT_INIT();//按键中断初始化(PA0是按键中断输入)
  27.  
     
  28.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //使能电源PWR时钟
  29.  
     
  30.  
    while(1){
  31.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
  32.  
    OLED_DISPLAY_8x16_BUFFER(4," CPU STOP! "); //显示字符串
  33.  
    delay_ms(500); //
  34.  
     
  35.  
    PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式
  36.  
     
  37.  
    RCC_Configuration(); //系统时钟初始化(停机唤醒后会改用HSI时钟,需要重新对时钟初始化)
  38.  
     
  39.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
  40.  
    OLED_DISPLAY_8x16_BUFFER(4," CPU WAKE UP! "); //显示字符串
  41.  
    delay_ms(500); //
  42.  
    }
  43.  
     
  44.  
    }
学新通

3.待机模式测试程序

对开发板跳线进行设置

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

学新通学新通

 学新通学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
     
  8.  
     
  9.  
    int main (void){//主程序
  10.  
    delay_ms(500); //上电时等待其他器件就绪
  11.  
    RCC_Configuration(); //系统时钟初始化
  12.  
    RELAY_Init();//继电器初始化
  13.  
    LED_Init();//LED
  14.  
     
  15.  
    I2C_Configuration();//I2C初始化
  16.  
     
  17.  
    OLED0561_Init(); //OLED初始化
  18.  
    OLED_DISPLAY_8x16_BUFFER(0," STANDBY TEST "); //显示字符串
  19.  
     
  20.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //使能电源PWR时钟
  21.  
    PWR_WakeUpPinCmd(ENABLE);//WKUP唤醒功能开启(待机时WKUP脚PA0为模拟输入)
  22.  
     
  23.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制
  24.  
    OLED_DISPLAY_8x16_BUFFER(4," CPU RESET! "); //显示字符串
  25.  
    delay_ms(500); //
  26.  
     
  27.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制
  28.  
    OLED_DISPLAY_8x16_BUFFER(4," STANDBY! "); //显示字符串
  29.  
    delay_ms(500); //
  30.  
     
  31.  
    PWR_EnterSTANDBYMode();//进入待机模式
  32.  
     
  33.  
    //因为待机唤醒后程序从头运行,所以不需要加while(1)的主循环体。
  34.  
    }
学新通

二:看门狗

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

  1.  
    看门狗定时器(WDT,Watch Dog Timer)是单片机的一个组成部分
  2.  
    它实际上是一个计数器,一般给看门狗计数值,程序开始运行后看门狗开始倒计数
  3.  
    如果程序运行正常,过一段时间CPU应发出指令让看门狗复位,重新开始倒计数
  4.  
    如果看门狗减到0就认为程序没有正常工作,强制整个系统复位
  5.  
     
  6.  
    看门狗是一个计数器
  7.  
    启动后开始倒计时
  8.  
    每过一段时间CPU要重新写入计数值(喂狗)
  9.  
    CPU能重写计数值,表示程序运行正常
  10.  
    如果程序运行出错或死机,则不能重写计数值
  11.  
    当计数值减到O时,看门狗会让整个单片机复位
  12.  
     
  13.  
     
  14.  
     
  15.  
    看门狗的作用
  16.  
    看门狗的主要目的是监控单片机程序
  17.  
    如果程序不断喂狗,就证明单片机工作正常
  18.  
    如果程序没有喂狗,就说明单片机出了问题
  19.  
    看门狗不能检查问题的原因,只能通过复位单片机,让程序重新开始运行
  20.  
     
  21.  
     
  22.  
     
  23.  
    类型:独立看门狗、窗口看门狗
学新通

学新通

  1.  
    独立看门狗可在计数到O前随时喂狗
  2.  
     
  3.  
    用于监控程序是否正常运行

 学新通学新通

  1.  
    窗口看门狗必须在规定的时间范围内喂狗
  2.  
     
  3.  
    作用是监控单片机运行时效是否精确

 学新通学新通

1.独立看门狗测试程序

学新通学新通

 新建文件夹

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

iwdg.h

  1.  
    #ifndef __IWDG_H
  2.  
    #define __IWDG_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
    //看门狗定时时间计算公式:Tout=(预分频值*重装载值)/40 (单位:ms)
  6.  
    //当前pre为64,rlr为625,计算得到Tout时间为1秒(大概值)。
  7.  
     
  8.  
    #define pre IWDG_Prescaler_64 //分频值范围:4,8,16,32,64,128,256
  9.  
    #define rlr 625 //重装载值范围:0~0xFFF(4095)
  10.  
     
  11.  
     
  12.  
    void IWDG_Init(void);
  13.  
    void IWDG_Feed(void);
  14.  
     
  15.  
    #endif
学新通

iwdg.c

  1.  
    #include "iwdg.h"
  2.  
     
  3.  
     
  4.  
    void IWDG_Init(void){ //初始化独立看门狗
  5.  
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作
  6.  
    IWDG_SetPrescaler(pre); //设置IWDG预分频值
  7.  
    IWDG_SetReload(rlr); //设置IWDG重装载值
  8.  
    IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
  9.  
    IWDG_Enable(); //使能IWDG
  10.  
    }
  11.  
     
  12.  
    void IWDG_Feed(void){ //喂狗程序
  13.  
    IWDG_ReloadCounter();//固件库的喂狗函数
  14.  
    }

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "iwdg.h"
  10.  
     
  11.  
    int main (void){//主程序
  12.  
    delay_ms(500); //上电时等待其他器件就绪
  13.  
    RCC_Configuration(); //系统时钟初始化
  14.  
    RELAY_Init();//继电器初始化
  15.  
    LED_Init();//LED
  16.  
    KEY_Init();//KEY
  17.  
     
  18.  
    I2C_Configuration();//I2C初始化
  19.  
     
  20.  
    OLED0561_Init(); //OLED初始化---------------"
  21.  
    OLED_DISPLAY_8x16_BUFFER(0," IWDG TEST "); //显示字符串
  22.  
    OLED_DISPLAY_8x16_BUFFER(4," RESET! "); //显示字符串
  23.  
    delay_ms(800); //
  24.  
    OLED_DISPLAY_8x16_BUFFER(4," "); //显示字符串
  25.  
     
  26.  
    IWDG_Init(); //初始化并启动独立看门狗
  27.  
     
  28.  
    while(1){
  29.  
     
  30.  
    IWDG_Feed(); //喂狗
  31.  
     
  32.  
    if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
  33.  
    delay_s(2); //延时2秒,使程序不能喂狗而导致复制
  34.  
    }
  35.  
    }
  36.  
    }
学新通

2.窗口看门狗测试程序

学新通学新通

 新建文件夹

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

wwdg.h

  1.  
    #ifndef __WWDG_H
  2.  
    #define __WWDG_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
    //窗口看门狗定时时间计算公式:
  6.  
    //上窗口超时时间(单位us) = 4096*预分频值*(计数器初始值-窗口值)/APB1时钟频率(单位MHz)
  7.  
    //下窗口超时时间(单位us) = 4096*预分频值*(计数器初始值-0x40)/APB1时钟频率(单位MHz)
  8.  
     
  9.  
    #define WWDG_CNT 0x7F //计数器初始值,范围:0x400x7F
  10.  
    #define wr 0x50 //窗口值(上窗口边界),范围:0x400x7F
  11.  
    #define fprer WWDG_Prescaler_8 //预分频值,取值:1,2,4,8
  12.  
     
  13.  
    //如上三个值是:0x7f,0x508时,上窗口48MS,下窗口64MS。
  14.  
     
  15.  
    void WWDG_Init(void);
  16.  
    void WWDG_NVIC_Init(void);
  17.  
    void WWDG_Feed(void);
  18.  
     
  19.  
    #endif
学新通

wwdg.c

  1.  
    #include "wwdg.h"
  2.  
     
  3.  
     
  4.  
    void WWDG_Init(void){ //初始化窗口看门狗
  5.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
  6.  
    WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值
  7.  
    WWDG_SetWindowValue(wr); //设置窗口值
  8.  
    WWDG_Enable(WWDG_CNT); //使能看门狗,设置 counter
  9.  
    WWDG_ClearFlag(); //清除提前唤醒中断标志位
  10.  
    WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC
  11.  
    WWDG_EnableIT(); //开启窗口看门狗中断
  12.  
    }
  13.  
     
  14.  
    void WWDG_NVIC_Init(void){ //窗口看门狗中断服务程序(被WWDG_Init调用)
  15.  
    NVIC_InitTypeDef NVIC_InitStructure;
  16.  
    NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中断
  17.  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 32
  18.  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 2
  19.  
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  20.  
    NVIC_Init(&NVIC_InitStructure); //NVIC 初始化
  21.  
    }
  22.  
     
  23.  
    void WWDG_Feed(void){ //窗口喂狗程序
  24.  
    WWDG_SetCounter(WWDG_CNT); //固件库的喂狗函数
  25.  
    }
  26.  
     
  27.  
    void WWDG_IRQHandler(void){ //窗口看门狗中断处理程序
  28.  
    WWDG_ClearFlag(); //清除提前唤醒中断标志位
  29.  
     
  30.  
    //此处加入在复位前需要处理的工作或保存数据
  31.  
    }
学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "wwdg.h"
  10.  
     
  11.  
    int main (void){//主程序
  12.  
    delay_ms(500); //上电时等待其他器件就绪
  13.  
    RCC_Configuration(); //系统时钟初始化
  14.  
    RELAY_Init();//继电器初始化
  15.  
    LED_Init();//LED
  16.  
    KEY_Init();//KEY
  17.  
     
  18.  
    I2C_Configuration();//I2C初始化
  19.  
     
  20.  
    OLED0561_Init(); //OLED初始化---------------"
  21.  
    OLED_DISPLAY_8x16_BUFFER(0," WWDG TEST "); //显示字符串
  22.  
    OLED_DISPLAY_8x16_BUFFER(4," RESET! "); //显示字符串
  23.  
    delay_ms(800); //
  24.  
    OLED_DISPLAY_8x16_BUFFER(4," "); //显示字符串
  25.  
     
  26.  
    WWDG_Init(); //初始化并启动独立看门狗
  27.  
     
  28.  
    while(1){
  29.  
    delay_ms(54); //用延时找到喂狗的窗口时间 避开计数初始值到上窗口边界这段时间
  30.  
    WWDG_Feed(); //喂狗
  31.  
     
  32.  
    if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
  33.  
    delay_s(2); //延时2秒,使程序不能喂狗而导致复制
  34.  
    }
  35.  
    }
  36.  
    }
学新通

三:TIM定时器

学新通

 学新通

  1.  
    定时器的3种功能
  2.  
    捕获器:测量波形的频率和宽度
  3.  
    比较器:分为模拟比较器和输出比较器
  4.  
    模拟比较器:比较两组输入电压的大小(STM32F103无此功能)
  5.  
    输出比较器:产生可调频率和可调占空比的脉冲波形
  6.  
    PWM:脉宽调制器,产生固定频率但占空比可调的脉冲波形
  7.  
     
  8.  
     
  9.  
     
  10.  
    普通定时器
  11.  
    定时器可以用于独立时间计时功能,原理和嘀嗒定时器、看门狗基本相同
  12.  
    定时时间到时,可等待CPU检查标志位(查寻方式),或产生“定时器中断”
  13.  
    —般都是让定时器产生中断
  14.  
     
  15.  
     
  16.  
     
  17.  
    捕获器
  18.  
    捕获什么? 输入接口的电平变化(上升沿或下降沿)
  19.  
    上升沿:从低电平到高电平
  20.  
    下降沿:从高电平到低电平
  21.  
     
  22.  
    有什么用? 可测量脉冲的宽度,或者测量脉冲频率
  23.  
    宽度
  24.  
    T1是上沿捕获的定时器值
  25.  
    T2是下沿捕获的定时器值
  26.  
    T2-T1=高电平宽度值
  27.  
    频率
  28.  
    T1是第1次上沿捕获值
  29.  
    T2是第2次上沿捕获值
  30.  
    T2-T1=一个周期时间值(频率)
  31.  
     
  32.  
    工作过程! 当接口产生上升沿或下降沿时,将当前定时器值保存
  33.  
     
  34.  
     
  35.  
     
  36.  
     
  37.  
    输出比较器
  38.  
    可输出脉冲,可调占空比和频率
  39.  
    每一个周期的长度都可以不同
  40.  
    每一个周期内的占空比都可以不同
  41.  
     
  42.  
    PWM只能调占空比(也是可以通过程序调频率,但不方便随时调)
  43.  
    输出比较器可随时调占空比和频率
  44.  
     
  45.  
    输出比较器主要用于步进电机、伺服电机的控制
学新通

学新通

定时器中断测试程序

学新通

 新建文件夹

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

tim.h

  1.  
    #ifndef __PWM_H
  2.  
    #define __PWM_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
    void TIM3_Init(u16 arr,u16 psc);
  6.  
    void TIM3_NVIC_Init (void);
  7.  
     
  8.  
     
  9.  
    #endif

tim.c

  1.  
    #include "led.h" //因在中断处理函数中用到LED驱动
  2.  
     
  3.  
    #include "tim.h"
  4.  
     
  5.  
    //定时器时间计算公式Tout = ((重装载值 1)*(预分频系数 1))/时钟频率;
  6.  
    //例如:1秒定时,重装载值=9999,预分频系数=7199
  7.  
     
  8.  
    void TIM3_Init(u16 arr,u16 psc){ //TIM3 初始化 arr重装载值 psc预分频系数
  9.  
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
  10.  
     
  11.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3
  12.  
    TIM3_NVIC_Init (); //开启TIM3中断向量
  13.  
     
  14.  
    TIM_TimeBaseInitStrue.TIM_Period=arr; //设置自动重装载值
  15.  
    TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数
  16.  
    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数器向上溢出
  17.  
    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
  18.  
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); //TIM3初始化设置
  19.  
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能TIM3中断
  20.  
    TIM_Cmd(TIM3,ENABLE); //使能TIM3
  21.  
    }
  22.  
     
  23.  
    void TIM3_NVIC_Init (void){ //开启TIM3中断向量
  24.  
    NVIC_InitTypeDef NVIC_InitStructure;
  25.  
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  26.  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3; //设置抢占和子优先级
  27.  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
  28.  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  29.  
    NVIC_Init(&NVIC_InitStructure);
  30.  
    }
  31.  
     
  32.  
    void TIM3_IRQHandler(void){ //TIM3中断处理函数
  33.  
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){ //判断是否是TIM3中断
  34.  
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
  35.  
     
  36.  
    //此处写入用户自己的处理程序
  37.  
    GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
  38.  
    }
  39.  
    }
学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "tim.h"
  10.  
     
  11.  
     
  12.  
    int main (void){//主程序
  13.  
    delay_ms(500); //上电时等待其他器件就绪
  14.  
    RCC_Configuration(); //系统时钟初始化
  15.  
    RELAY_Init();//继电器初始化
  16.  
    LED_Init();//LED
  17.  
    KEY_Init();//KEY
  18.  
     
  19.  
    I2C_Configuration();//I2C初始化
  20.  
     
  21.  
    OLED0561_Init(); //OLED初始化---------------"
  22.  
    OLED_DISPLAY_8x16_BUFFER(0," TIM TEST "); //显示字符串
  23.  
     
  24.  
    TIM3_Init(9999,7199);//定时器初始化,定时1秒(9999,7199)
  25.  
     
  26.  
    while(1){
  27.  
     
  28.  
    //写入用户的程序
  29.  
    //LED1闪烁程序在TIM3的中断处理函数中执行
  30.  
     
  31.  
     
  32.  
    }
  33.  
    }
学新通

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

1.CRC功能测试程序

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

学新通学新通

 学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
     
  10.  
    int main (void){//主程序
  11.  
    u32 a,b;
  12.  
    u8 c;
  13.  
    u32 y[3]={0x87654321,0x98765432,0x09876543};
  14.  
    delay_ms(500); //上电时等待其他器件就绪
  15.  
    RCC_Configuration(); //系统时钟初始化
  16.  
    RELAY_Init();//继电器初始化
  17.  
    LED_Init();//LED
  18.  
    KEY_Init();//KEY
  19.  
     
  20.  
    I2C_Configuration();//I2C初始化
  21.  
     
  22.  
    OLED0561_Init(); //OLED初始化---------------"
  23.  
    OLED_DISPLAY_8x16_BUFFER(0," CRC TEST "); //显示字符串
  24.  
     
  25.  
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//开启CRC时钟
  26.  
     
  27.  
    while(1){
  28.  
    CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
  29.  
    CRC_CalcCRC(0x12345678);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
  30.  
    CRC_CalcCRC(0x23456789);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
  31.  
    a = CRC_CalcCRC(0x34567890);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
  32.  
     
  33.  
    CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
  34.  
    b = CRC_CalcBlockCRC(y,3);//CRC计算一个32位数组。参数:32位数组名,数组长度。返回值:32位计算结果
  35.  
     
  36.  
    CRC_SetIDRegister(0x5a);//向独立寄存器CRC_IDR写数据。参数:8位数据。
  37.  
    c = CRC_GetIDRegister();//从独立寄存器CRC_IDR读数据。返回值:8位数据。
  38.  
     
  39.  
    //此时,a存放的是3个独立数的CRC结果。(32位)
  40.  
    //b存放的是数组y中3个数据CRC计算结果。(32位)
  41.  
    //c存放的是我们写入的独立寄存器数据0x5a。(8位)
  42.  
    }
  43.  
    }
  44.  
     
  45.  
    // 以下是CRC固件库函数,可在主程序中直接调用 //
  46.  
     
  47.  
    // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//开启CRC时钟,主程序开始时调用
  48.  
    // CRC_ResetDR();//复位CRC,需要清0重新计算时先复位
  49.  
    // uint32_t CRC_CalcCRC(uint32_t Data);//CRC计算一个32位数据。参数:32位数据。返回值:32位计算结果
  50.  
    // uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);//CRC计算一个32位数组。参数:32位数组名,数组长度。返回值:32位计算结果
  51.  
    // uint32_t CRC_GetCRC(void);//从CRC中读出计算结果。返回值:32位计算结果。
  52.  
     
  53.  
    // void CRC_SetIDRegister(uint8_t IDValue);//向独立寄存器CRC_IDR写数据。参数:8位数据。
  54.  
    // uint8_t CRC_GetIDRegister(void);//从独立寄存器CRC_IDR读数据。返回值:8位数据。
学新通

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

2.芯片ID读取程序

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

学新通

 学新通

学新通

main.c

  1.  
    #include "stm32f10x.h" //STM32头文件
  2.  
    #include "sys.h"
  3.  
    #include "delay.h"
  4.  
    #include "relay.h"
  5.  
    #include "oled0561.h"
  6.  
    #include "led.h"
  7.  
    #include "key.h"
  8.  
     
  9.  
    #include "usart.h"
  10.  
     
  11.  
    int main (void){//主程序
  12.  
    u32 ID[3];
  13.  
    delay_ms(500); //上电时等待其他器件就绪
  14.  
    RCC_Configuration(); //系统时钟初始化
  15.  
    RELAY_Init();//继电器初始化
  16.  
    LED_Init();//LED
  17.  
    KEY_Init();//KEY
  18.  
     
  19.  
    USART1_Init(115200); //串口初始化(参数是波特率)
  20.  
    I2C_Configuration();//I2C初始化
  21.  
     
  22.  
    OLED0561_Init(); //OLED初始化---------------"
  23.  
    OLED_DISPLAY_8x16_BUFFER(0," CHIP ID TEST "); //显示字符串
  24.  
     
  25.  
    ID[0] = *(__IO u32 *)(0X1FFFF7E8); //读出3个32位ID 高字节
  26.  
    ID[1] = *(__IO u32 *)(0X1FFFF7EC); //
  27.  
    ID[2] = *(__IO u32 *)(0X1FFFF7F0); // 低字节
  28.  
     
  29.  
    //08表示后面的数据不足8位就补0显示
  30.  
    printf("ChipID: X X %8X \r\n",ID[0],ID[1],ID[2]); //从串口输出16进制ID
  31.  
     
  32.  
    if(ID[0]==0x066EFF34 && ID[1]==0x3437534D && ID[2]==0x43232328){ //检查ID是否匹配
  33.  
    printf("chipID OK! \r\n"); //匹配
  34.  
    }else{
  35.  
    printf("chipID error! \r\n"); //不同
  36.  
    }
  37.  
     
  38.  
    while(1){
  39.  
     
  40.  
    }
  41.  
    }
学新通

五:还需要补充的知识

  1.  
    1.仿真
  2.  
    仿真接口有JTAG、SW接口,仿真器又有ST-LINK、J-LINK等
  3.  
    还有纯软件仿真Proteus等
  4.  
     
  5.  
     
  6.  
    2.HEL库
  7.  
     
  8.  
     
  9.  
    3.内置USB接口
  10.  
    USB鼠标、键盘、U盘
  11.  
     
  12.  
     
  13.  
    4.显示屏
  14.  
    除OLED之外,还能外扩LCD160212864
  15.  
    显示屏的类型还有VOG屏、TFT屏等
  16.  
    每种屏的接口也分好多种
  17.  
     
  18.  
     
  19.  
    5.定时器的复杂功能
  20.  
    TIM1高级定时器的使用
  21.  
    单脉冲模式
  22.  
    输出比较器的使用
  23.  
    捕获器的使用
  24.  
    定时器的DMA设置
  25.  
     
  26.  
     
  27.  
    6.中断的复杂功能
  28.  
    中断嵌套应用与优先级问题
  29.  
    外部中断的端口映射问题
  30.  
     
  31.  
     
  32.  
    7.单片机内部功能
  33.  
    WIFI、蓝牙、GPS模块、2.4G模块、彩屏的人机界面、RTOS嵌入式操作系统....
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgkgbhi
系列文章
更多 icon
同类精品
更多 icon
继续加载