查看: 3726|回复: 4

[求助] LPC54628J512使用位带操作无效果?

[复制链接]
  • TA的每日心情
    奋斗
    2021-2-4 16:14
  • 签到天数: 139 天

    连续签到: 1 天

    [LV.7]常住居民III

    14

    主题

    212

    帖子

    0

    高级会员

    Rank: 4

    积分
    881
    最后登录
    2021-2-4
    发表于 2019-12-16 10:02:41 | 显示全部楼层 |阅读模式
    使用官方开发板LPC54618J512,开发软件:MCUXPressoIDE
    LPC54618J512也是使用的Cortex-M4的内核,这样和STM32F429一样,能否直接使用位带操作?通过查阅LPC54618J512,发现支持位带操作。于是开始仿照STM32F429使用位带操作。通过查阅STM32F429的手册,发现位带操作就是映射了GPIO数据寄存器,将值直接写入数据寄存器。于是我也查阅LPC54628J512的参考手册,找到set寄存器(类似上面的数据寄存器),仿照之前的方法映射set寄存器,将值直接写入,两个使用只是寄存器地址不一样,但是通过实验,发现LED的小灯并未点亮,没有任何效果,不知用法哪里错了,求助!。下面是代码:

    #ifndef SYS_H_
    #define SYS_H_

    //#ifdef __cplusplus
    //extern "C" {
    //#endif
    //

    //这是参考M4权威指南给出的代码
    #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

    #define SET0 (0x2200U)
    #define SET1 (0x2204U)
    #define SET2 (0x2208U)
    #define SET3 (0x220CU)
    #define SET4 (0x2210U)
    #define SET5 (0x2214U)

    #define DIR0 (0x2000U)
    #define DIR1 (0x2004U)
    #define DIR2 (0x2008U)
    #define DIR3 (0x200CU)
    #define DIR4 (0x2010U)
    #define DIR5 (0x2014U)

    //output
    #define GPIO0_ODR_Addr (GPIO_BASE+SET0)
    #define GPIO1_ODR_Addr (GPIO_BASE+SET1)
    #define GPIO2_ODR_Addr (GPIO_BASE+SET2)
    #define GPIO3_ODR_Addr (GPIO_BASE+SET3)
    #define GPIO4_ODR_Addr (GPIO_BASE+SET4)
    #define GPIO5_ODR_Addr (GPIO_BASE+SET5)

    //input
    #define GPIO0_IDR_Addr (GPIO_BASE+DIR0)
    #define GPIO1_IDR_Addr (GPIO_BASE+DIR1)
    #define GPIO2_IDR_Addr (GPIO_BASE+DIR2)
    #define GPIO3_IDR_Addr (GPIO_BASE+DIR3)
    #define GPIO4_IDR_Addr (GPIO_BASE+DIR4)
    #define GPIO5_IDR_Addr (GPIO_BASE+DIR5)

    #define P0out(n)   BIT_ADDR(GPIO0_ODR_Addr,n)  //output
    #define P0in(n)    BIT_ADDR(GPIO0_IDR_Addr,n)  //input

    #define P1out(n)   BIT_ADDR(GPIO1_ODR_Addr,n)  //output
    #define P1in(n)    BIT_ADDR(GPIO1_IDR_Addr,n)  //input

    #define P2out(n)   BIT_ADDR(GPIO2_ODR_Addr,n)  //output
    #define P2in(n)    BIT_ADDR(GPIO2_IDR_Addr,n)  //input

    #define P3out(n)   BIT_ADDR(GPIO3_ODR_Addr,n)  //output
    #define P3in(n)    BIT_ADDR(GPIO3_IDR_Addr,n)  //input

    #define P4out(n)   BIT_ADDR(GPIO4_ODR_Addr,n)  //output
    #define P4in(n)    BIT_ADDR(GPIO4_IDR_Addr,n)  //input

    #define P5out(n)   BIT_ADDR(GPIO5_ODR_Addr,n)  //output
    #define P5in(n)    BIT_ADDR(GPIO5_IDR_Addr,n)  //input

    //#ifdef __cplusplus
    //}
    //#endif

    #endif /* SYS_H_ */


    上面是定义的位带操作头文件sys.h,下面是main函数点灯

    //定义位带操作
    #define LED1 P3out(14)  //P3_14
    #define LED2 P3out(3)   //P3_3
    #define LED3 P2out(2)  //P2_2


    int main(void) {

              /* Init board hardware. */
        BOARD_InitBootPins();  //已经初始化了LED三个引脚,初始化GPIO引脚测试过了无问题
        BOARD_InitBootClocks();
        BOARD_InitBootPeripherals();
              /* Init FSL debug console. */
        BOARD_InitDebugConsole();


        LED1 = 0;
        LED2 = 0;
        LED3 = 0;

    //调用例程提供的代码可以点亮,说明初始化LED引脚无问题
    //    LED1_ON();
    //    LED2_ON();
    //    LED3_ON();


    while(1) {

           }

    }


    我知道答案 目前已有4人回答
    今天天气不错!签到!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-12 16:11
  • 签到天数: 818 天

    连续签到: 1 天

    [LV.10]以坛为家III

    3

    主题

    860

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2759
    最后登录
    2025-5-22
    发表于 2019-12-16 13:55:52 | 显示全部楼层
    好像没看到这些步骤?
    1、配置工具配置引脚为GPIO
    2、打开GPIO时钟
    3、设置引脚方向为输出
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-2-4 16:14
  • 签到天数: 139 天

    连续签到: 1 天

    [LV.7]常住居民III

    14

    主题

    212

    帖子

    0

    高级会员

    Rank: 4

    积分
    881
    最后登录
    2021-2-4
     楼主| 发表于 2019-12-16 16:33:59 | 显示全部楼层
    idiy 发表于 2019-12-16 13:55
    好像没看到这些步骤?
    1、配置工具配置引脚为GPIO
    2、打开GPIO时钟

    这些初始化BOARD_InitBootPins();函数已经初始化了,代码注释写了
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-2-4 16:14
  • 签到天数: 139 天

    连续签到: 1 天

    [LV.7]常住居民III

    14

    主题

    212

    帖子

    0

    高级会员

    Rank: 4

    积分
    881
    最后登录
    2021-2-4
     楼主| 发表于 2019-12-16 17:06:24 | 显示全部楼层
    通过调试,使用位带操作实现了LED翻转的效果,即实现GPIO_PortToggle()函数的效果,映射NOT0到NOT5寄存器的地址,查阅LPC54628J512手册得到地址

    下面是代码:
    #ifndef SYS_H_
    #define SYS_H_

    #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))


    #define NOT0 (0x2300U)
    #define NOT1 (0x2304U)
    #define NOT2 (0x2308U)
    #define NOT3 (0x230CU)
    #define NOT4 (0x2310U)
    #define NOT5 (0x2314U)


    //toggle
    #define GPIO0_NOT_Addr (GPIO_BASE+NOT0)
    #define GPIO1_NOT_Addr (GPIO_BASE+NOT1)
    #define GPIO2_NOT_Addr (GPIO_BASE+NOT2)
    #define GPIO3_NOT_Addr (GPIO_BASE+NOT3)
    #define GPIO4_NOT_Addr (GPIO_BASE+NOT4)
    #define GPIO5_NOT_Addr (GPIO_BASE+NOT5)


    //toggle
    #define P0toggle(n) BIT_ADDR(GPIO0_NOT_Addr,n)  //toggle
    #define P1toggle(n) BIT_ADDR(GPIO1_NOT_Addr,n)  //toggle
    #define P2toggle(n) BIT_ADDR(GPIO2_NOT_Addr,n)  //toggle
    #define P3toggle(n) BIT_ADDR(GPIO3_NOT_Addr,n)  //toggle
    #define P4toggle(n) BIT_ADDR(GPIO4_NOT_Addr,n)  //toggle
    #define P5toggle(n) BIT_ADDR(GPIO5_NOT_Addr,n)  //toggle


    #endif /* SYS_H_ */


    定义好位带操作sys.h的头文件,在main函数添加:

    #define LED1 P3toggle(14)
    #define LED2 P3toggle(3)
    #define LED3 P2toggle(2)


    void delay(void)
    {
        volatile uint32_t i = 0;
        for (i = 0; i < 5000000; ++i)
        {
            __asm("NOP"); /* delay */
        }
    }

    int main(void) {
              /* Init board hardware. */
        BOARD_InitBootPins();  //已经初始化三个LED引脚了,分别是P3_14,P3_3,P2_2
        BOARD_InitBootClocks();
        BOARD_InitBootPeripherals();
              /* Init FSL debug console. */
        BOARD_InitDebugConsole();


        while(1)
        {
                LED1 = !LED1;
                LED2 = !LED2;
                LED3 = !LED3;

            delay();
        }

    }


    通过上面代码可以实现用位带操作控制LED翻转,如果要实现可读可写操作(直接通过位带操作赋值或读取操作),通过查看手册需要实现寄存器B的地址映射,实际使用有P0--P5 GPIO port,
    手册给出的是一个范围 B[0x0000:0x00B6],实际使用的形式是B[port][pin],例:LED1为P3_14-->>B[3][14]。类似一维数据转化为二维数组。但是每个独立的P0 ,P1,P2,P3,P4和P5的地址没有给出,这样地址映射无法写成NOTE寄存器映射控制LED翻转的方式。尝试猜测地址,假设P0,P1等都是依次往后排,一个字节代表一个引脚,LPC54628J512ET180总共有145个引脚,总共空间有182(0x00B6)字节,这样P0首地址偏移0x00字节,P1偏移32字节,P3引脚偏移64字节...等,测试结果是失败的,没有实现位带操作的效果,LED无反应。那这个问题是否就可以转化为怎样映射B寄存器的地址?求助!!!



    not.png
    B_reg.png
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    723

    主题

    6382

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25501
    最后登录
    2025-9-11
    发表于 2019-12-23 14:10:45 | 显示全部楼层
    楼主你好!
    你看下LPC54628的用户手册,如下章节
    2.1.2.2 Bit-band addressing
    然后按照那边的地址去操作下看看,是否有用。

    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-11 23:26 , Processed in 0.093967 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表