三天前我安装了 GNAT-GPS 和 AVR-ELF 来玩。我眨了眨眼,以为我可以再玩一些。我没有非 VHDL Ada 经验。
这是我在 C 中工作的场景:
我进行了设置,以便使用 GPIO typedef,我可以参考设置 GPIO 引脚所需的所有信息(即引脚号、引脚注册地址、dd 注册地址和端口注册地址)。然后我对 LED0 做同样的事情,这样逻辑上我可以将 LED0 连接到 GPIO15,它本身连接到 AVR 微控制器的 PB1。
我尝试在 Ada 中做同样的事情。我觉得我可能正在用 Ada 写 C;如果在 Ada 中有更好的方法可以做到这一点,请随时告诉我。
我为特定引脚设置了 AVR 寄存器以连接到其短名称参考:
-- PB1
PB1_Port_reg : Unsigned_8;
PB1_Dd_reg : Unsigned_8;
PB1_Pin_reg : Unsigned_8;
for PB1_Port_reg'Address use AVR.Atmega328p.PORTB'Address;
for PB1_Dd_reg'Address use AVR.Atmega328p.DDRB'Address;
for PB1_Pin_reg'Address use AVR.Atmega328p.PINB'Address;
PB1_Pin : constant := 1;
然后我设置它的短名称引用以连接到它的封装引脚号:
-- ATmega328p DIP28 Pin15 is PB1
Pin15_Port_reg : Unsigned_8;
Pin15_Dd_reg : Unsigned_8;
Pin15_Pin_reg : Unsigned_8;
for Pin15_Port_reg'Address use PB1_Port_reg'Address;
for Pin15_Dd_reg'Address use PB1_Dd_reg'Address;
for Pin15_Pin_reg'Address use PB1_Pin_reg'Address;
Pin15_Pin : constant := PB1_Pin;
接下来,我定义一个记录来保存引脚的所有参数:
type gpio_t is record
pin : Unsigned_8;
pin_reg : Unsigned_8;
dd_reg : Unsigned_8;
port_reg : Unsigned_8;
end record;
这是为了允许我编写以下函数:
procedure gpio_map (gpio_t_dest : in out gpio_t; gpio_t_pin, gpio_t_pin_reg, gpio_t_dd_reg, gpio_t_port_reg : in Unsigned_8) is
begin
gpio_t_dest.pin := gpio_t_pin;
gpio_t_dest.pin_reg := gpio_t_pin_reg;
gpio_t_dest.dd_reg := gpio_t_dd_reg;
gpio_t_dest.port_reg := gpio_t_port_reg;
end gpio_map;
将来,我希望将其设置为:
procedure gpio_map_future (gpio_t_dest : in out gpio_t; gpio_t_src : in gpio_t) is
begin
gpio_t_dest.pin := gpio_t_src.pin;
gpio_t_dest.pin_reg := gpio_t_src.pin_reg;
gpio_t_dest.dd_reg := gpio_t_src.dd_reg;
gpio_t_dest.port_reg := gpio_t_src.port_reg;
end gpio_map;
此 gpio_map 函数用于将封装引脚 gpio_t 连接到封装引脚号:
gpio_map(gpio15, Pin15_pin, Pin15_pin_reg, Pin15_dd_reg, Pin15_port_reg);
如果我使用此功能,我发现 LED 已正确初始化:
core_reg_write(Pin15_dd_reg, Shift_Left(1,Integer(Pin15_pin))); -- works
但是如果我这样做没有正确初始化:
core_reg_write(gpio15.dd_reg, Shift_Left(1,Integer(gpio15.pin))); -- does not work
但是,这有效:
core_reg_write(Pin15_dd_reg, Shift_Left(1,Integer(gpio15.pin))); -- works
我很清楚我有
Pin15_pin = 1 @ address (don't care - a variable)
Pin15_pin_reg = (don't care) @ address 0x23
Pin15_dd_reg = (0b00000000) @ address 0x24
Pin15_port_reg = (don't care) @ address 0x25
然后
gpio15.pin = 1 @ address (don't care, but not same as Pin15_pin address)
gpio15.pin_reg = (don't care) @ address IS NOT 0x23
gpio15.dd_reg = (don't care) @ address IS NOT 0x24
gpio15.port_reg = (don't care) @ address IS NOT 0x25
如何维护记录成员的固定内存地址,即获取
gpio15.pin_reg = (don't care) @ address 0x23
gpio15.dd_reg = (don't care) @ address 0x24
gpio15.port_reg = (don't care) @ address 0x25
如果我也能得到,那就更好了
gpio15.pin = 1 @ address (same as Pin15_pin address)
很抱歉这个问题很长;希望它有助于说清楚。