笔记:stm32f030 要点总结(时钟、中断、GPIO、定时器、串口、看门狗)

不支持位带操作

只有一条AHB-lite总线接口连到存储器、总线矩阵等

1条外设总线,APB速度高达48MHz

4个中断优先级

GPIO连载AHB总线,最高翻转速度为12MHz

一、时钟系统

M0芯片的时钟源有4个,

一个高速内部RC时钟源,频率为8M,精度1%

一个高速外部时钟源,频率为8到32MHz

一个低速外部时钟源,频率一般为32.768kHz,驱动RTC

一个低速内部时钟源,频率为40kHz,驱动IWDG

芯片上电的时候默认启用内部RC震荡,即8MHz的内部时钟源

倍频最高48MHz

启用HSI

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

/*

*********************************************************************************************************

*   函 数 名: HSI_setSysClk

*   功能说明: 设置HSI为系统时钟,

*   形    参:

*   返 回 值: 无

*********************************************************************************************************

*/

void HSI_setSysClk(void)

{

  __IO uint32_t StartUpCounter = 0, HSIStatus = 0;

   

    /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/

    /* Enable HSI*/ //使能内部时钟  

    RCC->CR |= ((uint32_t)RCC_CR_HSION);//使用内部8M时钟

  

    /* Wait till HSI is ready and if Time out is reached exit */ //等待内部时钟起振

    do

    {

        HSIStatus = RCC->CR & RCC_CR_HSIRDY;

        StartUpCounter++;  

    }while((HSIStatus== 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));

 

    if ((RCC->CR & RCC_CR_HSIRDY) != RESET)//使用内部8M时钟

    {

        HSIStatus = (uint32_t)0x01;

    }

    else

    {

        HSIStatus = (uint32_t)0x00;

    }  

  

    if (HSIStatus == (uint32_t)0x01)

    {

        /* Enable Prefetch Buffer and set Flash Latency */ //flash总线时钟使能

        FLASH->ACR |= FLASH_ACR_PRFTBE;

        FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY;

 

        /* HCLK = SYSCLK *///外设AHB总线时钟等于系统时钟

        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

 

        /* PCLK = HCLK *///外设APB总线时钟等于系统时钟

        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;

 

        /* PLL configuration = HSI/2 * 12= 48 MHz */

        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL));

        RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL12); //RC时钟2分频后 进行12倍频

         

        /* Enable PLL *///使能锁相环倍频开关 

        RCC->CR |= RCC_CR_PLLON;

 

        /* Wait till PLL is ready *///等待锁相环就绪 

        while((RCC->CR & RCC_CR_PLLRDY) == 0)

        {

        }

 

        /* Select PLL as system clock source *///选择锁相环输出时钟作为系统时钟 

        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

 

        /* Wait till PLL is used as system clock source *///等待锁相环输出时钟已经成为系统时钟 

        while((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)

        {

        }

    }

    else

    /* If HSE fails to start-up, the application will have wrong clock 

         configuration. User can add here some code to deal with this error */

    }  

}

二、NVIC

4个中断优先级

1

2

3

/* 开关全局中断的宏 */

#define ENABLE_INT()    __enable_irq()     /* 使能全局中断 */

#define DISABLE_INT()   __disable_irq()    /* 禁止全局中断 */

1

2

3

4

5

6

7

8

9

10

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

 

  /* 外设中断 */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                  //IRQ通道:串口1

  NVIC_InitStructure.NVIC_IRQChannelPriority = 1;                    //优先级 :1级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能IRQ通道

  NVIC_Init(&NVIC_InitStructure);

}


 

三、GPIO

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#define PORT_LED                  GPIOC                    //端口

#define PIN_LED                   GPIO_Pin_13              //引脚

 

#define LED_ON                    (PORT_LED->BSRR = PIN_LED)

#define LED_OFF                   (PORT_LED->BRR  = PIN_LED)

#define LED_TOGGLE                (PORT_LED->ODR ^= PIN_LED)

 

/*

**********************************************************************

* @fun     :bsp_led_init  

* @brief   :板上LED初始化

* @param   :None

* @return  :None 

* @remark  :

**********************************************************************

*/

void bsp_led_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

 

    GPIO_InitStructure.GPIO_Pin = PIN_LED;                             //LED引脚

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                      //输出模式

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //高速输出

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                     //推完输出

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                   //无上下拉(浮空)

    GPIO_Init(PORT_LED, &GPIO_InitStructure);

}

四、定时器

滴答定时器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

