GPIO实验

GPIO实验

裸机程序两种烧写方法

  • 直接烧写到SD卡 不需要superboot,地址0x00
    代码:1.leds_s
    其中mkv210_image.c是校验前16K
    start.S里面是汇编代码,需要查看datasheet
    write2sd是拷贝脚本 把编译好的.bin文件拷贝到SD卡里面
    make
    ./write2sd
    把SD卡插到开发板 SD卡启动 可以看到灯亮
  • 用minitools烧写裸机程序(需要superboot,地址0x20000000)
    先用SD_flasher烧写superboot到SD卡,拷贝images/FriendlyArm.ini文件到SD卡。SD卡插到开发板。
    打开mini tools,开发板SD卡模式启动,上电。屏幕出现connect
    烧写裸机程序到内存,地址0x20000000
    映像选择编译好的210.bin(注意makefile里面的地址也是0x20000000)
    下载运行 此时开发板四个灯都亮了

自己写裸机程序

datasheet

要看两个:厂家提供的开发板子的电路图和主芯片的手册,先通过厂家的电路图看led的引脚是怎么连到主芯片的?哪个引脚?再查主芯片的手册查看该引脚是怎么控制驱动led的?

怎么判定GPIO是输入还是输出?

GPIO寄存器属于SFRS(special function register特殊功能寄存器)
读寄存器:输入
写寄存器:输出
led是输出,寄存器GPJ2_0到GPJ2_3
GPJ2CON:地址0xE0200280
output=0001
GPJ2DAT: 地址0xE0200284
输出是0x00

从零写代码

  • 汇编:
    1. start.S
.text
.global _start
_start:
     LDR R0,=0xE0200280
     MOV R1,#00001111
     STR R1,[R0]

     LDR R0,=0xE0200284
     MOV R1,#00
     STR R1,[R0]
loop:
     B loop
  1. Makefile
led.bin:start.S
     arm-linux-gcc -c -o led.o start.S
     arm-linux-ld -Ttext 0x20000000 led.o -o led.elf
     arm-linux-objcopy -O binary -S led.elf led.bin
clean:
     rm -f *.o *.elf *.bin
  • C语言和汇编混合:
    1. start.S
.text
.global _start
_start:
     BL main
loop:
     B loop
  1. main.c
#define GPJCON *(volatile unsigned long*)0xE0200280
#define GPJDAT *(volatile unsigned long*)0xE0200284
int main()
{
     GPJCON |=(1<<0);
     GPJDAT &=~(1<<0);
     return 0;
}
  1. Makefile
led.bin:start.S main.c
     arm-linux-gcc -c -o led.o start.S
     arm-linux-gcc -c -o main.o main.c
     arm-linux-ld -Ttext 0x20000000 led.o main.o -o led.elf
     arm-linux-objcopy -O binary -S led.elf led.bin
clean:
     rm -f *.o *.elf *.bin
### GPIO 实验与 ADS 模数转换配置 在进行基于 GPIO实验并涉及模数转换器(ADS)时,可以参考以下配置方法和示例代码。以下是针对不同平台的具体实现方式。 #### ESP8266 平台下的 ADS1115 配置 对于 ESP8266 使用 Arduino 开发环境的情况,可以通过 Wire 库来初始化 I2C 接口并与 ADS1115 进行通信。具体步骤如下: - **I2C 引脚定义** 在 ESP8266 上,可以选择任意 GPIO 来模拟 I2C 协议(软 I2C),或者使用硬件支持的固定引脚组合。通常推荐使用默认的 D2 (GPIO4) 和 D1 (GPIO5)[^3]。 - **ADS1115 初始化** ADS1115 支持多种工作模式,包括单次采样模式和连续采样模式。为了降低功耗,在不需要频繁采集数据的情况下建议使用单次采样模式[^2]。 ```cpp #include <Wire.h> #include "Adafruit_ADS1X15.h" // 定义 ADS1115 对象 Adafruit_ADS1115 ads; void setup() { Serial.begin(9600); // 设置 SDA 和 SCL 引脚为默认值 #define SDA_PIN 4 #define SCL_PIN 5 Wire.begin(SDA_PIN, SCL_PIN); // 初始化 I2C 总线 if (!ads.begin()) { // 初始化 ADS1115 设备 Serial.println("Failed to initialize ADS1115."); while (1); } } void loop() { int16_t adc0 = ads.readADC_SingleEnded(0); // 读取第 0 通道的数据 float voltage = adc0 * (4.096 / 32768); // 计算实际电压值 Serial.print("AIN0: "); // 打印结果到串口监视器 Serial.println(voltage); delay(1000); // 延迟一秒再继续下一轮读取 } ``` 上述代码展示了如何通过 `Wire` 库设置 I2C 参数以及调用 Adafruit 提供的库函数完成对 ADS1115 的操作。 --- #### STM32 或 GD32F470 下的 SPI/UART/I2C 配置 如果目标 MCU 是 ARM Cortex-M 系列处理器,则需要根据具体的外设资源分配情况调整驱动程序设计思路。例如,在 GD32F470 中移植 ADS1115 功能模块时需要注意以下几点: - **硬件连接** - 将 ADS1115 的 ADR 地址管脚拉高或接地以改变设备地址。 - 正确接好 VDD、GND、SDA、SCL 四条线路至微控制器相应 IO 口上。 - **软件框架构建** ```c #include "gd32f4xx.h" #include "systick.h" #include "i2c.h" #define ADS1115_ADDR 0x48 << 1 /* 默认从机地址 */ uint8_t buffer[2]; /* 数据缓冲区 */ /* 函数声明 */ void i2c_master_init(void); int read_ads_value(uint8_t channel); /** * @brief 主函数入口 */ int main(void){ uint16_t value; rcu_periph_clock_enable(RCU_GPIOB | RCU_I2C1); // 启用所需外设时钟源 gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6|GPIO_PIN_7); gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7); gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_6|GPIO_PIN_7); i2c_master_init(); // 初始化 I2C 外设 systick_config(); while(1){ value = read_ads_value(0); // 获取指定通道上的数值 printf("Channel 0 Value:%d\r\n",value); delay_1ms(1000); // 添加适当延时防止打印过快溢出缓存 } } /** * @brief 发起一次完整的 ADS1115 测量流程 * @param[in] chn 待测信道编号 [0~3] * @retval 返回对应 ADC 数字码值 */ int read_ads_value(uint8_t channel){ uint8_t config_reg[]={ ((channel & 0b11)<<12)|(CONFIG_MUX_SINGLEENDED), // MUX选择单端输入 CONFIG_GAIN_ONE<<8 | // PGA增益=1倍 CONFIG_MODE_CONTINUOUS // 工作于持续转换状态 }; i2c_start(); i2c_send_addr(ADS1115_ADDR, I2C_MASTER_WRITE); i2c_write_byte(I2C_REG_POINTER_CONFIG); // 寄存器指针指向配置寄存器 i2c_write_buffer(config_reg,sizeof(config_reg)); // 写入配置参数 i2c_stop(); Delay_ms(10); // 给予一定时间让芯片完成内部运算过程 i2c_start(); i2c_send_addr(ADS1115_ADDR,I2C_MASTER_READ); i2c_read_multiple_bytes(buffer, sizeof(buffer)); i2c_nack_then_stop(); return (((buffer[0]<<8)|buffer[1])>>4; // 解析高低字节拼凑成最终整型变量形式返回给调用者 } ``` 此部分实现了基础功能——向 ADS1115 编程设定测量条件并通过轮询机制获取最新计算出来的量化结果。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值