//--------------------------------------------------------------------------------
#include <c8051f340.h>
#include <stdio.h>
typedef unsigned int uint ;
typedef unsigned char uchar;
#define SYSCLK 12000000 // 12M内部时钟
#define BAUDRATE 9600 // Baud rate of UART in bps
sbit SDA = P1^0;
sbit SCL = P1^1;
uchar buffer[16]; //数据存储器
bit Ack(void); /*应答位*/
bit NAck(void); //无应答位
void delay(); //长延时
void UART0_Init (void); //UART Init
void Start(void); /*起始条件*/
void Stop(void); /*停止条件*/
void Send(uchar Data); /*发送数据子程序,Data为要求发送的数据*/
uchar Read(void); /*读一个字节的数据,并返回该字节值*/
void OSCILLATOR_Init (void); //内部振荡器初始化
void PORT_Init (void); //I/O初始化
void wait(int n); //精确延时
int I2cReadWriteZL(int mode,unsigned char ChipAddress,unsigned char *Data,int NbData);
void outputchar(uint order);
void selectout(uint dat);
void main (void)
{
uchar i;
uchar deviceAddr=0x1C;
uchar dat[2]={0x14,0xC0};
uchar ucBuffer[3]={0xFF};
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator
UART0_Init(); //Initialize UART0
delay();
delay();
}
void PORT_Init (void)
{
P1MDOUT &= 0x00; // Enable UTX as push-pull output
P0MDOUT |= 0x10;
XBR1 = 0x40; // Enable crossbar and enable
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
// weak pull-ups
}
void OSCILLATOR_Init (void)
{
OSCICN |= 0x03; // Configure internal oscillator for
// its maximum frequency
RSTSRC = 0x04; // Enable missing clock detector
}
void Start(void) /*起始条件*/
{
SDA=1;
SCL=1;
wait(50);
SDA=0;
wait(50);
}
void Stop(void) /*起始条件*/
{
SDA=0;
SCL=1;
wait(50);
SDA=1;
wait(50);
}
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
/*------长延时-----*/
void delay(void)
{
int i,j;
for(i=255;i>0;i--)
for(j=255;j>0;j--)
;
}
void wait(int n) //延长n个系统时钟
{
for(;n>0;n--)
;
}
void SEND_0(void) /*发送0比特*/
{
SCL=0; //获取总线控制权
SDA=0; //发送数据
SCL=1;
wait(50); //延时 确保从机读取数据 具体时间视系统时钟而定
SCL=0;
wait(20); //延时
}
void SEND_1(void) /*发送比特1*/
{
SCL=0;
SDA=1;
SCL=1;
wait(50);
SCL=0;
wait(20);
}
void Send(uchar Data) /*发送数据子程序,Data为要求发送的数据*/
{
char i;
for(i=0;i<8;i++)
{
if((Data<<i)&0x80)
SEND_1();
else
SEND_0();
}
}
uchar Read(void) /*读一个字节的数据,并返回该字节值*/
{
bit F0;
char b=0,i;
for(i=0;i<8;i++)
{
SDA=1; /*释放总线*/
SCL=1; /*接受数据*/
wait(10); //等待数据建立
F0=SDA; //读取数据
if(F0==1) //判断存储
{
b=b<<1;
b=b|0x01;
}
else
b=b<<1;
wait(20);
SCL=0;
wait(10);
}
return b;
}
bit Ack(void) /*应答位*/
{
uchar w=40; //等待时间值
bit F0=1; //标志位
SDA=1;
SCL=1;
wait(10);
while(--w&&F0) //读取应答位
F0=SDA;
wait(20);
SCL=0;
return F0;
}
/*无应答数据位发送子程序*/
bit NAck(void)
{
bit s=0;
SCL=0;
wait(5);
SCL=1;
SDA=1;
wait(20);
s=SDA;
wait(40);
SCL=0;
return !s;
}
/*------底层I2C读写子程序-----
函数为单主机主控发送接受子程序,该程序使用时总线上不可有其他主机。。。。
函数参数设置为 wr_mode--读写模式 char_slv_addr--从机地址 *dat--数据首地址 len----数据长度
数据地址的第一个字节一般为寄存器的地址
写数据时--在上层函数中需要把被写寄存器地址写入*dat的第一个字节 写入数据从第二个字节开始 写入字节数不多于16个
读数据时--需要读取的寄存器地址存放在第一个字节中,读取的数据存放在第一个字节中,读取的数据会覆盖原寄存器的地址
读模式专用于10313和10039器件,其格式为
--发送开始标志
--发送从机地址(写形式)
--应答位
--发送寄存器地址
--应答位
--发送开始标志
--发送从机地址(读模式)
------------------
--应答位
--读取寄存器数据
----------------
--无应答位
--结束标志。
----------------------------------------------------------------------------------------------------------------*/
int I2cReadWriteZL(int wr_mode, char slv_addr, char *dat, int len)
{
uchar i;
if (wr_mode == 1) //判断读写功能
{
Start(); //开始标志
Send(slv_addr); //发送从机地址
for(i=0;i<len;i++)
{
if(Ack()) //读取应答位
return 1;
Send(*dat); //发送数据
++dat;
}
NAck();
Stop(); //结束标志
if(i==len) //成功
return 0;
}
else //数据读取
{
Start(); //开始标志位
Send(slv_addr); //从机地址
Ack();
Send(*dat); //数据发送--寄存器地址
Ack();
Start(); //开始标志
Send(slv_addr+1); //从机地址
for(i=0;i<len;i++)
{
if (Ack()) //应答位
return 1;
*dat=Read(); //数据读取
++dat;
}
NAck();
Stop(); //结束标志
if(i==len) //成功
return 0;
}
return 1; //失败
}
/*------输出字符形式数据---
数据以ASCII的形式输出
------------------------------*/
void outputchar(uint order)
{
selectout(order/16);
selectout(order%16);
}
/*获得的数据判断--以确定输出字符
---------------------------------*/
void selectout(uint dat)
{
switch(dat)
{
case 0:printf("%c",'0');
break;
case 1:printf("%c",'1');
break;
case 2:printf("%c",'2');
break;
case 3:printf("%c",'3');
break;
case 4:printf("%c",'4');
break;
case 5:printf("%c",'5');
break;
case 6:printf("%c",'6');
break;
case 7:printf("%c",'7');
break;
case 8:printf("%c",'8');
break;
case 9:printf("%c",'9');
break;
case 10:printf("%c",'A');
break;
case 11:printf("%c",'B');
break;
case 12:printf("%c",'C');
break;
case 13:printf("%c",'D');
break;
case 14:printf("%c",'E');
break;
case 15:printf("%c",'F');
break;
i2c.rar_C8051F340单片机_c8051f340_gpio i2c单片机_i2c_模拟I2C
版权申诉
5星 · 超过95%的资源 136 浏览量
2022-09-21
04:45:26
上传
评论
收藏 3KB RAR 举报
小贝德罗
- 粉丝: 70
- 资源: 1万+