/*

**********************************************************************

* @fun     :SysTick_Init  

* @brief   :滴答定时器初始化,提供1ms时基

* @param   :None

* @return  :=0,初始化成功;=1,初始化失败 

* @remark  :None

**********************************************************************

*/

unsigned char SysTick_Init(void)

{

    unsigned char sysFlag = 1;

     

    /* SystemFrequency / 1000    1ms中断一次

     * SystemFrequency / 100000  10us中断一次

     * SystemFrequency / 1000000 1us中断一次

     */ 

     

    sysFlag = SysTick_Config(SystemCoreClock / 1000);

 

    return sysFlag;

}

 

/*

**********************************************************************

* @fun     :bsp_DelayUS  

* @brief   :us级延迟。 必须在systick定时器启动后才能调用此函数

* @param   :None

* @return  :n-延迟长度,单位1 us

* @remark  :None

**********************************************************************

*/

void bsp_DelayUS(uint32_t n)

{

    uint32_t ticks;

    uint32_t told;

    uint32_t tnow;

    uint32_t tcnt = 0;

    uint32_t reload;

        

    reload = SysTick->LOAD;                

    ticks = n * (SystemCoreClock / 1000000); /* 需要的节拍数 */  

     

    tcnt = 0;

    told = SysTick->VAL;             /* 刚进入时的计数器值 */

 

    while (1)

    {

        tnow = SysTick->VAL;    

        if (tnow != told)

        {    

            /* SYSTICK是一个递减的计数器 */    

            if (tnow < told)

            {

                tcnt += told - tnow;    

            }

            /* 重新装载递减 */

            else

            {

                tcnt += reload - tnow + told;    

            }        

            told = tnow;

 

            /* 时间超过/等于要延迟的时间,则退出 */

            if (tcnt >= ticks)

            {

                break;

            }

        }  

    }

 

/*

**********************************************************************

* @fun     :SysTick_Handler  

* @brief   :滴答定时器中断服务函数

* @param   :None

* @return  :=0,初始化成功;=1,初始化失败 

* @remark  :None

**********************************************************************

*/

void SysTick_Handler(void)

{

 

}

五、串口

重定向prinf函数

1、需要在Options for Target -> Code Generation 中勾选Use MicroLIB;

2、需要加入下面这个函数:

int fputc(int ch, FILE *f)

{

  USART_SendData(USART1,(uint8_t)ch);

  while (USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);

  return (ch);

}

3、需要加入如下一个头文件:

#include "stdio.h"

(在网上看到多数人加了两个头文件:

#include "stdio.h"

#include "stdarg.h"

但在实际中只需加入一个头文件即可

)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#ifdef __GNUC__

    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

  

/** 

  * @brief  Retargets the C library printf function to the USART. 

  * @param  None 

  * @retval None 

  */  

PUTCHAR_PROTOTYPE  

{  

  /* Place your implementation of fputc here */  

  /* e.g. write a character to the USART */  

  USART_SendData(USART1, (uint8_t) ch);  

   

  /* Loop until the end of transmission */  

  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  

  {  

  }  

   

  return ch;  

}

六、看门狗

驱动独立看门狗的晶振为40KHz

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

/*

**********************************************************************

* @fun     :bsp_iwdg_init  

* @brief   :独立看门狗初始化,超时时间2048ms

* @param   :None

* @return  :None 

* @remark  :

**********************************************************************

*/

void bsp_iwdg_init(void)

{

    if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)

        RCC_ClearFlag();                             //清除标志

     

    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);   //使能寄存器 写功能

    IWDG_SetPrescaler(IWDG_Prescaler_64);           //设置预分频 40K/64=0.625k 一个周期是 1.6ms

    IWDG_SetReload(1280);                          //1280*1.6ms=2048ms //设置初值

    IWDG_ReloadCounter();                           //喂狗

    IWDG_Enable();                                  //使能独立看门狗

}

 

/*

**********************************************************************

* @fun     :bsp_iwdg_feed  

* @brief   :独立看门狗喂狗,必须在超时时间内调用

* @param   :None

* @return  :None 

* @remark  :

**********************************************************************

*/

void bsp_iwdg_feed(void)

