[C] 纯文本查看 复制代码
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/irq.h"
#include "hardware/gpio.h"
// I2C defines
// This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 400KHz.
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define I2C_PORT i2c0
#define I2C0_PORT i2c0
#define I2C0_SDA 8
#define I2C0_SCL 9
#define I2C1_PORT i2c1
#define I2C1_SDA 14
#define I2C1_SCL 15
#define MASTER 0
#define SLAVE 1
//函数声明
void init_I2CPort(i2c_inst_t *i2c, uint baudrate,uint I2C_SDA,uint I2C_SCL,bool mood);
void I2C0_callback(void);
int I2C_BUSCAN(void);
bool reserved_addr(uint8_t addr);
//全局变量
uint8_t ram_addr = 0;
uint8_t ram[256];
uint8_t tx_buff[2]={0x01,0xaa};
uint8_t i2c_buff[8]={0};
uint32_t i=0;
int main()
{
int ret=0;
stdio_init_all();
// I2C Initialisation. Using it at 100Khz.
init_I2CPort(I2C1_PORT,1000*100,I2C1_SDA,I2C1_SCL,MASTER);
printf("hello i2c1\n");
init_I2CPort(I2C0_PORT,1000*100,I2C0_SDA,I2C0_SCL,SLAVE);
printf("hello i2c0\n");
// I2C0_PORT->hw->intr_mask = (1 << 12) | (1 << 10) | (1 << 9) | (1 << 6) | (1 << 5) | (1 << 2);
I2C0_PORT->hw->intr_mask = I2C_IC_INTR_MASK_M_RX_FULL_BITS | I2C_IC_INTR_MASK_M_RD_REQ_BITS | I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS | I2C_IC_INTR_MASK_M_STOP_DET_BITS | I2C_IC_INTR_MASK_M_START_DET_BITS;
irq_set_exclusive_handler(I2C0_IRQ,I2C0_callback);
irq_set_enabled(I2C0_IRQ,true);
printf("irq_set_enabled i2c0 irq\n");
printf("hello i2c0 irq=%d\n",irq_is_enabled(I2C0_IRQ));
printf("i2c init ok!\n");
gpio_init(25);
gpio_set_dir(25,GPIO_OUT);
while(1)
{
printf("ram[0]=%x\n\r",ram[0]);
sleep_ms(1000);
/*
i2c_write_blocking(I2C1_PORT,0X53,tx_buff,2,true);
i2c_read_raw_blocking(I2C0_PORT,i2c_buff,2);
// printf("ret=%d\n",ret);
printf("i2c_buff=0x%x 0x%x\n\r",i2c_buff[0],i2c_buff[1]);
if((i2c_buff[0]==0x00)&&(i2c_buff[1]==0x99))
{
i2c_write_raw_blocking(I2C0_PORT,tx_buff,2);
i++;
}
*/
}
}
void init_I2CPort(i2c_inst_t *i2c, uint baudrate,uint I2C_SDA,uint I2C_SCL,bool mood)
{
i2c_init(i2c,baudrate);
// Addresses of the form 000 0xxx or 111 1xxx are reserved. No slave should
if(SLAVE==mood) i2c_set_slave_mode(i2c,true,0X53);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
}
void I2C0_callback(void)
{
i++;
// Get interrupt status
uint32_t status = i2c0->hw->intr_stat;
// Check to see if we have received data from the I2C controller
if (status & I2C_IC_INTR_STAT_R_RX_FULL_BITS) {
// Read the data (this will clear the interrupt)
uint32_t value = i2c0->hw->data_cmd;
// Check if this is the 1st byte we have received
if (value & I2C_IC_DATA_CMD_FIRST_DATA_BYTE_BITS) {
// If so treat it as the address to use
ram_addr = (uint8_t)(value & I2C_IC_DATA_CMD_DAT_BITS);
} else {
// If not 1st byte then store the data in the RAM
// and increment the address to point to next byte
ram[ram_addr] = (uint8_t)(value & I2C_IC_DATA_CMD_DAT_BITS);
ram_addr++;
}
}
// Check to see if the I2C controller is requesting data from the RAM
if (status & I2C_IC_INTR_STAT_R_RD_REQ_BITS) {
// Write the data from the current address in RAM
i2c0->hw->data_cmd = (uint32_t)ram[ram_addr];
// Clear the interrupt
i2c0->hw->clr_rd_req;
// Increment the address
ram_addr++;
}
if(ram[0]==0)
{
gpio_put(25, 0);
}
else if (ram[0]!=0)
{
gpio_put(25, 1);
}
}
int I2C_BUSCAN(void)
{
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr)
{
if (addr % 16 == 0)
{
printf("%02x ", addr);
}
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(I2C1_PORT, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
printf("Done.\n");
return 0;
}
bool reserved_addr(uint8_t addr)
{
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}