打印
[应用方案]

新唐N32905U1DN开发教程:使用寄存器配置IO口

[复制链接]
909|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
由于官方提供的IO口配置函数效率低,且配置比较繁琐,下面使用寄存器配置的方式来控制IO口,实现实验一的点亮LED。通过查阅N329_Design_Guide_A0.pdf第627页可以发现,IO口相关寄存器的基址为0xB8001000,由此我们定义一个宏 #define GP_BA 0xB8001000




根据上图寄存器的偏移量,我们对寄存器的地址进行宏定义,为了方便对IO口进行初始化,定义一个结构体,同时也要把相关变量类型重新定义一下,符合我们的使用习惯

使用特权

评论回复
沙发
两只袜子| | 2022-1-25 10:47 | 只看该作者
学习一下

使用特权

评论回复
板凳
欢乐家园|  楼主 | 2022-1-25 15:15 | 只看该作者
我创建的是n3290x.h,内容如下所示:
#ifndef __N3290X_H
#define __N3290X_H

#include "stdint.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
  #define     __I     volatile  
#else
  #define     __I     volatile const         
#endif
#define     __O     volatile
#define     __IO    volatile
     
typedef int32_t  s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef const int32_t sc32;  /*!< Read Only */
typedef const int16_t sc16;  /*!< Read Only */
typedef const int8_t sc8;   /*!< Read Only */

typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;

typedef __I int32_t vsc32;  /*!< Read Only */
typedef __I int16_t vsc16;  /*!< Read Only */
typedef __I int8_t vsc8;   /*!< Read Only */

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef const uint32_t uc32;  /*!< Read Only */
typedef const uint16_t uc16;  /*!< Read Only */
typedef const uint8_t uc8;   /*!< Read Only */

typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;

typedef __I uint32_t vuc32;  /*!< Read Only */
typedef __I uint16_t vuc16;  /*!< Read Only */
typedef __I uint8_t vuc8;   /*!< Read Only */
     
#define GP_BA 0xB8001000
#define GPIOA_BASE (GP_BA + 0x00)
#define GPIOB_BASE (GPIOA_BASE+ 0x10)
#define GPIOC_BASE (GPIOB_BASE+ 0x10)
#define GPIOD_BASE (GPIOC_BASE+ 0x10)
#define GPIOE_BASE (GPIOD_BASE+ 0x10)

typedef struct
{
    __IO uint32_t OMD;
    __IO uint32_t PUEN;
    __IO uint32_t DOUT;
    __I uint32_t PIN;
}GPIO_TypeDef;

#define GPIOA ((GPIO_TypeDef*)(GPIOA_BASE))
#define GPIOB ((GPIO_TypeDef*)(GPIOB_BASE))
#define GPIOC ((GPIO_TypeDef*)(GPIOC_BASE))
#define GPIOD ((GPIO_TypeDef*)(GPIOD_BASE))
#define GPIOE ((GPIO_TypeDef*)(GPIOE_BASE))

#endif

使用特权

评论回复
地板
欢乐家园|  楼主 | 2022-1-25 15:17 | 只看该作者
GPIOx_ODM是一个32bit寄存器,控制IO口为输入或输出,每一bit控制一个IO口。当某一位为1时,配置对应的IO口为输出;当为0时,配置对应的IO口为输入。

使用特权

评论回复
5
欢乐家园|  楼主 | 2022-1-25 15:23 | 只看该作者
如GPIOA->ODM = 0x00000001表示将PA0设为输出,PA的其它口均设为输入。

使用特权

评论回复
6
欢乐家园|  楼主 | 2022-1-25 15:24 | 只看该作者
GPIOx_DOUT控制IO的输出为高电平或低电平,当某位为1时,表示对应的IO口输出高电平,反之输出低电平,前提是该IO口配置为输出模式。

使用特权

评论回复
7
欢乐家园|  楼主 | 2022-1-25 15:25 | 只看该作者
下面贴出main.c的代码
#include "wblib.h"
#include "n3290x.h"

int main(void)
{
    sysSetSystemClock(eSYS_UPLL,    //E_SYS_SRC_CLK eSrcClk,   
                        192000,     //UINT32 u32PllKHz,     
                        192000,     //UINT32 u32SysKHz,
                        192000,     //UINT32 u32CpuKHz,
                          96000,        //UINT32 u32HclkKHz,
                          48000);       //UINT32 u32ApbKHz  
    //PB3~PB6设为输出
    GPIOB->OMD |= 0x0F<<3;
    //PB3~PB6输出高电平
    GPIOB->DOUT |= 0x0F<<3;
    //PB3~PB6输出低电平
    GPIOB->DOUT &= ~(0x0F<<3);
    while(1)
    {
    }
}

使用特权

评论回复
8
欢乐家园|  楼主 | 2022-1-25 15:29 | 只看该作者
通过仿真可以看到执行GPIOB->DOUT |= 0x0F<<3;后,灯就灭了,如此,用寄存器控制LED的实验完成。

使用特权

评论回复
9
drer| | 2022-2-7 13:01 | 只看该作者
大概能低到多少呢

使用特权

评论回复
10
coshi| | 2022-2-7 13:49 | 只看该作者
用熟悉了的话  这种是很靠谱的

使用特权

评论回复
11
kxsi| | 2022-2-7 14:41 | 只看该作者
那本身对寄存器需要非常了解

使用特权

评论回复
12
wiba| | 2022-2-7 15:21 | 只看该作者
一共也没有几行代码吧

使用特权

评论回复
13
qcliu| | 2022-2-7 15:51 | 只看该作者
头文件也是自己定义的吗

使用特权

评论回复
14
szchen2017| | 2022-2-7 23:56 | 只看该作者
想请教一下楼主,你们发现没有,如果2个以上的I/O同时由低电平翻转到高电平时,它们到达高电平的时间是不同的,而且这个不同很明显。我在驱动步进马达时发现了这个问题。请问你们有没有遇到过呢?是怎么解决的呢?谢谢分享。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

93

主题

889

帖子

1

粉丝