gd32e10单片机 sd3078的驱动程序
时间: 2023-07-15 12:15:33 浏览: 252
SD3078是一款I2C总线实时时钟芯片,其驱动程序需要涉及到I2C总线的相关操作。以下是一个基于GD32E10单片机的SD3078驱动程序的示例代码,仅供参考:
```c
#include "gd32e10x.h"
#define I2C_SCL_PIN GPIO_PIN_6
#define I2C_SDA_PIN GPIO_PIN_7
#define I2C_GPIO_PORT GPIOB
#define I2C_GPIO_CLK RCU_GPIOB
#define I2C_RCC_CLK RCU_I2C0
#define SD3078_ADDR 0xDE // I2C总线地址
#define I2C_ACK 0
#define I2C_NACK 1
/* 初始化I2C总线 */
void i2c_init(void)
{
rcu_periph_clock_enable(I2C_RCC_CLK);
rcu_periph_clock_enable(I2C_GPIO_CLK);
gpio_init(I2C_GPIO_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN | I2C_SDA_PIN);
gpio_pin_remap_config(GPIO_I2C0_REMAP, ENABLE);
i2c_deinit(I2C0);
i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, SD3078_ADDR, I2C_I2COADDR_DUAL_ENABLE);
i2c_enable(I2C0);
}
/* I2C总线发送START信号 */
void i2c_start(void)
{
i2c_ack_config(I2C0, I2C_ACK);
i2c_start_on_bus(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
}
/* I2C总线发送STOP信号 */
void i2c_stop(void)
{
i2c_ack_config(I2C0, I2C_ACK);
i2c_stop_on_bus(I2C0);
while(i2c_flag_get(I2C0, I2C_FLAG_STPDET));
}
/* I2C总线发送ACK */
void i2c_ack(void)
{
i2c_ack_config(I2C0, I2C_ACK);
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
}
/* I2C总线发送NACK */
void i2c_nack(void)
{
i2c_ack_config(I2C0, I2C_NACK);
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
}
/* I2C总线发送数据 */
void i2c_send_byte(uint8_t byte)
{
i2c_data_transmit(I2C0, byte);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
}
/* I2C总线接收数据 */
uint8_t i2c_receive_byte(void)
{
i2c_ack_config(I2C0, I2C_ACK);
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
i2c_ack_config(I2C0, I2C_NACK);
return i2c_data_receive(I2C0);
}
/* SD3078读取时间 */
void sd3078_read_time(uint8_t *time_buf)
{
i2c_start();
i2c_send_byte(SD3078_ADDR | I2C_DIRECTION_TRANSMITTER);
i2c_send_byte(0x00); // 寄存器地址
i2c_start();
i2c_send_byte(SD3078_ADDR | I2C_DIRECTION_RECEIVER);
for(uint8_t i = 0; i < 6; i++) {
time_buf[i] = i2c_receive_byte();
if(i == 5) {
i2c_nack();
} else {
i2c_ack();
}
}
i2c_stop();
}
/* SD3078设置时间 */
void sd3078_set_time(uint8_t *time_buf)
{
i2c_start();
i2c_send_byte(SD3078_ADDR | I2C_DIRECTION_TRANSMITTER);
i2c_send_byte(0x00); // 寄存器地址
for(uint8_t i = 0; i < 6; i++) {
i2c_send_byte(time_buf[i]);
}
i2c_stop();
}
```
需要注意的是,此示例代码中的IO口和时钟等配置仅供参考,具体应根据实际情况进行调整。并且,SD3078的寄存器地址及数据格式也需要根据其芯片手册进行设置。
阅读全文