#include "board.h" /* --EV5 */ #define I2C_BUSY ((uint32_t)0x00020000) /* --EV5 */ #define I2C_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* --EV6 */ #define I2C_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ #define I2C_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ /* --EV9 */ #define I2C_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ /* Master RECEIVER mode -----------------------------*/ /* --EV7 */ #define I2C_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ /* Master TRANSMITTER mode --------------------------*/ /* --EV8 */ #define I2C_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ /* --EV8_2 */ #define I2C_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ #define Addr24c04 0xa0 /** * 总线初始化 * * @author LXZ (051220) * * @param void */ void hw_iic_init(void) { RCC->APB2ENR |= 1 << 1; GPIO_Set(GPIOB,PIN8,GPIO_MODE_AF_PP,GPIO_SPEED_50M,GPIO_PUPD_PU); GPIO_Set(GPIOB,PIN9,GPIO_MODE_AF_OD,GPIO_SPEED_50M,GPIO_PUPD_NONE); //GPIO_Remap_Set(GPIO_Remap_I2C1, 1); // GPIO_AF_Set(GPIOB, 6, 4); //PG10,AF12 // GPIO_AF_Set(GPIOB, 7, 4); //PG10,AF12 RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; RCC->APB1RSTR |= RCC_APB1RSTR_I2C1RST; RCC->APB1RSTR &= ~RCC_APB1RSTR_I2C1RST; //初始化IIC I2C1->CR2 |= 10; //8; //10M I2C1->CCR |= I2C_CCR_FS; // 快速模式 //I2C1->CCR &= ~I2C_CCR_FS; // 标准模式 I2C1->CCR |= I2C_CCR_DUTY; // 16:9 I2C1->CCR |= 1; //0x28; // I2C1->TRISE = 4; //9; //300ns上升 100ns的时钟周期 I2C1->CR1 |= I2C_CR1_PE; //使能I2C } /** * 总线检查事件状态 * * @author LXZ (051220) * * @param event * * @return unsigned char */ unsigned char hw_iic_check_event(uint32_t event) { uint32_t flag = 0; flag = I2C1->SR1; flag += ((I2C1->SR2) << 16); flag &= 0xffffffff; if ((flag & event) == event) { return 1; } else { return 0; } } /** * 总线停止指令 * * @author LXZ (051220) * * @param void */ void hw_iic_stop(void) { I2C1->CR1 |= I2C_CR1_STOP; } /** * 总线开始指令 * * @author LXZ (051220) * * @param void */ void hw_iic_start(void) { I2C1->CR1 |= I2C_CR1_START; while (!hw_iic_check_event(I2C_MASTER_MODE_SELECT)) ; } /** * 总线免回应指令 * * @author LXZ (051220) * * @param void */ void hw_iic_no_ack(void) { I2C1->CR1 &= (unsigned short)~I2C_CR1_ACK; } /** * 总线回应指令 * * @author LXZ (051220) * * @param void */ void hw_iic_ack(void) { I2C1->CR1 |= I2C_CR1_ACK; } /** * 总线检测是否忙 * * @author LXZ (051220) * * @param void */ void hw_iic_check_busy(void) { while (hw_iic_check_event(I2C_BUSY)) { hw_iic_stop(); } } /** * 总线指定设备开始传送 * * @author LXZ (051220) * * @param addr */ void hw_iic_begin_write(unsigned short addr) { I2C1->DR = addr; while (!hw_iic_check_event(I2C_MASTER_TRANSMITTER_MODE_SELECTED)) ; } /** * 总线指定设备开始接收 * * @author LXZ (051220) * * @param addr */ void hw_iic_begin_recv(unsigned short addr) { I2C1->DR = addr; while (!hw_iic_check_event(I2C_MASTER_RECEIVER_MODE_SELECTED)) ; } /** * 总线写一个字节 * * @author LXZ (051220) * * @param value */ void hw_iic_write_byte(unsigned char value) { I2C1->DR = value; while (!hw_iic_check_event(I2C_MASTER_BYTE_TRANSMITTED)) ; } /** * 总线读取一个字节 * * @author LXZ (051220) * * @param void * * @return unsigned char */ unsigned char hw_iic_read_byte(void) { while (!hw_iic_check_event(I2C_MASTER_BYTE_RECEIVED)) ; return (I2C1->DR); } /** * 获取器件地址 * * @author LXZ (051220) * * @param addr * * @return unsigned char */ unsigned char hw_iic_device_id(unsigned short addr) { unsigned char devicetype = Addr24c04; unsigned char page = 0; page = addr >> 8; page = page << 1; devicetype += page; return devicetype; /* if (addr <= 0x07ff) { if (addr > 0x06ff) { devicetype += 14; } else if (addr > 0x05ff) { devicetype += 12; } else if (addr > 0x04ff) { devicetype += 10; } else if (addr > 0x03ff) { devicetype += 8; } else if (addr > 0x02ff) { devicetype += 6; } else if (addr > 0x01ff) { devicetype += 4; } else if (addr > 0x00ff) { devicetype += 2; } else { devicetype += 0; } } return devicetype; */ } /** * 将地址转换为不带器件的地址 * * @author LXZ (051220) * * @param addr * * @return unsigned short */ unsigned short hw_iic_rw_addr(unsigned short addr) { unsigned char rw_addr = addr; if (addr <= 0x07ff) { if (addr > 0x06ff) { rw_addr -= 0x700; } else if (addr > 0x05ff) { rw_addr -= 0x600; } else if (addr > 0x04ff) { rw_addr -= 0x500; } else if (addr > 0x03ff) { rw_addr -= 0x400; } else if (addr > 0x02ff) { rw_addr -= 0x300; } else if (addr > 0x01ff) { rw_addr -= 0x200; } else if (addr > 0x00ff) { rw_addr -= 0x100; } else { rw_addr -= 0; } } return rw_addr; } /** * 写入一个字节数据 * * @author LXZ (051220) * * @param addr 写入地址,以字节为单位 * @param dat 写入数据 */ void eeprom_write_byte(unsigned short addr, unsigned char dat) { unsigned char devicetype = 0; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_start(); hw_iic_begin_write(devicetype); hw_iic_write_byte(addr); hw_iic_write_byte(dat); hw_iic_stop(); } } /** * 写入数组,以字节为单位 * * @author LXZ (051220) * * @param addr 写入地址 * @param src 写入缓冲 * @param size 写入数量 */ void eeprom_write_array(unsigned short addr, unsigned char *src, int size) { unsigned char devicetype = 0; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_check_busy(); hw_iic_start(); hw_iic_begin_write(devicetype); hw_iic_write_byte(addr); while (size) { hw_iic_write_byte(*src); src++; size--; } hw_iic_stop(); hw_iic_check_busy(); } } /** * 写入字数组 * * @author LXZ (051220) * * @param addr 写入地址 * @param src 数据 * @param size 写入大小 */ void eeprom_write_word_array(unsigned short addr, unsigned short *src, int size) { unsigned char devicetype = 0; addr = addr * 2; size = size * 2; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_check_busy(); hw_iic_start(); hw_iic_begin_write(devicetype); hw_iic_write_byte(addr); while (size) { hw_iic_write_byte((*src)); hw_iic_write_byte((*src) >> 8); src++; size--; } hw_iic_stop(); } } /** * 写入一个字 * * @author LXZ (051220) * * @param addr 写入地址,以字为单位 * @param dat 写入数据 */ void eeprom_write_word(unsigned short addr, unsigned short dat) { unsigned char devicetype = 0; //uint8 tmp; addr = addr * 2; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_check_busy(); hw_iic_start(); hw_iic_begin_write(devicetype); hw_iic_write_byte(addr); hw_iic_write_byte(dat); hw_iic_write_byte(dat >> 8); hw_iic_stop(); } } /** * 写入一个双字长度数据 * * @author LXZ (051220) * * @param addr 写入地址,以字为单位 * @param dat 写入数据 */ void eeprom_write_dword(unsigned short addr, unsigned int dat) { unsigned char devicetype = 0; addr = addr * 2; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_start(); hw_iic_begin_write(devicetype); hw_iic_write_byte(addr); hw_iic_write_byte(dat); hw_iic_write_byte(dat >> 8); hw_iic_write_byte(dat >> 16); hw_iic_write_byte(dat >> 24); hw_iic_stop(); } } /** * 读取一个字节 * * @author LXZ (051220) * * @param addr 读取地址,以字节为单位 * * @return unsigned char 读取结果 */ unsigned char eeprom_read_byte(unsigned short addr) { unsigned char dat = 0; unsigned char devicetype = 0; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_check_busy(); hw_iic_start(); hw_iic_begin_write(devicetype + 0); hw_iic_write_byte(addr); hw_iic_start(); hw_iic_begin_recv(devicetype + 1); hw_iic_no_ack(); hw_iic_stop(); dat = hw_iic_read_byte(); } return dat; } /** * 读取数组 * * @author LXZ (051220) * * @param addr 开始地址 * @param dst 保存缓冲 * @param size 读取数量,以字节为单位 */ void eeprom_read_array(unsigned short addr,unsigned char *dst, int size) { unsigned char devicetype; if (addr < EEPROM_SIZE) { devicetype = hw_iic_device_id(addr); addr = hw_iic_rw_addr(addr); hw_iic_check_busy(); hw_iic_ack(); hw_iic_start(); hw_iic_begin_write(devicetype + 0); hw_iic_write_byte(addr); hw_iic_start(); hw_iic_begin_recv(devicetype + 1); while (size > 0) { if (size == 1) { hw_iic_no_ack(); hw_iic_stop(); } *dst = hw_iic_read_byte(); dst++; size--; } } }