精华内容
下载资源
问答
  • 当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。GPIO的优点:低功耗:GPIO具有更低的功率损耗(大约1μA,μC的工作电流则为100μA)。集成IIC....

    General Purpose Input Output (通用输入/输出)简称为GPIO,或总线扩展器,人们利用工业标准I2C、SMBus或SPI接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。

    GPIO的优点:

    低功耗:GPIO具有更低的功率损耗(大约1μA,μC的工作电流则为100μA)。

    集成IIC从机接口:GPIO内置IIC从机接口,即使在待机模式下也能够全速工作。

    小封装:GPIO器件提供最小的封装尺寸 ― 3mm x 3mm QFN!

    低成本:您不用为没有使用的功能买单。

    快速上市:不需要编写额外的代码、文档,不需要任何维护工作。

    灵活的灯光控制:内置多路高分辨率的PWM输出。

    可预先确定响应时间:缩短或确定外部事件与中断之间的响应时间。

    更好的灯光效果:匹配的电流输出确保均匀的显示亮度。

    布线简单:仅需使用2条就可以组成IIC总线或3条组成SPI总线。

    与ARM 的几组GPIO引脚,功能相似,GPxCON 控制引脚功能,GPxDAT用于读写引脚数据。另外,GPxUP用于确定是否使用上拉电阻。 x为A,B,,H/J,

    GPAUP没有上拉电阻。

    GPIO的确切作用:

    ----输出值可写(高=1,低=0)。一些芯片也可以选择驱动这些值的方式,以便支持“线-或”或类似方案(开漏信号线)。

    ----输入值可读(1,0)。一些芯片支持输出管脚回读,这在线或的情况下非常有用(以支持双向信号线)。GPIO控制器可能具有一个输入防故障/防反跳逻辑,有时还会有软件控制。

    ----输入经常被用作中断信号,通常是边沿触发,但也有可能是电平触发。这些中断可以配置为系统唤醒事件,从而将系统从低功耗模式唤醒。

    ----一个GPIO经常被配置为输入/输出双向,根据不同的产品单板需求,但也存在单向的情况。

    ----大多是GPIO可以在获取到spinlock自旋锁时访问,但那些通过串行总线访问的通常不能如此操作(休眠的原因)。一些系统中会同时存在这两种形式的GPIO。

    ----在一个给定单板上,每个GPIO用于一个特定的目的,如监控MMC/SD卡的插入/移除,检查卡写保护状态,驱动LED,配置发送器,串行总线位拆,触发一个硬件看门狗,触发一个开关之类的。

    什么是管脚复用?

    所谓的管脚复用,就是除第一功能外,增加了第二功能,如单片机89C51的P3 I/O口同时还为中断管脚,主要为节约芯片面积。当然在利用程序控制时是不会影响的

    为何要有管脚复用?

    当:芯片上的引脚资源不够用;芯片上,为了更高效率的利用引脚资源;就可能会出现引脚复用。物理上,同样的一组引脚,pin脚;

    可以被设置(通过软件配置对应的寄存器去控制)为不同的功能,这样就可以实现可以根据实际需要,在不同的情况下,使用同一组引脚,实现不同的功能,用于不同的功能。

    GPIO管脚的复用功能重映:

    1、复用功能:内置外设是与I/O口共用引出管脚(不同的功能对应同一管脚)STM32 所有内置外设的外部引脚都是与标准GPIO引脚复用的,如果有多个复用功能模块对应同一个引脚,只能使能其中之一,其它模块保持非使能状态。

    2、重映射功能:复用功能的引出脚可以通过重映射,从不同的I/O管脚引出,即复用功能的引出脚位是可通过程序改变到其他的引脚上!

    直接好处:PCB电路板的设计人员可以在需要的情况下,不必把某些信号在板上绕一大圈完成联接,方便了PCB的设计同时潜在地减少了信号的交叉干扰。如:USART1:0: 没有重映像(TX/PA9,RX/PA10);1: 重映像(TX/PB6,RX/PB7)[0,1为一寄存器的bit值]

    下述复用功能的引出脚具有重映射功能:

    - 晶体振荡器的引脚在不接晶体时,可以作为普通I/O口

    - CAN模块; - JTAG调试接口;- 大部分定时器的引出接口; - 大部分USART引出接口 - I2C1的引出接口; - SPI1的引出接口;

    举例:对于STM32F103VBT6,47引脚为PB10,它的复用功能是I2C2_SCL和 USART3_TX,表示在上电之后它的默认功能为PB10,而I2C2的SCL和USART3的TX为它的复用功能;另外在TIM2的引脚重映射后,TIM2_CH3也成为这个引脚的复用功能。

    (1)要使用STM32F103VBT6的47、48脚的USART3功能,则需要配置47脚为复用推挽输出或复用开漏输出,配置48脚为某种输入模式,同时使能USART3并保持I2C2的非使能状态。

    (2)使用STM32F103VBT6的47脚作为TIM2_CH3,则需要对TIM2进行重映射,然后再按复用功能的方式配置对应引脚。

    下面跟大家说一下STM32单片机的端口重映射,因为是以自己为实例。这里是以USART1的重映射为例:

    STM32上有很多I/O口,也有很多的内置外设想I2C,ADC,ISP,USART等,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。但是STM32还有一特别之处就是:很多复用内置的外设的I/O引脚可以通过重映射功能,从不同的I/O管脚引出,即复用功能的引脚是可通过程序改变的。

    ba1bee552ab935f0146b0ac1653de67e.png

    以上是我在配置GPIO管脚PA9 PA10时没有发现的复用功能,

    65269260de26a5a1928e3ac6e8be9172.png

    直到我添加了RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);这个函数才通。

    f7ab3d423bea7a4df4fc0ff05c926d82.png

    重映射步骤为:

    1.打开重映射时钟和USART重映射后的I/O口引脚时钟, RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);

    2.I/O口重映射开启。

    GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

    3.配制重映射引脚, 这里只需配置重映射后的I/O,原来的不需要去配置。 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStructure);

    只需要这三步,串口就可以正常使用了,简单吧? 但是我纠结了大半个小时才搞定的,好多事情都是说起来容易做起来难的,希望我以后多多进步。不要眼高手低,嗯我正朝这个方向前进。

    最后总结一下:

    简单的说 STM32的io有3个功能一个是默认的一个是复用一个是重映射功能(这个其实也属于复用)

    如果配置成复用则将使用第2个功能如果配置成复用同时相应的重映射配置了则将使用第3个功能

    通常一个口的复用+重映射有好多不止两个这时候就看你使能哪个设备了(哪个被使能就用哪个)

    开复用 + 使能设备+ 是否重映射就可以决定这个io口到底使用哪个功能 别忘了开启USART1的外设时钟。

    展开全文
  • STM32通用和复用功能IO

    2021-09-15 13:45:51
    GPIO功能配置 每个端口可以被配置为8种模式: typedef enum { GPIO_Mode_AIN = 0x0, GPIO_Mode_IN_FLOATING = 0x04, GPIO_Mode_IPD = 0x28, GPIO_Mode_IPU = 0x48, GPIO_Mode_Out_OD = 0x14, GPIO_Mode_Out_PP = 0x...

    总结

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    //后面肯定接的代码是
    //重映射引脚
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
    //或者配置为中断线
    GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    //或者配置为事件输出
    GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    

    上面代码用于引脚重映射,数据手册Remap功能。

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    

    上面代码用于普通IO口复用功能,数据手册Default功能。

    GPIO功能配置

    每个端口可以被配置为8种模式:

    typedef enum
    { 
    	GPIO_Mode_AIN = 0x0,//模拟输入--IO口用于模拟量输入
    	GPIO_Mode_IN_FLOATING = 0x04,//浮空输入
    	GPIO_Mode_IPD = 0x28,//下拉输入
    	GPIO_Mode_IPU = 0x48,//上拉输入
    	GPIO_Mode_Out_OD = 0x14,//开漏输出
    	GPIO_Mode_Out_PP = 0x10,//推挽输出
    	GPIO_Mode_AF_OD = 0x1C,//复用开漏输出--不作为普通IO口时使用
    	GPIO_Mode_AF_PP = 0x18 //复用推挽输出--不作为普通IO口时使用
    }GPIOMode_TypeDef;
    

    AFIO端口复用

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    

    F1系列:

    • 配置复用功能重映射
      为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其他引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上。
      复用功能重映射可以分为:没有重映射,部分重映射,完全重映射。
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
    
    • 配置外部中断线映射
    GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    
    • 配置EVENTOUT事件输出
    GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    

    F4系列:

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); 
    
    展开全文
  • (STM32开漏输出若外部不接上拉电阻只能输出0)STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。我们知道每个内置外设都有若干...

    Stm32的引脚一般应用:

    模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电。

    浮空输入_IN_FLOATING ——可以做KEY识别,RX1

    开漏输出_Out_OD——应用于I2C总线; (STM32开漏输出若外部不接上拉电阻只能输出0)

    STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。

    我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的脚位外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的脚 位。下面是STM32F103xC中有关USART3引脚的摘要片段;8a68e4a4989952fb3041c1cbe6a252c4.png

    从这里可以看出,USART3_TX的默认引出脚是PB10,USART3_RX的默认引出脚是PB11;但经过重映射后,可以变更USART3_TX的引出脚为PD8,变更USART3_RX的引出脚为PD9。

    STM32中的很多内置外设都具有重映射的功能,比如USART、定时器、CAN、SPI、I2C等,详细请看STM32参考手册(RM0008)和STM32数据手册。

    有些模块(内置外设)的重映射功能还可以有多种选择,下面是RM0008上有关USART3输入输出引脚的重映射功能表:

      a2e4086b1b40d38a2bb94343309da0f8.png

    从这个表中可以看出,USART3的TX和RX引脚默认的引出脚位是PB10和PB11,根据配置位的设置,可以重映射到PC10和PC11,还可以重映射到PD8和PD9。

    一个模块的功能引脚不管是从默认的脚位引出还是从重映射的脚位引出,都要通过GPIO端口模块实现,相应的GPIO端口必须配置为输入(对应模块的 输入功能,如USART的RX)或复用输出(对应模块的输出功能,如USART的TX),对于输出引脚,可以按照需要配置为推挽复用输出或开漏复用输出。

    c3ac5b08c4377043645f132faa8a8ad6.png

    上图是STM32的GPIO端口模块,使用复用功能时的配置。从图中可以看出,配置为复用输出时,该端口对应的GPIO输出功能将不起作用。例如当配置PB10对应的引脚为复用输出功能时,操作PB10对应的输出寄存器将不影响引脚上的信号。

    从图中还可以看出,普通的GPIO端口输入功能与复用的输入功能的配置方式没有分别,这意味着在使用引脚的复用输入功能时,可以在这个引脚的输入寄 存器上读出引脚上的信号。例如在使能了USART3模块时,可以读GPIOB_IDR寄存器,得到PB11信号线上的当前状态。

    有不少引脚上配备了来自多个模块的复用功能引出脚,例如本文第一张图中显示的PB10,默认复用功能就有I2C2_SCL和USART3_TX两个功能,TIM2重映射后,TIM2_CH3也使用PB10的复用功能。

    在使用引脚的复用功能时,需要注意在软件上只可以使能一个外设模块,否则在引出脚上可能产生信号冲突。例如,如果使能了USART3模块,同时没有 对USART3进行重映射配置,则不可以使能I2C2模块;同理如果需要使用I2C2模块,则不能使能USART3模块。但是如果配置了USART3的引 脚重映射,USART3的TX和RX信号将从PC10和PC11,或PD8和PD9引出,避开了I2C2使用的PB10和PB11,这时就可以同时使用 I2C2模块和USART3模块了。

    USART3模块共有5个信号,分别为TX、RX、CK、CTS和RTS,从上面给出的第二张图中可以看出,重映射是对所有信号同时有效。

    这5个信号中,在使能了USART3模块后,只有TX和RX是始终与对应的引出脚相连,而其它3个信号分别有独立的控制位,控制它们是否与外部引脚 相连,如果程序中不使用某个信号的功能,则可以关闭这个信号的功能,对应的引脚可以做为其它功能的引出脚。例如,当关闭了USART3的CK、CTS和 RTS功能并且没有重映射USART3时,PB12、PB13和PB14可以作为通用输入输出端口使用,也可以作为其它模块的复用功能引出脚。

    下面这张图是一个内部控制连接的等效示意图,它并不表示真正的内部连接,但可以有效地帮助理解重映射和复用引脚的概念。图中右边引出的信号,分别连接到了本文第三张图的输入输出模块。

    da3ec3290234009b2214dcd12298fa39.png

    展开全文
  • //使能GPIO外设和AFIO复用功能模块时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |...

    \\

    //TIM3 PWM部分初始化 
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  , ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟  1
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
    
      GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   PC7
    	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3完全重映射  TIM3_CH1->PC6 CH2->PC7 CH3->PC8 CH4->PC9
    	
    	
    	//设置该引脚为复用输出功能,输出TIM3 CH1的PWM脉冲波形	GPIOA.6  
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM_CH1
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
    	
    
    	
    		//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOC.8  重映射的端口remap 3
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM3_CH3
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
    	
       //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOB.5  重映射的端口remap  2
    	
    //	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
    //	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    //	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    //	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
    	
        //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOC.7  重映射的端口remap
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
    	
    	
    	//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOC.7  重映射的端口remap
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TIM_CH2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
    	
    
    	
       //初始化TIM3
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    	
    	//初始化TIM3 Channel2 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2  3  
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	
    	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1  TIM3 CH1的PWM脉冲波形	GPIOA.6
    	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器 TIM3 CH1的PWM脉冲波形	GPIOA.6
    	
     	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2  TIM3 CH2的PWM脉冲波形	GPIOB.5   4  C7
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器 TIM3 CH2的PWM脉冲波形	GPIOB.5  C7
    	
    	 	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3  TIM3 CH2的PWM脉冲波形	GPIOC8
    	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR3上的预装载寄存器 TIM3 CH2的PWM脉冲波形	GPIOC8
     
     //	TIM_CtrlPWMOutputs(TIM3,ENABLE); //⑤MOE 主输出使能   非高级定时器可省略  通用定时器 2 3 4 5
    	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
    	
    
    }
    

    stm32定时器重映射一个通道是不是就所有通道都被映射了?比如我设置定时器3的通道二完全重映射,那剩下的三个通道是不是也完全重映射了??还是没有重映射?????... stm32定时器重映射一个通道是不是就所有通道都被映射了?比如我设置定时器3的通道二完全重映射,那剩下的三个通道是不是也完全重映射了??还是没有重映射?????

    设定的时候只能设定时器3部分或者完全重映射,部分重映像只有通道1和2被重映射,完全重映像,四个通道都会被映射到其他IO。

    https://wenku.baidu.com/view/e3ce2a215901020207409c15.html 

    typedef enum
    {
    	ADC_PORTA0 = ADC_Channel_0,    
    	ADC_PORTA1 = ADC_Channel_1,
    	ADC_PORTA2 = ADC_Channel_2,
    	ADC_PORTA3 = ADC_Channel_3,
    	ADC_PORTA4 = ADC_Channel_4,
    	ADC_PORTA5 = ADC_Channel_5,
    	ADC_PORTA6 = ADC_Channel_6,
    	ADC_PORTA7 = ADC_Channel_7,
    	ADC_PORTA8 = ADC_Channel_8,
    	ADC_PORTA9 = ADC_Channel_9,
    	ADC_PORTA10 = ADC_Channel_10,
    	ADC_PORTA11 = ADC_Channel_11,
    	ADC_PORTA12 = ADC_Channel_12,
    	ADC_PORTA13 = ADC_Channel_13,
    	ADC_PORTA14 = ADC_Channel_14,
    	ADC_PORTA15 = ADC_Channel_15,
    }AD_PORT;
     
    typedef enum 
    {
    	KEY_LINE_1,
    	KEY_LINE_2,
    	ADC_KEY_LINE_MAX = KEY_LINE_2,
    	BATTERY_AD,
    	ADC_NUM_CNT,	//ADC的总数
    }ADC_NUM;
     
     
    volatile u16 g_uADC_ConVal[ADC_NUM_CNT] = {0};		// ADC转换值
     
     
    u32 const  g_uADNum[]=
    { 	
    	//KEYPORTA1, 
    	ADC_PORTA9,	 
    	ADC_PORTA8,	 
    	ADC_PORTA2,
    	//KEYPORTA0,
    };
     
     
    void Adc_Init(void)
    {
    	ADC_DeInit(ADC1);   
    	
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
     
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
     
    	//打开DMA1的时钟
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    	//打开ADC1的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
     
    	RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
     
    	//初始化IO口
    	GPIO_InitTypeDef	GPIO_InitStruct;
    	GPIO_StructInit(&GPIO_InitStruct);
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
    	GPIO_InitStruct.GPIO_Pin =	AD_KEY1_PIN;
    	GPIO_Init(AD_KEY1_PORT,&GPIO_InitStruct);				// KEY1
    	GPIO_InitStruct.GPIO_Pin =	AD_KEY2_PIN;
    	GPIO_Init(AD_KEY2_PORT,&GPIO_InitStruct);				// KEY2
    	GPIO_InitStruct.GPIO_Pin =	BATTERY_AD_PIN;
    	GPIO_Init(BATTERY_AD_PORT,&GPIO_InitStruct);;			// 电池电源采样
     
    	//配置ADC1的DMA模式
    	ADC_InitTypeDef ADC_InitStructure;
    	DMA_InitTypeDef DMA_InitStructure;
    	DMA_DeInit(DMA1_Channel1);
    	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);				//定义DMA外设基地址,即为存放转换结果的寄存器
    	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_uADC_ConVal;		//定义内存基地址
    	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;			//定义AD外设作为数据传输的来源
    	DMA_InitStructure.DMA_BufferSize = ADC_NUM_CNT;		//指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个
    	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;	//设定寄存器地址固定
    	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;			//设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到三个内存空间中
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;		//设定外设数据宽度
    	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;			//设定内存的的宽度
    	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;						//设定DMA工作再循环缓存模式
    	DMA_InitStructure.DMA_Priority = DMA_Priority_High;					//设定DMA选定的通道软件优先级
    	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
     
    	/* ADC DMA request in circular mode */
    	ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);					//必须得添加,否则无法获取到采样值
     
    	ADC_StructInit(&ADC_InitStructure);
    	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;					//设定AD转化在连续模式
    	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;			//不使用外部促发转换
    	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;					//采集的数据在寄存器中以左对齐的方式存放
    	ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
      	ADC_Init(ADC1, &ADC_InitStructure); 
     
    	for(u8 uCnt = 0;uCnt < ADC_NUM_CNT;uCnt++)
    	{
    		/* Convert the ADC1  with 55.5 Cycles as sampling time */ 
    		ADC_ChannelConfig(ADC1, g_uADNum[uCnt] , ADC_SampleTime_55_5Cycles); 	//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
    	}
    	
    	//ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_55_5Cycles); 	//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
    	//ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_55_5Cycles); 	//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
    	//ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_55_5Cycles); 	//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
    	//ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); 
     
    	
    	/* ADC Calibration */
    	ADC_GetCalibrationFactor(ADC1);						//校准ADC
     
    	
    	DMA_Cmd(DMA1_Channel1,ENABLE);
    	
    	/* Enable ADC_DMA */
    	ADC_DMACmd(ADC1, ENABLE);  
     
    	ADC_Cmd(ADC1,ENABLE);																	//使能指定的ADC1
    	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));			<span style="white-space:pre">	</span>//等待ADC准备好
     
     
    	ADC_StartOfConversion(ADC1);						//启动转换
    }

     

    STM32F030f4的代码段

     

    #include "ADC.h"
    
    
    
    
    
     __IO uint32_t TempSensVoltmv=0;
     __IO uint32_t VrefIntVoltmv=0;
     __IO uint32_t PC3Voltmv=0; 
     __IO uint32_t VbatVoltmv=0; 
     
     uint16_t RegularConvData_Tab[4];
    
    
    
    void ADC1_DMA_Init(void)
    {
    	GPIO_InitTypeDef    GPIO_InitStructure;
    	DMA_InitTypeDef     DMA_InitStructure;
    	ADC_InitTypeDef     ADC_InitStructure;
    
    	
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2; //PA0
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOA, &GPIO_InitStructure);	
    		
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);		
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
    	
    	ADC_DeInit(ADC1);//ADC恢复默认设置		
    
      DMA_DeInit(DMA1_Channel1);	/* DMA1 Channel1 Config */
     // DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//外设地址
    	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);				//定义DMA外设基地址,即为存放转换结果的寄存器
      DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;//内存地址
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设作为数据传输的来源
      DMA_InitStructure.DMA_BufferSize = 4;//
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器不变
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据宽度为16位
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA_Priority设定DMA通道x的软件优先级
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输
      DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    		  
      
    	
    	DMA_Cmd(DMA1_Channel1, ENABLE);/* DMA1 Channel1 enable */			
    	ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); /* Enable ADC_DMA */	
      ADC_DMACmd(ADC1, ENABLE);  
    	
    		
    
    	ADC_StructInit(&ADC_InitStructure);//初始化ADC结构
    	
    	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位精度
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //规定模式装换工作在连续模式
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不使用外部促发转换 
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对其为右对齐
      ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward; //ADC的扫描方向
      ADC_Init(ADC1, &ADC_InitStructure); 
    	 
      ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */  
    
    	ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */ 
    
    
    
    /*
      ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint ,ADC_SampleTime_239_5Cycles); 
      ADC_VrefintCmd(ENABLE);
    	
    	ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor ,ADC_SampleTime_239_5Cycles);
    	ADC_TempSensorCmd(ENABLE);
    	
    	ADC_ChannelConfig(ADC1, ADC_Channel_Vbat ,ADC_SampleTime_239_5Cycles);
    	ADC_VbatCmd(ENABLE);
    	*/
    	ADC_GetCalibrationFactor(ADC1); /* ADC Calibration */  //ADC校准
      ADC_Cmd(ADC1, ENABLE);  /* Enable ADCperipheral[PerIdx] */	  //使能指定的ADC1
      while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* Wait the ADCEN falg *///等待ADC准备好
      ADC_StartOfConversion(ADC1); /* ADC1 regular Software Start Conv */ //启动转换
    			
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*
    //ADC检测 
    
    void ADC_MyInit(void)
    {
    	  ADC_InitTypeDef   ADC_InitStruct; 
    	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    	
    	  RCC_ADCCLKConfig(RCC_ADCCLK_HSI14); 
    	
      //ADC参数配置
       
        ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;   //12位精度 
        ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;      //单次ADC  
        ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;  
        ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐 
        ADC_InitStruct.ADC_ScanDirection=ADC_ScanDirection_Backward;//数据覆盖
        ADC_Init(ADC1,&ADC_InitStruct); 
    	
    	  ADC_ChannelConfig(ADC1,ADC_Channel_6,ADC_SampleTime_239_5Cycles);  
    	    
    		ADC_GetCalibrationFactor(ADC1);  //ADC校准
      
        ADC_Cmd(ADC1,ENABLE); //ADC使能
    
        while(ADC_GetFlagStatus(ADC1,ADC_FLAG_ADRDY)==RESET);  //等待ADC准备  
    }
    
    u16 Get_Adc(void)    
    {
      u32 adc=0;
    	u8  q;
    	for(q=0;q<3;q++)
    	 {
    		ADC_StartOfConversion(ADC1);  //启动ADC转换  
    		while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);   //等待转换完成
    		adc +=ADC_GetConversionValue(ADC1);
       }
    	adc=adc/3;    //
    	adc=adc>>6;    //
    //	adc=(float)adc*3.3/4096;
    	
      return adc;   //返回adc  电压值
    }
    
    */
    
    
    #ifndef __ADC_H
    #define __ADC_H 
    
    #include "ALL_Includes.h"
    #include "stm32f0xx.h"
    
    
    #define ADC1_DR_Address                0x40012440
    
    extern  __IO uint32_t TempSensVoltmv;
    extern  __IO uint32_t VrefIntVoltmv ;
    extern  __IO uint32_t PC3Voltmv ;
    extern  __IO uint32_t VbatVoltmv ;
    extern  uint16_t RegularConvData_Tab[4];
    
    void ADC1_DMA_Init(void);
    
    
    
    
    
    
    void ADC_MyInit(void); 
    u16 Get_Adc(void) ;
    
    #endif
    

     

    展开全文
  • STM32F030如何正确配置IO口的复用功能

    千次阅读 2021-01-12 03:17:10
    在030系列的单片机中,PA2引脚除了作为普通的IO引脚用作输入输出功能以外,还可以作为内部外设串口1,串口2,定时器15通道1这三个外设的功能引脚.那么如何配置这个IO口用作哪一种外设的功能引脚呢?查找STM32F030数据手册...
  • 一、 STM32 上有很多 I/O 口,也有很多的内置外设,像 I2C,ADC,ISP,USART 等 ,为了节省引出管脚,这些 内置外设基本上是与 I/O 口共用管脚的 ,也就是 I/O 管脚的 复用功能 。但是 STM32 还有一特别之处就是:很多...
  • STM32引脚列表中主功能,默认复用功能和重定义功能的区别&STM32F103RCT6引脚功能及使用 -------转载------ 1 主功能就是STM32基本IO口,与外设没有连接的,我们可以直接输出或读入高低电平 使用时采用要...
  • 2020-7-3 08:22TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStruct.TIM_Cou...
  • 系统:WIN10x64 软件版本:STM32CubeMX 6.0.1 本人stm32新手,手写代码觉得不太完美,想通过官方IDE生成后修改, 无奈不会用其自动配置复用,百度了也没有~~ 重复尝试多次后得出:
  • 每个IO都拥有复用功能,在28035的数据手册的134页,就是28035的复用功能列表,这里记录一下,方便以后查找。
  • #define LED_ON GPIO_ResetBits(GPIOC,GPIO_Pin_8)//亮 #define LED_OFF GPIO_SetBits(GPIOC,GPIO_Pin_8)//不亮 #define Key_DownStatu GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0//按下 #define Key_UpStatu ...
  • 复用功能输入输出类似于:房间《--》大厅《--》门《--》室外的关系;从房间到室外,需要经过大厅,在经过大门才可以到达室外;从室外到房间,也需要经过大门 1) 当给TDR寄存器赋值时,数据会通过移位寄存器发送到...
  • 原来的stm32代码中,在上电时就关闭了JTAG/SWD复用功能,用做普通IO。但使用GD32F305时,发现关闭后,就再也通讯不上了。 查看手册,有如下说明: 从上图看出,MCU复位后,默认是启用SWJ功能的,而且下载时...
  • 针对F4系列,STM32F4库函数中,已经取消了GPIO_*PinRemapConfig()函数,对于复用功能使用GPIO*_PinAFConfig()函数了! 但是在GPIO_PinAFConfig()函数已经没有禁止JTAG/SW等选项了,而是复用到AF0~AF15线上,其中AF0...
  • 将可复用功能提取,用到vue的mixin技能; 上图为jeecg中定义可复用功能的mixin.js,关键步骤如图圈中点:引入vue,export暴露对象,定义所需的data数据、钩子函数、methods方法。 下面是在目标组件中的使用: ...
  • 前言:今天给大家介绍一下自己在使用航顺32芯片中遇到的一些问题。我用的是航顺的HK32f103VET6的一颗芯片,其中使用其中SPI3外设复用功能时,发现对应官方库的宏定义有些错误。遂给大...
  • 文章目录 大家一定要学会看官方的文档,它是一个最好的文档 Vue的生命周期 Vue的组件复用 script中 body中 new Vue中 在Body中加上复用的地方 大家一定要学会看官方的文档,它是一个最好的文档 Vue的生命周期 ...
  • //进行相应的多重引脚的复用功能的使用 GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;//查看相应的寄存器控制表,可以得到GPIO0复用为相应的数值I/O口 GpioCtrlRegs.GPAMUX1.bit.GPIO1=1;//GPIO1复用为相应的数字EPWM1B EDIS...
  • STM32按键功能复用

    2021-11-02 14:07:24
    为了节约资源往往需要一个按键实现多个功能,这里分别对单击、双击、长按进行响应编程。 思路如下: 1.检测输入是否为1,若为1,每隔50ms采集一次输入信号,若5次都为1,则结束判断, 设置FLAG=3。如果采集到0则...
  • 在嵌入式画板的时候, 我们需要先明确功能需求, 然后选择芯片, 然后再确定管脚, 特别是在嵌入式资源比较紧缺的时候, 合理分配管脚显得尤为重要. 但是当功能变得非常多的时候, 合理两个字也变得有一定的难度. 我这里...
  • 1 端口复用功能 1.1 端口复用的定义 STM32有许多的内置外设(如串口、ADC、DCA等等),这些外设的外部引脚都是和GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设...
  • 一、PA15配置为普通IO,PB3配置为TIMER1通道CH1的相关代码 1.PA15如何配置为普通IO #define A_PIN GPIO_PIN_15 #define A_GPIO GPIOA #define A_CLK RCU_GPIOA void micromotor_alarm_...复用功能时钟使能
  • RCW 512bit 来配置所以的硬件复用,不够使用,IIC3 IIC4的复用,需要使用PBI 命令来配置,或者在uboot下修改这个寄存器 SCFG_RCWPMUXCR0 : 00000000 IIC3 IIC4功能 可以在RCW中配置 .pbi write 0x57040C,...
  • STM32-IO引脚复用-原理和使用

    千次阅读 2021-09-15 10:06:46
    例如串口1 的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。 2.STM32引脚可以复用为哪些功能? 可在芯片STM32767IGT6资料中的pin and ball definitio

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 428,314
精华内容 171,325
关键字:

复用功能