{

    IWDG_ReloadCounter();

}

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F030C8T6是一款基于ARM Cortex-M0内核的单片机,它具有一些内置的模块和外设,例如ADC和定时器。ADC是模数转换器,用于将模拟信号转换为数字信号,而定时器则用于生成定时中断或脉冲。 要配置STM32F030C8T6的ADC使用定时器触发,首先需要设置ADC的时钟和引脚。然后,我们需要配置定时器时钟和相关参数。 对于ADC的配置,我们可以使用寄存器来完成。首先,我们需要启用ADC时钟,并选择ADC的工作模式和采样时间。然后,我们需要配置ADC的引脚和通道。接下来,我们可以设置ADC的转换模式和分辨率。最后,我们需要启用ADC。 对于定时器的配置,我们同样需要使用寄存器来完成。首先,我们需要启用定时器时钟。然后,我们需要配置定时器的分频系数和计数模式。接下来,我们可以设置定时器的重装载值和计数方向。最后,我们需要启用定时器定时器中断。 最后,我们还需要编写中断服务子程序(ISR)来处理定时器中断。在ISR中,我们可以执行一些特定的操作,例如启动ADC转换或读取ADC结果等。 需要注意的是,以上只是一个大致的步骤,实际的配置和使用可能涉及到更多的细节和设置。具体的配置细节可以参考STM32F030C8T6的参考手册和相关的资料。 通过以上的步骤,我们可以成功地配置和使用ADC和定时器来实现定时触发并测量模拟信号的目的。 ### 回答2: STM32F030C8T6是一款基于ARM Cortex-M0内核的单片机,内置了ADC(模数转换器)和定时器。下面是关于如何配置使用定时器触发ADC的步骤: 1. 首先,需要启用ADC和相关的GPIO端口。可以使用RCC(Reset and Clock Control)寄存器配置使能ADC,并将相应的GPIO端口设置为模拟输入模式。 2. 配置ADC的基本参数,例如转换分辨率、采样时间等。可以使用ADC_CR寄存器进行配置。 3. 配置ADC的通道和触发源。可以通过ADC_CHSELR寄存器来选择要转换的通道,并使用ADC_CFGR1寄存器来选择ADC触发源。在本例中,我们使用定时器作为ADC的触发源。 4. 配置定时器的基本参数,例如时钟频率、预分频因子、计数器模式等。可以使用TIMx_CR1、TIMx_PSC和TIMx_ARR寄存器进行配置。 5. 配置定时器的触发源和触发模式。可以使用TIMx_SMCR寄存器来选择定时器的触发源,并使用TIMx_CR2寄存器来选择触发模式。在本例中,我们选择外部事件触发模式,并将ADC转换触发源设置为TIMx的TRGO信号。 6. 启动定时器和ADC。可以分别使用TIMx_CR1和ADC_CR寄存器的相应位来启动定时器和ADC。 7. 在定时器溢出中断中进行ADC转换。如果定时器的计数器溢出中断使能,则可以在该中断处理函数中触发ADC转换。在中断处理函数中,可以使用ADC_CR寄存器的ADSTART位触发ADC转换。 8. 在ADC转换结束中断中读取转换结果。如果ADC转换完成中断使能,则可以在该中断处理函数中读取ADC转换结果。可以使用ADC_DR寄存器读取转换结果。 通过以上步骤,就可以配置使用定时器触发ADC的功能了。需要根据具体的应用场景和需求进行相应的配置和调整。 ### 回答3: stm32f030c8t6是一款32位的ARM Cortex-M0微控制器,提供了多个模块和功能,其中包括一个12位的ADC(模数转换器)和多个定时器。 要配置使用定时器触发ADC,首先需要进行以下几个步骤: 1. 选择使用的定时器stm32f030c8t6提供了多个定时器,例如TIM2、TIM3、TIM14等。根据需求选择一个合适的定时器。 2. 配置定时器:使用寄存器设置定时器时钟源、预分频因子、计数模式和自动重装载值等参数。可以参考芯片手册和相应的寄存器描述来进行配置。 3. 配置ADC:使用寄存器设置ADC的采样通道、分辨率、采样时间和转换模式等参数。同样可以参考芯片手册和寄存器描述进行配置。 4. 配置定时器触发ADC:将定时器的触发源设置为ADC转换触发源,并设置相应的触发极性和触发分频因子。 5. 初始化和启动定时器和ADC:根据配置的参数,初始化定时器和ADC,并启动它们的工作。 6. 编写中断处理程序(可选):如果需要使用定时器中断触发ADC转换,可以编写相应的中断处理程序,并在程序中启用定时器中断。 以上就是使用定时器触发ADC的配置步骤。在实际使用中,需要根据具体的需求和外部电路进行相应的配置和连接。同时,还需要注意定时器和ADC的初始化顺序和时序要求,以确保它们能够按照预期工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值