我在调TEL6621的时候的一个I2C 程序。用的是中断
注意: TEL6621 的I2C read 是如下这样的
start ADDR D0 D1 D2 D3 STOP
I2C.C-
- #include "main.h"
- I2C_StruDef I2C1;
- void Bsp_I2CInit(void)
- {
- CLK_PCKENR1 |= 0x01;
- I2C_CR1 = 0x00; //禁用I2C外设
- //如果需产生100k的时钟,假始输入时钟为8MHz,则Tck = 125ns.
- //因为100k时钟半个周期为5us(5000ns), CCR = 5000/125 = 40(28h)
- I2C_FREQR = 16; //输入外设时钟频率为16MHz (如果设置为8M, 实际输入是16M时,I2C时钟以16M为准)
- I2C_CCRH = 0x00; //标准模式
- I2C_CCRL = 0x50;
- //标准模式下,最大允许上升时间为1000ns, 因为Tck = 125ns,
- //则TRISER = (1000 / 125 + 1) = 9
- I2C_TRISER = 0x09; //设置上升时间
- I2C_CR1 = 0x01; //开启I2C外设
- }
- void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
- {
- if(0x02 == (I2C_SR3 & 0x02))
- {
- ;
- }
- else
- {
- I2C1.State = I2C_WRITEMODE;
- I2C1.DeviceAddr = Dev_Addr;
- I2C1.SubAddr = Sub_Addr;
- I2C1.Tx_I2C_Buf = pdata;
- I2C1.Tx_Cnt = num;
- I2C1.Rx_Cnt = 0;
- I2C1.Cnt = 0;
-
- I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
- I2C_CR2 = 0x01; //产生开始位
- }
- }
- void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num)
- {
- if(0x02 == (I2C_SR3 & 0x02))
- {
- ;
- }
- else
- {
- I2C1.State = I2C_READMODE;
- I2C1.DeviceAddr = Dev_Addr;
- I2C1.SubAddr = Sub_Addr;
- I2C1.Rx_I2C_Buf = pdata;
- I2C1.Rx_Cnt = num;
- I2C1.Tx_Cnt = 0;
- I2C1.Cnt = 0;
-
- I2C_ITR = 0x07; //使能事件和出错中断, 缓冲中断
- I2C_CR2 = 0x01; //产生开始位
- }
- TIM2DlyHMSM(0, 0, 0, 10);
- }
- void I2C_Interrupt_Handler(void)
- {
- uint8_t temp;
- if(0x01 == (I2C_SR1 & 0x01)) //EV5, 开始位已发送
- {
- temp = I2C_SR1;
-
- if(I2C_WRITEMODE == I2C1.State)
- I2C_DR = I2C1.DeviceAddr & 0xfe;
- else if(I2C_READMODE == I2C1.State)
- I2C_DR = I2C1.DeviceAddr | 0x01;
- else;
- }
- else if(0x02 == (I2C_SR1 & 0x02)) //EV6, 器件地址已发送
- {
- temp = I2C_SR1;
- temp = I2C_SR3;
-
- if(I2C_WRITEMODE == I2C1.State)
- I2C_DR = I2C1.SubAddr;
- else if(I2C_READMODE == I2C1.State)
- {
- if(I2C1.Rx_Cnt > 1) I2C_CR2 = 0x04;
- else if(I2C1.Rx_Cnt == 1) I2C_CR2 = 0x00;
- else I2C_CR2 = 0x02; //产生STOP位
- }
- else;
- }
- else if(0x40 == (I2C_SR1 & 0x40)) //EV7
- {
- if(I2C1.Cnt < (I2C1.Rx_Cnt - 1))
- {
- I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
- I2C1.Cnt++;
-
- if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
- {
- I2C_CR2 = 0x02; //产生STOP位, no ack
- }
- }
- else if(I2C1.Cnt == (I2C1.Rx_Cnt - 1))
- {
- I2C1.Rx_I2C_Buf[I2C1.Cnt] = I2C_DR;
- }
- else;
- }
- else if(0x80 == (I2C_SR1 & 0x80)) //EV8
- {
- temp = I2C_SR1;
-
- if(I2C1.Cnt < I2C1.Tx_Cnt)
- {
- I2C_DR = I2C1.Tx_I2C_Buf[I2C1.Cnt];
- I2C1.Cnt++;
- }
- else
- {
- I2C_CR2 = 0x02; //产生STOP位
- }
- }
- else
- {
- printf("\r\n I2C_SR1 = %x", (uint16_t)I2C_SR1);
- temp = I2C_SR1;
- }
- if(I2C_SR2)
- {
- printf("\r\n I2C_SR2 = %x", (uint16_t)I2C_SR2);
- I2C_SR2 = 0;
- }
- }
I2C.H
-
- #ifndef _BSP_I2C_H_
- #define _BSP_I2C_H_
- #define I2C_WRITEMODE 0
- #define I2C_READMODE 1
- typedef struct
- {
- uint8_t State;
- uint16_t Cnt;
- uint16_t Rx_Cnt, Tx_Cnt;
- uint8_t DeviceAddr;
- uint8_t SubAddr;
- uint8_t *Rx_I2C_Buf;
- uint8_t *Tx_I2C_Buf;
- }I2C_StruDef;
- extern I2C_StruDef I2C1;
- void Bsp_I2CInit(void);
- void Bsp_I2CWrite(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
- void Bsp_I2CRead(uint8_t Dev_Addr, uint8_t Sub_Addr, uint8_t* pdata, uint16_t num);
- void I2C_Interrupt_Handler(void);
- #endif
|