初级会员

- 积分
- 110
- 金钱
- 110
- 注册时间
- 2016-6-2
- 在线时间
- 43 小时
|
发表于 2016-6-13 15:35:26
|
显示全部楼层
这是我的I2C读写AD5274写正常,读有点问题
------------------------------------------------
#include <board.h>
#include <rtthread.h>
#include <finsh.h>
#include "public.h"
#define GPIOB_MODE *(volatile uint32_t *)0x40020400
#define SDAL GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define SDAH GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define SCLL GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define SCLH GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define SDA_READ GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)
#define RESETL GPIO_ResetBits(GPIOB,GPIO_Pin_3)
#define RESETH GPIO_SetBits(GPIOB,GPIO_Pin_3)
#define SDA_IN {GPIOB_MODE &= 0xFFFF3FFF;}
#define SDA_OUT {GPIOB_MODE |= (0x8FFF);}
#define ADDR 0x5e
/* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency
(I2C peripheral input clock) must be a multiple of 10 MHz */
//#define FAST_I2C_MODE
#ifdef FAST_I2C_MODE
#define I2C_SPEED 340000
#define I2C_DUTYCYCLE I2C_DutyCycle_16_9
#else
#define I2C_SPEED 100000
#define I2C_DUTYCYCLE I2C_DutyCycle_2
#endif /* FAST_I2C_MODE*/
void i2c_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// I2C_InitTypeDef I2C_InitStructure;
/* Enable I2C1 clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Configure TIM1 CH1 pin (PE9) as alternate function */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SDAH;
SCLH;
RESETH;
}
void SDA(int i)
{
if(0){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
}
//延时
static void I2C_delay(void)
{
uint8_t i=50;
while(i)
{
__NOP();
i--;
}
}
//开始
static void I2C_Start() //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号
{
SDAH;
I2C_delay();
SCLH;
I2C_delay();
SDAL;
I2C_delay();
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
}
//停止
static void I2C_Stop(void)
{
SDAL;
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
I2C_delay();
SDAH;
I2C_delay();
I2C_delay();
I2C_delay();
}
//写
static void Writebyte(uint8_t frame)
{
uint8_t i;
for(i=0; i<8; i++) {
if((frame << i) & 0x80)
SDAH;
else
SDAL;
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
}
}
//读
static uint8_t Readbyte(void)
{
uint8_t ReadDate;
uint8_t i;
SDA(1);
SDAH;
for(i = 0; i < 8; i++) {
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
ReadDate <<= 1;
if(SDA_READ)
ReadDate += 1;
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
}
SDA(0);
return ReadDate;
}
//等待应答
static int I2C_WaitAck(void)
{
// SDA_IN;
// SDAH;
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
if(SDA_READ != 0) {
// rt_kprintf("%d\n", SDA_READ);
I2C_delay();
I2C_delay();
SCLH;
// return -1;
}
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
// SDA_OUT;
return 0;
}
//应答
static void I2C_Ack(void)
{
SDAL;
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
}
//不应答
static void I2C_NoAck(void)
{
SDAH;
I2C_delay();
I2C_delay();
SCLH;
I2C_delay();
I2C_delay();
I2C_delay();
SCLL;
I2C_delay();
}
//写数据 date(0~16基本为线性调节)
void WriteAD5274(uint8_t Command, uint16_t data)
{
uint8_t frame1,frame2,frame3;
frame1 = ADDR;
frame3 = (data & 0xff);
frame2 = (Command << 2) | ((data >> 8) & 0x03);
rt_kprintf("0x%x 0x%x 0x%x\n", frame1, frame2, frame3);
I2C_Start();
Writebyte(frame1);
I2C_WaitAck();
Writebyte(frame2);
I2C_WaitAck();
Writebyte(frame3);
I2C_WaitAck();
I2C_Stop();
// rt_thread_delay(35);
}
FINSH_FUNCTION_EXPORT(WriteAD5274, uint8_t Command uint16_t data);
//读数据
uint16_t ReadFromAD5274(uint8_t Command)
{
uint8_t frame1, frame2, frame3;
uint16_t data = 0;
uint16_t ReadDate;
frame1 = ADDR;
frame3 = (data&0xff);
frame2 = (Command << 2) | ((data >> 8) & 0x03);
I2C_Start();
Writebyte(frame1);
I2C_WaitAck();
Writebyte(frame2);
I2C_WaitAck();
Writebyte(frame3);
I2C_WaitAck();
I2C_Stop();
I2C_Start();
Writebyte((frame1+1));
I2C_WaitAck();
ReadDate = Readbyte();
I2C_Ack();
ReadDate <<= 8;
ReadDate |= Readbyte();
I2C_NoAck();
I2C_Stop();
rt_kprintf("ReadDate: 0x%04x\n", ReadDate);
return ReadDate&0x03ff;
}
FINSH_FUNCTION_EXPORT(ReadFromAD5274, set uint8_t Command);
void I2C_Reset(void)
{
RESETL;
I2C_delay();
RESETH;
}
FINSH_FUNCTION_EXPORT(I2C_Reset, );
|
|