国民技术N32G031开发笔记 - 定时器+GPIO

N32G031定时器+GPIO点灯

GPIO模块

国民技术N32G031开发笔记 - 定时器+GPIO_第1张图片
关于GPIO口的说明,请查看官方的指导手册。文档有中英文的,在这里就不啰嗦了。

GPIO口配置

配置PB1脚为推挽输出。使用PB1来点亮LED灯。直接操作寄存器来实现。
硬件接线图:
国民技术N32G031开发笔记 - 定时器+GPIO_第2张图片

  • gpio.h
#ifndef __GPIO_H__
#define __GPIO_H__

#include "n32g031.h"

//PB1(0) -> PB1=0(低电平,此时LED点亮);PB1(X)只要X不等于0,PB1输出高电平,此时LED熄灭
#define PB1(X) GPIOB->PBSC = (X)>0 ? (1<<1):(0X10000<<1)

void Gpio_init(void);//gpio口初始化


#endif 
  • gpio.c
#include "gpio.h"



void Gpio_init(void)
{
	RCC->APB2PCLKEN |=(1<< 3);//使能GPIOB时钟
	
	GPIOB->PMODE &= (~(3 << 2));//清除PB1的模式
	GPIOB->PMODE |= (1<<2); //PB1设置为通用输出模式
	GPIOB->POTYPE &=(~(1<<1)); //PB1设置为推挽输出
	GPIOB->SR &=(~(1<<1)); //PB1快速翻转
	GPIOB->PUPD &=(~(3<<2));//PB1无上下拉
	GPIOB->DS |=(1<<1);//PB1设为低驱动能力(8mA(5V)/4mA(3.3V)/2mA(1.8V)
	GPIOB->POD |=(1<<1);//PB1输出高电平
}

通用定时器TIM3

国民技术N32G031开发笔记 - 定时器+GPIO_第3张图片
关于TIM3的说明,请查看官方的指导手册。文档有中英文的,在这里就不啰嗦了。重要的解析会在代码里注释。

TIM3配置

TIM3配置为定时器,并且产生中断。使用寄存器编写。

  • timer.h
#ifndef __TIMER_H__
#define __TIMER_H__

#include "n32g031.h"
#include 

void TIM3Init_ds(uint16_t PrescalerVal, uint16_t period);

#endif 
  • timer.c
#include "timer.h"
#include "gpio.h"
/*
*fck_psc=48MHz
* PrescalerVal - 预分频值
* period - 装载周期
*/
void TIM3Init_ds(uint16_t PrescalerVal, uint16_t period)
{
	RCC->APB1PCLKEN |=(1<<1);//使能TIM3的时钟
	
	TIM3->CTRL1 =0;
	TIM3->CTRL1 |=(1<<7);//自动重装载预装载允许位:1-TIMx_AR 寄存器的影子寄存器使能
	TIM3->CTRL1 |=(0<<5);//00:边缘对齐模式。 TIMx_CTRL1.DIR 指定向上计数或向下计数。
	TIM3->CTRL1 |=(0<<4);//0:计数器向上计数;1:计数器向下计数。
	TIM3->CTRL1 |=(0<<3);//0:禁用单脉冲模式,发生更新事件时不影响计数器计数。
	TIM3->CTRL1 |=(1<<2);//更新请求源:1:如果更新中断或 DMA 请求使能,只有计数器上溢/下溢会产生更新中断或 DMA请求。
	TIM3->CTRL1 |=(0<<1);//0-启用更新事件;1:UEV 禁用。 不生成更新事件,影子寄存器(AR、PSC 和 CCDATx)保持它们的值。
	
	TIM3->CTRL2=0;//控制寄存器2
	TIM3->SMCTRL=0;//从模式控制寄存器
	TIM3->DINTEN=0;//DMA/中断使能寄存器
	
	TIM3->STS=0;//状态寄存器 UDITF[0] -1:发生更新中断。TITF[6] -触发器中断标记:0:无触发器事件产生;1:触发中断等待响应。 
	TIM3->EVTGEN=0;
	//TIM3->EVTGEN |=(1<<0);//产生更新事件 (Update generation) 该位由软件置’1’,由硬件自动清’0’。当由软件设置1时,该位可以生成更新事件。
												//而此时计数器会重新初始化,预分频计数器会被清零,计数器在中央对齐或向上计数模式下会被清零,但在向下计数模式下取TIMx_AR寄存器的值。
	TIM3->CNT=0;//计数器的值设置为0
	
	RCC->CFG &=(~(0X07<<8));//配置APB1 时钟PCLK1 的预分频系数。0xx:HCLK 不分频
	//RCC->CFG |=(0X06<<8);//fAPB1=HCLK/8
	
	TIM3->PSC = PrescalerVal;//f=fck_psc/(PrescalerVal+1)
	TIM3->AR = period;//自动重装载的值
	
	TIM3->DINTEN |=(1<<0);//:允许更新中断。
	TIM3->CTRL1 |=1;//使能计数器
	
	
	//TIM3接到中断线16上。NVIC配置,详情请参考Cortex-M0编程手册
	NVIC->IP[4] |= (NVIC->IP[4]&(~(0xff<<0)))|(0Xb0<<0);//16/4=4; 16%4=0;最大只能设置为192=0xc0,此处设置优先级为0xb0=176
	NVIC->ISER[0] |=(1<<16);//TIM3 NVIC中断使能(写0无效)
}

uint8_t ONOrOFF=0XFF;
void TIM3_IRQHandler(void)
{
	if((TIM3->STS & 0X01))//发生更新中断
	{
		TIM3->STS &=(~0x01);//清除更新中断标志

		PB1(ONOrOFF);//LED转态翻转
		ONOrOFF=~ONOrOFF;
	}
	
}
  • main.c
#include "gpio.h"
#include "timer.h"

int main(void)
{
    /* SystemInit() function has been called by startup file startup_n32g031.s */
    /* Configure the system clock to 48 MHz */    

	Gpio_init();
	TIM3Init_ds(48000-1,999);//1s
    while (1)
    {          
       
    }
}

结尾

  • 实验现象:每隔1秒,LED电平翻转一次。

你可能感兴趣的:(国民技术N32系列开发,单片机,嵌入式硬件,c语言,stm32,个人开发)