0

我想变短。昨天我得到了一个 Pico,昨天晚上我花了一个晚上通过 Linux 在 mi Pico 上制作了一个 blink.c(来自 Raspberry 网站),我让它工作了。

现在我想制作 myblink.c,它是低级编程(寄存器和所有这些)中的 blink.c。但我上一次进行低级编程是在 5 年前在 MSP430 上,我已经不记得基础知识了。有人可以帮我吗?对不起。如何在 C 中进行这种低级编程编译一个 uf2 文件,使我的树莓派 pico 闪烁 25 针上的 LED?它可以编译,但 Pico 什么也不做。显然这段代码不正确,我可以改变什么来使它工作?谢谢你。

下面是 myblink.c 和 CMakeLists.txt:

#include <stdio.h>
#include <stdlib.h>

#define SIO_BASE        0xd0000000
#define GPIO_IN         0xd0000004
#define GPIO_HI_IN      0xd0000008
#define GPIO_OUT        0xd0000010
#define GPIO_OUT_SET    0xd0000014
#define GPIO_OUT_CLR    0xd0000018
#define GPIO_OUT_XOR    0xd000001c
#define GPIO_OE         0xd0000020
#define GPIO_OE_SET     0xd0000024
#define GPIO_OE_CLR     0xd0000028
#define GPIO_OE_XOR     0xd000002c
#define GPIO_HI_OUT     0xd0000030

typedef unsigned int uint;

void write32(uint dst, uint val){
    uint dst_u = (uint)dst;
    dst_u = val;  
    return;
}

uint read32(uint src){
    uint src_u = (uint)src;
    return src;
}

int main(){
    uint gpoes = read32(GPIO_OE);
    gpoes |= (1<<25);
    write32(GPIO_OE, gpoes);

    //int i=0;

    while(1){
        //turn on pin 0
        write32(GPIO_OUT, 1<<25);
        //delay
        //while (i < 0x80000){
        //    i++;    
        //}
        //turn off pin 0
        //write32(GPIO_OUT_CLR, 1<<25);
        //delay
        //while (i < 0x80000){
        //    i++;    
        //}
    }        
}
cmake_minimum_required(VERSION 3.12)

# PUll in PICO SDK (must be before project)
include(pico_sdk_import.cmake)

project(myblink C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})

# Initialize the SDK
pico_sdk_init()

add_executable(myblink
    myblink.c
    )

# Pull in our pico_stdlib which pulls in common
target_link_libraries(myblink pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(myblink)
4

3 回答 3

1

以下是它在汇编程序中的执行方式:

void write32(uint dst, uint val){
    uint dst_u = (uint)dst; //a register gets the value from stack pop (dst) 
    dst_u = val; // that same register gets overwritten from stack pop (val)
    return; // ret and nothing was achieved by this function
}

如果这个函数的原因是改变 whereGPIO_OUT指向的值,val那么你必须通过引用传递它:

void write32(uint &dst, uint val){
    dst = val;
}
于 2021-11-27T16:42:41.193 回答
0

我没有使用过这个特定的目标,但通常如果您没有预定义的所有这些寄存器的寄存器映射,那么您可以按照此处的建议自行定义它们:如何从固件访问硬件寄存器?

然后我们可以像这样修复您的代码:

// #include <stdio.h> avoid stdio.h on microcontrollers
#include <stdint.h>

#define SIO_BASE (*(volatile uint32_t*)0xd0000000u)
// ... and so on

// typedef unsigned int uint; get rid of home-made garage standard types

// replace "magic numbers" with meaningful names, "PORTX_PIN25" or whatever it might be called in hw
#define MEANINGFUL_NAME_HERE (1u << 25) 

int main(){
    GPIO_OE |= MEANINGFUL_NAME_HERE;

    while(1){
        GPIO_OUT |= MEANINGFUL_NAME_HERE;

        // write an actually working busy-delay loop by including volatile:
        for(volatile int i=0; i<0x80000; i++)
        {}

        GPIO_OUT_CLR |= MEANINGFUL_NAME_HERE;
        // I'm assuming GPIO_OUT &= ~MEANINGFUL_NAME_HERE; would work too

        for(volatile int i=0; i<0x80000; i++)
        {}
    }        
}

可能你也可以做一点切换:(GPIO_OUT_CLR ^= ...按位异或)。然后你只需要1个延迟循环。

于 2021-09-23T08:50:20.713 回答
-1

尝试更正您的读写功能。

下面是读取函数的样子:

uint read32(addr){
    uint* base = (uint*)addr;
    uint value = *base;
    return value; }

下面是 write 函数的样子:

void write32(void *dst, uint val){
    uint* dst_u = (uint*)dst;
    *dst_u = val;
    return;
}

毕竟,我对 Rpi pico 了解不多,但这似乎是您代码中的问题之一。

于 2021-09-22T22:45:18.820 回答