求飞思卡尔MMA7455的verilog的读写模块代码

2024-12-28 12:57:57
推荐回答(2个)
回答1:

/********************************************************
【dev.env.】KEIL UV4.2
【Target 】AT89C52
【Crystal 】11.0592Mhz
LQ-7455加速度模块测试程序
********************************************************/
#include
#include "intrins.h"

//nop指令个数定义
#define nops() {_nop_();_nop_();_nop_();_nop_();_nop_();}
//端口位定义,可修改
sbit SDA=P1^1; //IIC数据线定义
sbit SCL=P1^0; //IIC时钟线定义
//内部数据定义
unsigned char IIC_ad_main; //器件从地址
unsigned char IIC_ad_sub; //器件子地址
unsigned char *IIC_buf; //发送|接收数据缓冲区
unsigned char IIC_num; //发送|接收数据个数
#define ack 1 //主应答
#define no_ack 0 //从应答

void send232byte(unsigned char bytebuf)
{
SBUF=bytebuf;
while(!TI);
TI=0;
}

void IIC_start(void){
SCL=0;
SDA=1;
_nop_();
SCL=1;
nops();
SDA=0;
nops();
SCL=0;
}
//************************************************
//送停止位 SDA=0->1
void IIC_stop(void){
SCL=0;
_nop_();
SDA=0;
_nop_();
SCL=1;
nops();
SDA=1;
nops();
SCL=0;
}
//************************************************
//主应答(包含ack:SDA=0和no_ack:SDA=0)
void IIC_ack_main(bit ack_main){
SCL=0;
if(ack_main)SDA=0; //ack主应答
else SDA=1; //no_ack无需应答
nops();
SCL=1;
nops();
SCL=0;
}
//*************************************************
//字节发送程序
//发送c(可以是数据也可是地址),送完后接收从应答
//不考虑从应答位
void send_byte(unsigned char c){
unsigned char i;
for(i=0;i<8;i++){
SCL=0;
if((c< else SDA=0;
_nop_();
SCL=1;
nops();
SCL=0;
}
nops();
SDA=1; //发送完8bit,释放总线准备接收应答位
_nop_();
SCL=1;
nops(); //sda上数据即是从应答位
SCL=0; //不考虑从应答位|但要控制好时序
}
//**************************************************
//字节接收程序
//接收器件传来的数据,此程序应配合|主应答函数|IIC_ack_main()使用
//return: uchar型1字节
unsigned char read_byte(void){
unsigned char i;
unsigned char c;
c=0;
SCL=0;
_nop_();
SDA=1; //置数据线为输入方式
for(i=0;i<8;i++){
_nop_();
SCL=0; //置时钟线为低,准备接收数据位
nops();
SCL=1; //置时钟线为高,使数据线上数据有效
_nop_();
c<<=1;
if(SDA)c+=1; //读数据位,将接收的数据存c
}
SCL=0;
return c;
}
//***************************************************
//向无子地址器件发送单字节数据
void send_to_byte(unsigned char ad_main,unsigned char c){
IIC_start();
send_byte(ad_main); //发送器件地址
send_byte(c); //发送数据c
IIC_stop();
}
//***************************************************
//向有子地址器件发送多字节数据
void send_to_nbyte(unsigned char ad_main,unsigned char ad_sub,unsigned char *buf,unsigned char num){
unsigned char i;
IIC_start();
send_byte(ad_main); //发送器件地址
send_byte(ad_sub); //发送器件子地址
for(i=0;i send_byte(*buf); //发送数据*buf
buf++;
}
IIC_stop();
}
//***************************************************
//从无子地址器件读单字节数据
//function:器件地址,所读数据存在接收缓冲区当前字节
void read_from_byte(unsigned char ad_main,unsigned char *buf){
IIC_start();
send_byte(ad_main); //发送器件地址
*buf=read_byte();
IIC_ack_main(no_ack); //无需应答
IIC_stop();
}
//***************************************************
//从有子地址器件读多个字节数据
//function:
void read_from_nbyte(unsigned char ad_main,unsigned char ad_sub,unsigned char *buf,unsigned char num){
unsigned char i;
IIC_start();
send_byte(ad_main);
send_byte(ad_sub);
for(i=0;i *buf=read_byte();
IIC_ack_main(ack); //主应答
buf++;
}
*buf=read_byte;
buf++; //本次指针调整无意义,目的是操作后buf指向下一地址
IIC_ack_main(no_ack); //无需应答
IIC_stop();
}

unsigned char MMA7455_readbyte(unsigned char address)
{
unsigned char ret = 100;
IIC_start(); //启动
send_byte(0x3A); //写入设备ID及写信号
send_byte(address); //X地址
IIC_start(); //重新发送开始
send_byte(0x3B); //写入设备ID及读信
ret = read_byte(); //读取一字节
IIC_stop();

return ret;
}

//写入
void MMA7455_writebyte(unsigned char address, unsigned char thedata)
{
IIC_start(); //启动
send_byte(0x3A); //写入设备ID及写信号
send_byte(address); //X地址
send_byte(thedata); //写入设备ID及读信
IIC_stop();
}

//初始化
//初始化为指定模式
void MMA7455_init()
{
MMA7455_writebyte(0x16, 0x05);
}

void main()
{ unsigned char x, y, z;

TMOD=0x21; //定时T1方式2,C/T=0,M1=1,定时T0方式1, M0=1
SCON=0x60; //8 bit SM1=SM2=1,SM0=0, REN=0
TL1=0xfd; //9600
TH1=0xfd;
TR1=1;
ET0=1;
EA=1;

MMA7455_init(); //初始化MMA7455

while(1)
{ //读取重力信息
x = MMA7455_readbyte(0x06);
y = MMA7455_readbyte(0x07);
z = MMA7455_readbyte(0x08);

send232byte(0x55);
send232byte(0xAA);
send232byte(x);
send232byte(y);
send232byte(z);

}
}

回答2:

。。。。去网上搜吧 太多了 我写不下~