最近在使用MSP430FR5969的板子驱动OV7725,在第一步用SCCB总线写和读寄存器的时候总是有错误,现在我也不知道是没写进去还是读不到寄存器的内容,每次读厂家ID的时候都是0或者一些随机的值!
IIC.c
#include "driverlib.h"
#include "iic.h"
#include "intrinsics.h"
void Delay50us(void)
{//delay in hardware
TA0CCR0 = 50;
TA0CTL = TASSEL__SMCLK | MC__UP; // SMCLK, UP mode
while(TA0R < 48) {}
TA0CTL &= ~MC__STOP;
}
void Delay5ms(void)
{
unsigned int n = 560;
while (n--);
}
void IIC_Init(void){
//430软件模拟IIC的IO口初始化
P1DIR |= BIT6;
//GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN6); //SDA 6
P1DIR |= BIT7;
//GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN7); //SCL 7
IIC_SCL_OH;
IIC_SDA_OH;
}
void IIC_Start(void){
SDA_OUT();
IIC_SDA_OH;
IIC_SCL_OH;
Delay50us();
IIC_SDA_OL;
Delay50us();
IIC_SCL_OL;
}
void IIC_Stop(void){
SDA_OUT();
IIC_SCL_OL;
IIC_SDA_OL;
Delay50us();
IIC_SCL_OH;
IIC_SDA_OH;
Delay50us();
}
//init NA bit
void init_NA(void)
{
Delay50us();
IIC_SDA_OH;
IIC_SCL_OH;
Delay50us();
IIC_SCL_OL;
Delay50us();
IIC_SDA_OL;
Delay50us();
}
//wait ack ????????????????????????????????????????????????
uint8_t IIC_Wait_Ack(void)
{
/* uint8_t res;
SDA_IN();
Delay50us();
IIC_SCL_OH;
Delay50us();
if(READ_SDA) res = 1;//SDA=1发送失败,返回1
else res = 0;
IIC_SCL_OL;
SDA_OUT();
Delay50us();
return res;*/
uint8_t ucErrTime=0;
SDA_IN();Delay50us();
//IIC_SDA_OH;Delay50us();
IIC_SCL_OH;Delay50us();
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_OL;
SDA_OUT();
return 0;
}
//0:write successly,1:write failed
//dat:the value we want to write
uint8_t IIC_Write_Byte(uint8_t dat)
{
uint8_t t;
uint8_t temp;
SDA_OUT();
IIC_SCL_OL;
for(t=0;t<8;t++)
{
temp = (dat&0x80)>>7;
if(temp){
IIC_SDA_OH;
}
else{
IIC_SDA_OL;
}
dat<<=1;
Delay50us();
IIC_SCL_OH;
Delay50us();
IIC_SCL_OL;
Delay50us();
}
return IIC_Wait_Ack();
}
//return 0:write successly,1:write failed
//reg: register address,data:Value we want to write to reg
uint8_t IIC_Write_Reg(uint8_t reg, uint8_t data)
{
uint8_t res = 0;
IIC_Start();
if(IIC_Write_Byte(SlaveAddress_wr)) res = 1;
Delay50us();
if(IIC_Write_Byte(reg)) res = 1;
Delay50us();
if(IIC_Write_Byte(data)) res = 1;
Delay50us();
__no_operation();
IIC_Stop();
return res;
}
//the register's value will be renturn
uint8_t IIC_Read_Byte()
{
uint8_t i,receive=0;
SDA_IN();
IIC_SCL_OL;
for(i=0;i<8;i++ )
{
Delay50us();
IIC_SCL_OH;
receive<<=1;
if(READ_SDA)receive++;
Delay50us();
IIC_SCL_OL;
}
SDA_OUT();
return receive;
}
//register value will be return
//reg:register address
uint8_t IIC_Read_Reg(uint8_t reg)
{
uint8_t res=0;
IIC_Start();
if(IIC_Write_Byte(SlaveAddress_wr)) return 1;
Delay50us();//_NOP;
if(IIC_Write_Byte(reg)) return 1;
IIC_Stop();
Delay50us();
IIC_Start();
if(IIC_Write_Byte(SlaveAddress_rd))
return 1;
Delay50us();
res=IIC_Read_Byte();
init_NA();
IIC_Stop();
return res;
}
IIC.h
#ifndef SYS_IIC_IIC_H_
#define SYS_IIC_IIC_H_
#include "inc/hw_memmap.h"
#define SlaveAddress_rd 0x43
#define SlaveAddress_wr 0x42
#define IIC_SCL_OL GPIO_setOutputLowOnPin(GPIO_PORT_P1,GPIO_PIN7) //RST IO口输出低电平 P1OUT &= ~BIT7
#define IIC_SCL_OH GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN7) //RST IO口输出高电平 P1OUT |= BIT7
#define IIC_SDA_OL GPIO_setOutputLowOnPin(GPIO_PORT_P1,GPIO_PIN6) //DC IO口输出低电平 P1OUT &= ~BIT6
#define IIC_SDA_OH GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN6) //DC IO口输出高电平 P1OUT |= BIT6
#define SDA_OUT() GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN6) //SDA
#define SDA_IN() GPIO_setAsInputPin(GPIO_PORT_P1,GPIO_PIN6) //SDA
#define READ_SDA GPIO_getInputPinValue(GPIO_PORT_P1,GPIO_PIN6)
//#define READ_SDA (P1IN&BIT6)>>6 //0100 0000
void Delay50us(void );
void Delay5ms(void);
void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
uint8_t IIC_Wait_Ack(void);//wait for dont care bit
void init_NA(void);
uint8_t IIC_Write_Byte(uint8_t dat);
uint8_t IIC_Write_Reg(uint8_t reg, uint8_t data);
uint8_t IIC_Read_Byte();
uint8_t IIC_Read_Reg(uint8_t reg);
#endif