📄 hnr_s4.c
字号:
//I2C存储器AT24C64读写实验
//需要将多功能模块电路板接到P1口上
//将数码管电路板接到J11插座上,注意引脚位置
#include "msp430x14x.h"
#define uint unsigned int
#define uchar unsigned char
//共阳数码管的表格为:
//本表格通过LEDSET软件可以快速得到
const uchar Seg[]=
{
0X84, // 0
0XBD, // 1
0XE0, // 2
0XB0, // 3
0X99, // 4
0X92, // 5
0X82, // 6
0XBC, // 7
0X80, // 8
0X90, // 9
0X88, // A
0X83, // b
0XC6, // C
0XA1, // d
0XC2, // E
0XCA // F
};
//SDA
#define SDA_OUT P1DIR|=BIT7
#define SDA_IN P1DIR&=~BIT7
#define SDA_HIGH P1OUT|=BIT7
#define SDA_LOW P1OUT&=~BIT7
#define SDA_DATA P1IN&BIT7
//SCL
#define SCL_OUT P1DIR|=BIT6
#define SCL_HIGH P1OUT|=BIT6
#define SCL_LOW P1OUT&=~BIT6
//SWP
#define SWP_OUT P1DIR|=BIT5
#define SWP_HIGH P1OUT|=BIT5
#define SWP_LOW P1OUT&=~BIT5
//10us级延时子程序
void Delayus(uint us)
{
while(us--)
{
for(uint i=0;i<5;i++);
}
}
//I2C起始条件
void I2cStart()
{
SDA_OUT;
SDA_HIGH;
Delayus(1);
SCL_OUT;
SCL_HIGH;
Delayus(1);
SDA_LOW;
Delayus(1);
SCL_LOW;//钳住I2C总线,准备发送或接收数据
}
//I2C停止条件
void I2cStop()
{
SCL_OUT;
SCL_LOW;
Delayus(1);
SDA_OUT;
SDA_LOW;
Delayus(1);
SCL_HIGH;
Delayus(1);
SDA_HIGH;
Delayus(1);
}
//发ACK应答
void I2cAck()
{
SDA_OUT;
SDA_LOW;
Delayus(1);
SCL_OUT;
SCL_HIGH;
Delayus(1);
SCL_LOW;
Delayus(1);
}
//发NAK应答
void I2cNAk()
{
SDA_OUT;
SDA_HIGH;
Delayus(1);
SCL_OUT;
SCL_HIGH;
Delayus(1);
SCL_LOW;
Delayus(1);
}
//等待应答
int WaitAck()
{
uchar Time=255;
SDA_OUT;
SDA_HIGH;
Delayus(1);
SDA_IN;
SCL_OUT;
SCL_HIGH;
Delayus(1);
while(SDA_DATA)
{
Time--;
if(Time==0)
{
I2cStop();
return (0);
}
}
SCL_LOW;
Delayus(1);
return (1);
}
//I2C写一字节数据
void I2cWriteByte(uchar Data){
uchar i;
SDA_OUT;
SCL_OUT;
for(i=0;i<8;i++)
{
SCL_LOW;
Delayus(1);
if(Data&0x80) SDA_HIGH;
else SDA_LOW;
Data<<=1;
SCL_HIGH;
Delayus(1);
Delayus(1);
}
SCL_LOW;
}
//I2C读一字节数据
uchar I2cReadByte()
{
uchar i,TmpData=0;
SDA_IN;
SCL_OUT;
// SDA_HIGH;
for(i=0;i<8;i++)
{
SCL_LOW;
Delayus(1);
SCL_HIGH;
Delayus(1);
SDA_IN;
TmpData<<=1;
if(SDA_DATA) TmpData|=1;
}
SCL_LOW;
return(TmpData);
}
//I2C写数据到AT24C64
void I2cWrite(uchar Address,uchar Data)
{
I2cStart();//启动总线
I2cWriteByte(0xAE);//发送器件地址
WaitAck();
I2cWriteByte(Address);//发送器件子地址
WaitAck();
I2cWriteByte(Data);//发送数据
WaitAck();
I2cStop();
}
//I2C从AT24C64读数据
uchar I2cRead(uchar Address)
{
uchar TmpData;
I2cStart();//启动总线
I2cWriteByte(0xAE);//发送器件地址
WaitAck();
I2cWriteByte(Address);//发送器件子地址
WaitAck();
I2cStart();//启动总线
I2cWriteByte(0xAF);//发送器件地址
I2cAck();
TmpData=I2cReadByte();//读取数据
I2cNAk();
I2cStop();
return(TmpData);
}
void main()
{
uchar cpos;
uint i,j;
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
//初始化端口
P4DIR = 0XFF; //P4作为段输出
P5DIR = 0X0F; //P5作为位输出
P4OUT = 0XFF; //熄灭所有数码管
P5OUT = 0X00; //熄灭所有数码管
SWP_OUT;
SWP_LOW; //禁用写保护
BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启 LFXT1工作在低频模式 ACLK不分频 最高的标称频率
DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率
do
{
IFG1&=~OFIFG;//清除振荡器失效标志
for(uint i=255;i>0;i--);
}while(IFG1&OFIFG);//判断XT2是否起振
BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK不分频
_DINT();//关闭中断
I2cWrite(0x00,Seg[0x08]);//在地址0x00写入数据8
while(1)
{
for(cpos=0;cpos<16;cpos++)
{
P5OUT |= BIT0; //点亮数码管1
P4OUT=I2cRead(0x00);//读出地址0x00~0x0a的数据并显示
for(i=0;i<1000;i++) //粗略延时
{
for(j=0;j<1000;j++);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -