打印

I2C接口应用(转)

[复制链接]
476|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Orchids|  楼主 | 2017-9-27 15:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
I2C接口应用


#include "vardefine.h"
int IIC_DELAY=100;
int IIC_UpDown=50;
unsigned char mode_memread = 0xA1;
unsigned char mode_memwrite = 0xA0;
unsigned char mode_regread = 0xD1;
unsigned char mode_regwrite = 0xD0;
unsigned char
rece_buffer[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char RTC_Control = 0x00;
unsigned char CAL_Control = 0x01;
unsigned char RTC_Seconds = 0x02;
unsigned char RTC_minutes = 0x03;
unsigned char RTC_hours = 0x04;
unsigned char RTC_week = 0x05;
unsigned char RTC_day = 0x06;
unsigned char RTC_months = 0x07;
unsigned char RTC_years = 0x08;
unsigned char Dog_Flag = 0x09;
unsigned char Dog_Control = 0x0A;
unsigned char Comp_Control = 0x0B;
unsigned char Event_Control = 0x0C;
unsigned char Counter1_LSB = 0x0D;
unsigned char Counter1_MSB = 0x0E;
unsigned char Counter2_LSB = 0x0F;
unsigned char Counter2_MSB = 0x10;
unsigned char Serial_Num0 = 0x11;
unsigned char Serial_Num1 = 0x12;
unsigned char Serial_Num2 = 0x13;
unsigned char Serial_Num3 = 0x14;
unsigned char Serial_Num4 = 0x15;
unsigned char Serial_Num5 = 0x16;
unsigned char Serial_Num6 = 0x17;
unsigned char Serial_Num7 = 0x18;
int w=0;
unsigned char rece_data=0;
struct time {
unsigned char second;
unsigned char minutes;
unsigned char hours;
unsigned char week;
unsigned char days;
unsigned char months;
unsigned char year;
}time;
// 函数原形声明
void FM_Start(void);
void FM_Stop(void);
void FM_Send_Ack(void);
void FM_Send_AckRD(void);
void FM_Send_noAck(void);
void FM_transf( unsigned char tran_byte );
void FM_membyte_WR(int address,unsigned char * data_byte,int length);
void FM_membyte_RD(int address,int length);
void write_reg(unsigned char add,unsigned char wbyte);
unsigned char read_reg(unsigned char add);
void read_time(void);
void write_time(void);
unsigned char FM_rece( void );
unsigned char FM_rece_data(void);
void delay(int delay_num);
void Gpio_select(void);
void InitSystem(void);
unsigned char bcd_to_hex(unsigned char condata)
{
unsigned char temp,temp0,temp10;
temp10 = (condata&0xF0)>>4;
temp0 = condata&0x0F;
temp = temp10*10+temp0;
return(temp);
}
unsigned char hex_to_bcd(unsigned char condata)
{
unsigned char temp,temp0,temp10;
temp10 = condata/10;
temp0 = condata%10;
temp = (temp10<<4)|temp0;
return(temp);
}
void main(void)
{
int i=0;
unsigned char data_buffer[0x10] = {0};
unsigned char
buffer_t[16]={0x07,0x08,0x01,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08};
InitSystem(); // 初始化DSP内核寄存器
delay(20000);
Gpio_select(); // 设置GPIO复用寄存器
InitPieCtrl();
InitPieVectTable();
IER = 0;
// 使能全局中断
EINT;
ERTM;
// SRAM memory test
delay(2000);
while(!FM_RST);
delay(2000);
write_reg(0x01,0x00); //启动时钟
delay(200);
for(i=0;i<4;i++)
{
FM_membyte_WR(i*16,buffer_t,16);
}
for(i=0;i<2048;i++)
{
FM_membyte_RD(i*16,16);
}
// FM31256 Flash测试
FM_membyte_WR(0x0,buffer_t,10); // 存储器写程序,无长度限制
FM_membyte_RD(0x0,16); // 存储器读程序,要求长度小于255(采用单字写实现)
//FM31256 时钟初始化
time.second = 00;
time.minutes= 10;
time.hours = 11;
time.week = 1;
time.days = 13;
time.months = 8;
time.year = 7;
write_time();
while(1)
{
read_time();
delay(20);
FM_membyte_RD(0x0,16); // 存储器读程序,要求长度小于255(采用单字写实现)
FM_membyte_WR(0x0,buffer_t,10); // 存储器写程序,无长度限制
EALLOW;
SysCtrlRegs.WDKEY = 0xAA; // and serve watchdog #2
EDIS;
}
}
void Gpio_select(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.all = 0x0;
GpioMuxRegs.GPBMUX.all = 0x0;
GpioMuxRegs.GPDMUX.all = 0x0;
GpioMuxRegs.GPFMUX.all = 0x0;
GpioMuxRegs.GPEMUX.all = 0x0;
GpioMuxRegs.GPGMUX.all = 0x0;
GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPBDIR.all = 0x0; //
GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入
GpioMuxRegs.GPFDIR.bit.GPIOF8 = 1; // FM SCLK MCLKXA_GPIOF8
GpioMuxRegs.GPFDIR.bit.GPIOF9 = 1; // FM A0 MCLKRA_GPIOF9
GpioMuxRegs.GPFDIR.bit.GPIOF10 = 1; // FM A1 MFSXA_GPIOF10
GpioMuxRegs.GPFDIR.bit.GPIOF11 = 0; // FM CAL MFSRA_GPIOF11
GpioMuxRegs.GPFDIR.bit.GPIOF12 = 1; // FM SDA MDXA_GPIOF12
GpioMuxRegs.GPFDIR.bit.GPIOF13 = 0; // FM RST MDRA_GPIOF13
GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT as input
FM_A0 =0;
FM_A1 =0;
FM_SDA =0;
FM_SCLK=0;
FM_RST =0;
DAC_CS =1;
GpioMuxRegs.GPAQUAL.all = 0x1;
GpioMuxRegs.GPBQUAL.all = 0x1;
GpioMuxRegs.GPDQUAL.all = 0x1;
GpioMuxRegs.GPEQUAL.all = 0x1;
EDIS;
}
void InitSystem(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00E8; // 配置看门狗
// 0x00E8 禁止看门狗, Prescaler = 1
// 0x00AF 使能看门构, Prescaler = 64
SysCtrlRegs.SCSR = 0; // 看门狗产生复位
SysCtrlRegs.PLLCR.bit.DIV = 10; // 设置PLL倍频参数
SysCtrlRegs.HISPCP.all = 0x1; // 设置高速时钟预定标分频系数2
SysCtrlRegs.LOSPCP.all = 0x2; //设置低速时钟预定标分频系数4
// 外设时钟控制
SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=0;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;
EDIS;
}
//===============================================================
// 铁电存储器 应用程序
//===============================================================
void FM_Start(void) /*FM启动程序*/
{/*FM启动程序*/
FM_SDA = 1;
delay(IIC_DELAY);
FM_SCLK = 1;
delay(IIC_DELAY);
FM_SDA = 0;
delay(IIC_DELAY);
FM_SCLK = 0;
}
void FM_Stop(void)
{/*FM停止程序*/
FM_SDA = 0;
delay(IIC_DELAY);
FM_SCLK = 1;
delay(IIC_DELAY);
FM_SDA = 1;
delay(IIC_DELAY);
FM_SCLK = 0;
}
void FM_Send_Ack(void)
{ /*FM应答程序*/
EALLOW;
GpioMuxRegs.GPFDIR.bit.GPIOF12 = 0; //SDA设置为输入
EDIS;
FM_SCLK = 0;// SCL=0
delay(IIC_DELAY);
FM_SDA = 0;// SDA=0
while(FM_SDA);
delay(IIC_DELAY);
FM_SCLK = 1;// SCL=1
delay(IIC_DELAY);
FM_SCLK = 0;// SCL=0
delay(IIC_DELAY);
EALLOW;
GpioMuxRegs.GPFDIR.bit.GPIOF12 = 1; //SDA设置为输入
EDIS;
}
void FM_Send_AckRD(void)
{ /*FM应答程序*/
FM_SCLK = 0;// SCL=0
delay(IIC_DELAY);
FM_SDA = 0;// SDA=0
delay(IIC_DELAY);
FM_SCLK = 1;// SCL=1
delay(IIC_DELAY);
FM_SCLK = 0;// SCL=0
delay(IIC_DELAY);
}
void FM_Send_noAck(void)
{/*FM不应答程序*/
FM_SDA = 1;// SDA=1
delay(IIC_DELAY);
FM_SCLK = 1;// SCL=1
delay(IIC_DELAY);
FM_SCLK = 0;// SCL=0
}
/* 说明:SCL线是高电平时,SDA线从高电平向低电平切换,表示起始条件;当SCL是高电平时,SDA线由低电平向高电平切换,表示停止条件。相关的确认时钟脉冲由主机产生,在确认的时钟脉冲器件发送方释放SDA(高电平),在此期间接收方须将SDA 拉低。*/
void FM_transf(unsigned char tran_byte )
{/* CPU字节发送程序*/
unsigned char i,current_bit=0x80;
FM_SCLK = 0; // SCL=0
delay(IIC_DELAY);
for(i=0;i<=7;i++)
{
if(tran_byte & current_bit){FM_SDA = 1;}
else{FM_SDA =0;}
current_bit=current_bit >>1;
delay(IIC_DELAY);
FM_SCLK =1; //SCL=1
delay(IIC_DELAY);
FM_SCLK =0; //SCL=0
delay(IIC_DELAY);
}
}
void FM_membyte_WR( int address,unsigned char * data_byte,int length)
{
int i;
unsigned char address_MSB,address_LSB;
address_MSB = address>>8;
address_LSB = address&0xff;
FM_Start();
FM_transf(mode_memwrite);
FM_Send_Ack();
FM_transf(address_MSB);
FM_Send_Ack();
FM_transf(address_LSB);
FM_Send_Ack();
for(i=0;i<length;i++)
{
FM_transf( * data_byte);
data_byte++;
FM_Send_Ack();
}
FM_Stop();
}
// 存储器读程序,要求长度小于255(采用单字读实现)
void FM_membyte_RD(int address,int length) // read length<255
{
int i;
unsigned char address_MSB,address_LSB;
address_MSB = address>>8;
address_LSB = address&0xff;
for(i=0;i<length;i++)
{
FM_Start();
FM_transf(mode_memwrite);
FM_Send_Ack();
FM_transf(address_MSB);
FM_Send_Ack();
FM_transf(address_LSB+i);
FM_Send_Ack();
FM_Start();
FM_transf(mode_memread);
FM_Send_Ack();
FM_rece();
rece_buffer=rece_data&0xff;
FM_Send_noAck();
FM_Stop();
}
}
//======================================================
void write_reg(unsigned char add,unsigned char wbyte)
{
FM_Start();
FM_transf(mode_regwrite);
FM_Send_Ack();
FM_transf(add);
FM_Send_Ack();
FM_transf(wbyte);
FM_Send_Ack();
FM_Stop();
}
//=================================================
unsigned char read_reg (unsigned char add)
{
unsigned char temp;
FM_Start();
FM_transf(mode_regwrite);
FM_Send_Ack();
FM_transf(add);
FM_Send_Ack();
FM_Start();
FM_transf(mode_regread);
FM_Send_Ack();
FM_rece();
FM_Send_AckRD();
FM_Stop();
temp=rece_data;
return(temp);
}
void read_time(void)
{
unsigned char flagstempa,flagstempb;
int i;
flagstempa=read_reg(RTC_Control);
flagstempb=(flagstempa|0x01)&0xFD;
write_reg(RTC_Control,flagstempb);
for(i=0;i<0x10;i++)
{
rece_buffer= read_reg(i);
}
write_reg(RTC_Control, flagstempb&0xFE);
for(i=0;i<0x10;i++)
{
rece_buffer= read_reg(i);
}
// write_reg(0x00,0x00);
time.second = bcd_to_hex(rece_buffer[2]);
time.minutes= bcd_to_hex(rece_buffer[3]);
time.hours = bcd_to_hex(rece_buffer[4]);
time.week = bcd_to_hex(rece_buffer[5]);
time.days = bcd_to_hex(rece_buffer[6]);
time.months = bcd_to_hex(rece_buffer[7]);
time.year = bcd_to_hex(rece_buffer[8]);
}
void write_time(void)
{
unsigned char temp[7];
unsigned char i,flagstempa,flagstempb;
flagstempa=read_reg(RTC_Control);
flagstempb=(flagstempa|0x02)&0xFE;
write_reg(RTC_Control, flagstempb);
temp[6]=hex_to_bcd(time.year);
temp[5]=hex_to_bcd(time.months);
temp[4]=hex_to_bcd(time.days);
temp[3]=hex_to_bcd(time.week);
temp[2]=hex_to_bcd(time.hours);
temp[1]=hex_to_bcd(time.minutes);
temp[0]=hex_to_bcd(time.second); //0x02
for(i=2;i<0x9;i++)
{
write_reg(i,temp[i-2]);
}
delay(1000);
}
unsigned char FM_rece(void)
{ /* CPU 接收字节程序*/
unsigned char mvalue,i=0;
EALLOW;
GpioMuxRegs.GPFDIR.bit.GPIOF12 = 0; //SDA设置为输入
EDIS;
delay(IIC_DELAY);
FM_SCLK =0; //SCL=0
delay(IIC_DELAY);
for(i=0;i<=7;i++)
{
rece_data = rece_data<<1;
FM_SCLK =1; //SCL=1
delay(IIC_DELAY);
mvalue = FM_SDA;
if(mvalue) //接收位为 1
rece_data = rece_data|0x01;
else
rece_data = rece_data&0xFE;
FM_SCLK =0; //SCL=0
delay(IIC_DELAY);
}
rece_data =rece_data & 0xff;
EALLOW;
GpioMuxRegs.GPFDIR.bit.GPIOF12 = 1; //SDA设置为输出
EDIS;
return(rece_data);// 返回接收字节
}
void delay(int delay_num)
{
int i=0;
for(i=0;i<delay_num;i++);
}
//===============================================================
// 代码结束
//===============================================================

相关帖子

沙发
baimiaocun2015| | 2017-9-27 21:05 | 只看该作者
这个程序的有一个功能的我看懂了,就是实现日期时间的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

697

主题

993

帖子

4

粉丝