精华内容
下载资源
问答
  • 传统时钟源的内外频标切换是用检波器对外频标进行检波,用检波出来的信号去控制晶振的电源通断,从而实现切换。但这种传统的检波方式,只能对频标的有无进检波,无法检出参考的频率,而且要求内外频标的频率相等,...
  • 传统时钟源的内外频标切换是用检波器对外频标进行检波,用检波出来的信号去控制晶振的电源通断,从而实现切换。但这种传统的检波方式,只能对频标的有无进检波,无法检出参考的频率,而且要求内外频标的频率相等,...
  • 在一般应用场合(不使用USB,对精度要求不高)LPC17xx系列除了使用外部晶体,还可以使用内部的12MHZ晶体作为振荡源。其实在运行初始化程序,进入用户程序前(main函数),LPC17xx是使用了内部晶体,这样设计是为了让...

            在一般应用场合(不使用USB,对精度要求不高)LPC17xx系列除了使用外部晶体外,还可以使用内部的12MHZ晶体作为振荡源。其实在运行初始化程序,进入用户程序前(main函数),LPC17xx是使用了内部晶体,这样设计是为了让引导代码(俗称bootloader)运行在一个已知的频率上。

            最近在开发板上做了个使用内部晶体的小实验,把原来使用外部12MHZ的程序修改成了使用内部晶体。这个修改其实很简单,只要修改时钟源选择寄存器(CLKSRCSEL)和锁相环0配置寄存器(PLL0CFG)。在Keil下system_LPC177x_8x.c下甚至能可视化修改。具体如下图:



      为了确定实验效果,把外部晶体使能关闭了(Main Oscillator enable),PLL1一般只给USB用,所以这里也可以关闭了PLL1使能。
      LPC17xx最多可以运行在120MHZ,所以PLL0的M值最大可以设为10(0xA)
    展开全文
  • STM32CUBEME--自定义红外NEC解码,定时器TIM捕获方式概述硬件准备选择芯片型号配置时钟源配置时钟树串口配置定时器配置代码 概述 本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。 硬件...

    概述

    本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。

    硬件准备

    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
    在这里插入图片描述

    选择芯片型号

    在这里插入图片描述

    配置时钟源

    HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:在这里插入图片描述

    配置时钟树

    STM32F0的最高主频到48M,所以配置48即可:
    在这里插入图片描述

    串口配置

    本次实验使用的串口1进行串口通信,波特率配置为115200。
    在这里插入图片描述

    定时器配置

    本次使用定时器1的通道2进行检测,配置入下。
    在这里插入图片描述

    红外接收管

    这里使用VS838的接收管,如下所示:
    在这里插入图片描述

    红外编码

    NEC协议载波:38khz
    其逻辑1与逻辑0的表示如图所示:
    在这里插入图片描述
    NEC协议格式:
    在这里插入图片描述

    自定义红外编码

    协议如下:

    在这里插入图片描述

    代码

    在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。

    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    /* USER CODE END Includes */
    

    红外接收口定义

    /* USER CODE BEGIN PTD */
    #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)
    /* USER CODE END PTD */
    

    函数声明和串口重定向:

    /* USER CODE BEGIN PFP */
    #ifdef __GNUC__
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    #endif /* __GNUC__ */
    PUTCHAR_PROTOTYPE
    {
        HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
        return ch;
    }
    /* USER CODE END PFP */
    
    /* USER CODE BEGIN 0 */
    uint32_t OrderData = 0;
    uint8_t ReadyFlag = 0;
    uint8_t OK = 0;
    /* USER CODE END 0 */
    

    定时器配置

      /* USER CODE BEGIN 2 */
    	HAL_TIM_Base_Start_IT(&htim1);//启动定时器
    	HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
    	printf("IR Capture !! \r\n");
      /* USER CODE END 2 *
    

    红外接收代码

    • [4400,5000]是用于捕获4.5ms的信号
    • [550,700]是用于捕获560us的数据0信号
    • [1100,1250]是用于捕获1120us的数据1信号
    • [2000,2500]是用于捕获2240us的截止位信号
    /* USER CODE BEGIN 4 */
    // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    {
    	uint32_t fallingCount = 0 ; // 下降沿计数
    	uint8_t temp = 0 ;
    	// 判断是否是定时器1的外部捕获口2
    	if(htim->Instance == TIM1)
    	{
    		// 捕获到了上升沿
    		if(IR_IN1)
    		{
    			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
    			__HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
    		}
    		else
    		{
    			fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
    			__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
    			if( ((fallingCount > 4400) && (fallingCount <5000))) 
    				OK = 1;/// 4.5ms引导电平
    			else if (((fallingCount > 550) && (fallingCount < 700)))	
    			{
    				temp = 0;//560 us,数据为0
    			}	
    			else if (((fallingCount > 1100) && (fallingCount < 1250)))
    			{
    			
    				temp = 1;//1120 us,数据为1
    			}
    			
    			else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))	//2.240ms截止码
    			{
    			  ReadyFlag = 1 ;
    				OK = 0;
    			}
    			if(OK)
    			{
    				OrderData <<= 1 ;
    				OrderData += temp ;
    				KeyCount = 0; // 按键次数
    			}
    		}
    	}
    }
    /* USER CODE END 4 */
    

    主函数

      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    		if(ReadyFlag)
    		{
    			printf("order=%08X , code=%d\r\n",OrderData,OrderData);
    			OrderData = 0;
    			OK = 0;
    			ReadyFlag = 0;		
    		}
      }
      /* USER CODE END 3 */
    

    结果演示

    红外连续发送5次码值,发送分别为

    • 1011(11)
    • 11 1010(58)
    • 11 0001(49)
    • 11 1111(63)
    • 11 0011(51)

    分别如下所示:
    在这里插入图片描述

    教学视频

    https://www.bilibili.com/video/BV1Yp4y1r7QX

    最后

    以上的代码会在Q群里分享。QQ群:615061293。
    或者关注微信公众号『记贴』,持续更新文章和学习资料,可加作者的微信交流学习!
    在这里插入图片描述

    展开全文
  • SystemInit():在"startup_stm32f10x_xx.s"文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有flash的设定),这个函数会在系统复位之后首先被执行。默认的一些设置:允许HSE(外部...

    试着申请首页,看看这类内容在blogcn的关注程度,呵呵

    system_stm32f10x.c

    SystemInit():在"startup_stm32f10x_xx.s"文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有flash的设定),这个函数会在系统复位之后首先被执行。默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周期),PLL系数为9,开启PLL并选择PLL输出作为时钟源(SYSCLK),后续设置SYSCLK = HCLK = APB2 = 72MHz,APB1 = HCLK/2 = 36MHz,HCLK即AHB的时钟。

    SystemCoreClockUpdate():在系统时钟HCLK变化的时候调用,以更新一个全局变量SystemCoreClock,这个变量可以为应用程序使用,必须保证正确。默认不用调用这个函数,因为SystemCoreClock默认被设置为设定的频率了(72MHz)

    另外,这种使用库的方法值得借鉴,先用位名清除相应的位,再进行设置:


    #define
    RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ #define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */ #define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */ #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

     

    startup_stm32f10x_md.s:(我用的是中容量的产品,且使用IAR)

    这个文件里面首先定义了复位中断(复位入口矢量被固定在地址0x0000_0004)的处理函数:Reset_Handler,它的作用就是将保存于flash中的初始化数据复制到sram中,调用上面说到的SystemInit来初始化时钟,接着跳转到main执行。

    接着定义了Default_Handler,这个是作为其他所有中断的默认处理函数,作用就是死循环,所以你假如开启了某个中断,请按照这里面的中断函数名给它写中断处理函数,例如串口的USART1_IRQHandler,你开了串口中断,如果不重写USART1_IRQHandler,就默认执行Default_Handler。而如果你有重写,那么中断向量表中的处理函数的地址就会更新为你自己写的那个函数的地址了。为什么会这样呢?因为此文件的末尾用了类似这样的语句:

        .weak    USART1_IRQHandler
        .thumb_set USART1_IRQHandler,Default_Handler

    它给中断处理函数提供了弱(weak)别名(Default_Handler),如果不重写,中断了默认执行Default_Handler,如果重写了,因为是弱别名,所以会被你写的同名函数覆盖。


    最后定义了一个中断向量表的段.section    .isr_vector,"a",%progbits),这个表将会放置在0x0000 0000那里,第二个字(0x0000 0004)是复位向量,复位之后重这地址所指的函数执行。

     

    那么,如何保证.isr_vector这个段将放在flash的最开始(0x08000000)呢?这就需要链接脚本了,即我们用的那个stm32_flash.ld文件了,查看一下就知道了,里面先定义了堆栈的地址:_estack

    /* Highest address of the user mode stack */
    _estack = 0x20005000;    /* end of 20K RAM */

    接着定义了堆和栈的大小:

    /* Generate a link error if heap and stack don't fit into RAM */
    _Min_Heap_Size = 0;      /* required amount of heap  */
    _Min_Stack_Size = 0x100; /* required amount of stack */

    接着声明了各个内存的区域(定义了几个代表某个线性空间的名字,如下面的FLASH):

    /* Specify the memory areas */
    MEMORY
    {
      FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 128K
      RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 20K
      MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
    }

    接着下面再详细地介绍上面这三个名字里面都放了什么东西,首先是FLASH的:

    /* Define output sections */
    SECTIONS
    {
      /* The startup code goes first into FLASH */
      .isr_vector :
      {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */
        . = ALIGN(4);
      } >FLASH
    
      /* The program code and other data goes into FLASH */
      .text :
      {
        . = ALIGN(4);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
        *(.glue_7)         /* glue arm to thumb code */
        *(.glue_7t)        /* glue thumb to arm code */
    
        KEEP (*(.init))
        KEEP (*(.fini))
    
        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
      } >FLASH

    可以看到startup_stm32f10x_md.s中定义的这个段.isr_vector确实放在了最开头的位置。下面其他的内容就不分析了。

         但是我们前面说复位向量在0x0000 0004,现在其地址是在flash中,所以地址是0x0800 0004,这个怎么回事呢?原来,stm32可以通过boot0、boot1引脚的配置将flash映射到0x0000 0000处。具体可参考stm32的数据手册2.4节:

    从主闪存存储器启动(BOOT0 = 0,BOOT1 = X):主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(0x0800 0000)访问它,即闪存存储器的内容可以在两个地址区域访问,0x0000 0000或0x0800 0000。

    至此,整个STM32的启动过程以及程序结构都可以比较清晰了吧。

    转载于:https://www.cnblogs.com/TrueElement/archive/2012/09/08/2677010.html

    展开全文
  • 1.时钟源 外部时钟 2.GPIO (实验:点亮LED灯,获取引脚的电平高低,将对应引脚置高置低)。 3.PWM-脉宽调制 主要是调节占空比(在小车中用来实现小车的加减速)。 4.TIMX定时器 5.红外遥控 主要运用了EXTI(外部中断/...
  • GPS传感器最出色的功能除了有基于原子钟的精准时钟源PPS信号,还拥有包含了网络时间的GPRMC信号,在校准RTC之前,对GPRMC时间信号的解析也变得尤为重要,对于GPRMC的解析网上有很多参考例程。GPRMC信号通过232芯片...

      GPS传感器最出色的功能除了有基于原子钟的精准时钟源PPS信号外,还拥有包含了网络时间的GPRMC信号,在校准RTC之前,对GPRMC时间信号的解析也变得尤为重要,对于GPRMC的解析网上有很多参考例程。GPRMC信号通过232芯片转换成TTL信号之后在电脑上的显示就是一行字符串,因为只需要提取年月日时分秒即可,所以我在最开始的时候打算偷个懒,直接从字符串数组中按索引依次提取时分秒,年月日的值,再通过计算转换成北京时间。然后就操蛋了,时分秒一直没有问题,到了年月日,一会儿是25年,一会儿是21年,一会儿是12月一会儿是24月。这个小bug我排查了三天,先是怀疑GPS发出的GPRMC有问题(可能是没有看到向往的蓝天,他理解错了时间),排查!没问题,再怀疑232芯片转换有问题,排查,没问题!再开始怀疑测试环境的风水……哎~~~

      最后发现问题所在,就是————不能按照数组下标提取时间!!!!因为GPRMC的长度不是固定的,它的方位角等参数是一直变的,一会儿是三位,一会儿是四位,操蛋了啊!!!

      所以可采用的方法就是,找GPRMC的字段标识符,也就是“,”,利用锁定字符串中指定字符位置的小算法得到标识符的位置,然后根据这个来锁定年月日时分秒的位置。

    HAL库环境下可参考我的部分代码如下,pch为自定义指针,USART_RX_BUF为单片机接收的GPRMC信号。

    pch = strchr(USART_RX_BUF, ',');
    	while (pch != NULL) {
    		for(i=0;i<12;i++)
    			{
    			comma[i]=pch-USART_RX_BUF;
    			pch = strchr(pch + 1, ',');
    			}
                                 }

     

    展开全文
  • ARM 时钟管理的学习

    2012-05-21 15:28:01
    除了USB,其他模块的时钟源,“一定”为同一时钟源,而USB和其他模块是否为同一时钟源呢?是由OM2,OM3引脚决定的,即有硬件设置决定的。分为同是外部时钟,同为晶振,分别为外部时钟和晶振共四种情况。   二。...
  • 在 STM32 中,一共有 5 个时钟源,分别是 HSI 、 HSE 、 LSI 、 LSE 、 PLL 。 ①HSI 是高速内部时钟, RC 振荡器,频率为 8MHz ; ②HSE 是高速外部时钟,可接石英 / 陶瓷谐振器,或者接外部时钟源,频率范围是 4...
  • 答:只要电路没错会起振,但有两种情况除外:你得单片机支持片内震荡且熔丝设置位为使能内部震荡,另一种是片外时钟输入模式,这个模式中你没有片外时钟源(有源晶振除外,这个只要有电就算没有单片机也振),不光...
  • OMAP4平台设置时钟频率

    千次阅读 2012-06-28 14:42:13
     FREF_CLK1_OUT/GPIO_181/SAFE_MODE 这个引脚是复用的,设为MODE0可以作为时钟源,只需要配置相应的寄存器,就可以完成,这里不再赘述。  硬件上决定了该时钟源受auxclk1控制,现在的工作就是配置a
  • 接收机端从接收到的来自串行链路的比特流中提取时钟信号Clk1,作为其工作时钟源;而发送机端采用本地晶振和锁相环产生的时钟Clk2,作为其工作时钟源。接收机在时钟Clk1的上升沿把数据写入弹性缓存,发送机在时钟Clk2...
  • 接收机端从接收到的来自串行链路的比特流中提取时钟信号Clk1,作为其工作时钟源;而发送机端采用本地晶振和锁相环产生的时钟Clk2,作为其工作时钟源。接收机在时钟Clk1的上升沿把数据写入弹性缓存,发送机在时钟Clk2...
  • 接收机端从接收到的来自串行链路的比特流中提取时钟信号Clk1,作为其工作时钟源;而发送机端采用本地晶振和锁相环产生的时钟Clk2,作为其工作时钟源。接收机在时钟Clk1的上升沿把数据写入弹性缓存,发送机在时钟Clk2...
  • STM32CUBEMX移植雅特力AT32F403AVGT7概述硬件准备选择芯片型号配置时钟源配置时钟树串口配置定时器配置红外接收管红外编码自定义红外编码代码结果演示最后 概述 本篇文章主要介绍如何使用STM32CubeMX移植到雅特力AT...
  • stm32时钟详细说明

    2019-09-29 16:20:31
    在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、...②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③、LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④、LSE是低速...
  • TM32学习笔记(3):系统时钟和...在STM32中,一共有5个时钟源,分别是HSI、HSE、LSI、LSE、PLL (1) HSI是高速内部时钟,RC振荡器,频率为8MHz; (2) HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接
  • STM32时钟之默认系统时钟配置讲解1-转载他人...STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接...
  • 【stm32】时钟树解析

    千次阅读 2017-05-08 11:44:50
    有时候会突然忘了这个重要的时钟树,这里转载一个比较好的,以...②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速
  • Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟 用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven Bean EJB实例源代码 2个目标文件 摘要:...
  • Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟 用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven Bean EJB实例源代码 2个目标文件 摘要:...
  • STM32CUBEMX(4)--GPIO输出

    万次阅读 2020-06-19 19:00:43
    STM32CUBEME--GPIO输出概述硬件准备选择芯片型号配置时钟源配置时钟树GPIO口配置生成工程设置代码生成设置生成代码配置keil代码演示效果最后 概述 本篇文章主要介绍如何使用STM32CubeMX对红外波形进行GPIO输出,并...
  • IMX6UL主频与时钟配置

    2020-05-18 18:56:33
    I.MX6U在默认配置下工作频率为396MHZ,但是I.MX6U系列标准的工作频率为528MHz ...I.MX6U 的设有很多,不同的外设时钟源不同, NXP 将这些外设的时钟源进行了分组,一共有 7 组,这 7 组时钟源都是从 2
  • 高分辨率ADC的板布线

    2021-01-20 00:12:05
    高速ADC(模/数变换器)是各种应用领域(如质谱仪,超声,激光雷达/雷达,电信收发机模块等)中关键的模拟处理元件。...没有的时钟源或仔细设计的板布线,则高性能变换器将达不到其性能指标。  单IF
  • [SOC]clock与reset设计

    2021-01-15 17:38:32
    [SOC]芯片中的clock与reset关于时钟 ...常见的外部时钟源有32.768KHz时钟和26MHz(这个频率可以更改)时钟。32.768KHz时钟用来提供给rtc模块或者timer模块,用于产生系统时钟、时间戳或者计数等。26MHz时钟常用做
  • STM32定时器

    2018-11-15 16:35:42
    时钟源 ②触发控制器 ③时基单元 ④输入捕获模块 ⑤输出比较模块 ⑥断路功能。 一:时钟源 可以来自 ①_1:内部时钟 ①_2:外部时钟模式1 1_时钟输入引脚TIMx_CH1/2/3/4 ----&gt;2_滤波—&gt;3_边沿检测...
  • 嵌入式工程模板搭建

    2021-03-06 19:04:39
    嵌入式工程模板搭建几点注意事项—以STM...一般我们采用PLLCLK作为系统时钟源。然后,我们根据系统时钟树确定PLLCLK,芯片手册的时钟树截图如下: 虽说上面的时钟树能说明问题,但是有点不太清晰,我们从网上下载找到
  • 内核节拍

    2018-02-18 22:09:38
    内核的节拍是选用一个时钟源作为滴答源,但是选择这个时钟源有个条件,就是这个时钟必须有计时功能,定时功能,硬件中断功能,即可以触发中断,这样才可以去产生tick。 软件上的tick正是在这个中断函数中实现的,当...

空空如也

空空如也

1 2
收藏数 35
精华内容 14
热门标签
关键字:

外时钟源是