123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- #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--;
- }
- }
- }
|