|
//系统时钟8M
#include <iom128v.h>
#include <string.h>
#include <stdio.h>
#include"1602.h"
#include "twi_master.h"
#include"mpu_6050.h"
#define uchar unsigned char
#define uint unsigned int
uchar dis[4]; //存储要显示的(并且已经转化为字符串的)数据的ASCII码
uchar receive_data;
uchar send_data;
uchar bMastRead; //读写控制标志位
uchar cSendSlaveAddress; //从机地址+写信号
uchar reg_read_adress; //要读寄存器的地址
uchar reg_address; //要写入寄存器的地址
uchar bSign1ms;
char i,j;
/********************************************/
//定时器0溢出中断服务例程
// Timer 0 overflow interrupt service routine
/********************************************/
//interrupt [TIM0_COMP] void timer0_comp_isr(void)
#pragma interrupt_handler time0_interrupt:iv_TIM0_OVF
void time0_interrupt(void)
{
TCNT0=216; //计数器赋初值定时为5MS
bSign1ms = 1;
}
/********************************************/
//*******定时器0初始化
/********************************************/
void time0_init(void)
{
ASSR=0x00; //一般不用配置
TCCR0=0x07; //普通模式,正常端口输出,1024分频
TCNT0=216; //计数器赋初值定时为5MS
TIFR=0X01; //清除中断标志
TIMSK=0X01; //使能定时器溢出中断
SREG|=0x80; //使能全局中断
}
/********************************************/
//*****I2C总线初始化
/********************************************/
void twi_init(void)
{
TWSR=0x11; //0X00不分频 0x01 4,0x10 16,0x11 64分频
TWBR=0x40; // 大约为970HZ (对应于8M晶振)
TWAR=0x00; //不作为从机,可不管
// TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE);//TWCR=0x05;
}
/********************************************/
//*****发送一个字节数据
/********************************************/
void twi_send(uchar REG_Address,uchar REG_data) //向MPU6050的REG_Address寄存器写入REG_data
{
bMastRead=0;
reg_address=REG_Address;
send_data=REG_data;
StartTwiMaster();
}
/********************************************/
//*****接收一个字节数据
/********************************************/
unsigned char twi_receive(uchar REG_Address ) //从MPU6050的REG_Adress寄存器读取数据
{
bMastRead=1;
reg_read_adress=REG_Address;
StartTwiMaster();
return receive_data;
}
/********************************************/
//*****MPU_6050初始化
/********************************************/
void mpu6050_init(void)
{
// cSendSlaveAddress=SlaveAddress;
twi_send(PWR_MGMT_1, 0x80);
delay_nms(10);
twi_send(PWR_MGMT_1, 0x01);
twi_send(PWR_MGMT_1, 0x00); //解除休眠状态 关闭温度传感器
twi_send(SMPLRT_DIV, 0x07); //陀螺仪采样率,典型值:0x07(125Hz)
twi_send(CONFIG, 0x06); //低通滤波频率,典型值:0x06(5Hz)
twi_send(GYRO_CONFIG, 0x18); //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
twi_send(ACCEL_CONFIG, 0x01); //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
}
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address)
{
char H,L;
H=twi_receive(REG_Address); //一个数据有两个8位寄存器存储,且地址相邻
L=twi_receive(REG_Address+1);
return (H<<8)+L; //合成数据
}
//****************************************
//将数据转字符串存在指针*s指向的数组里
//****************************************
void lcd_printf(uchar *s,int temp_data) //将temp_data转化为对应 符号,百,十,个位数的ASCII码,
{ //并存入指针*s指向首地址的数组 ,,将来lcd调用显示
if(temp_data<0)
{
temp_data=-temp_data;
*s='-';
}
else *s=' ';
*++s =temp_data/100+0x30;
temp_data=temp_data%100; //取余运算
*++s =temp_data/10+0x30;
temp_data=temp_data%10; //取余运算
*++s =temp_data+0x30;
}
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(int value,uchar x,uchar y)
{
value%=100; //(相当于右移6位)转换为10位数据
lcd_printf(dis, value); //转换数据显示
LCD_dis_string(x,y,dis,4); //启始列,行,显示数组,显示长度
}
/***************** 2 Wire bus interrupt service routine *****************
模式标志位:(TWAR = 0x01,bMastRead = 1)->主机接收模式;
(TWAR = 0x00,bMastRead = 0)->主机发送模式;
主机发送模式:
写发送地址cSendSlaveAddress,包括广播地址和从机地址,bFinishSendData;
主机接收模式:
写接收地址cReceiveSlaveAddress,bFinishReceiveData;
*************************************************************************/
#pragma interrupt_handler twi_isr:34
void twi_isr(void)
{
unsigned char cStatusCode=0; //定义TWI状态,用于读取状态寄存器与预定的状态比较
cStatusCode = TWSR & 0xF8; //屏蔽分频因子?
/***********************接收模式*******************/
if(bMastRead==1)
{
switch(cStatusCode)
{
case MT_START_08: //start已经发送,接下来发送SLA+W
PORTA|=(1<<0);
TWDR =cSendSlaveAddress; //要写器件的地址+写信号
LoadSLA_W();
break;
case MT_RESTART_10: //重复START已发送
PORTA|=(1<<1);
TWDR = cSendSlaveAddress+1 ; //SLA+R
LoadSLA_R(); //发送SLA+R
break;
case MT_SLAW_ACK_18: //SLA+W 已发送;接收到 ACK
PORTA|=(1<<2);
TWDR=reg_read_adress; //写入要读寄存器的地址
//TWDR= 0x3B;
SendData();
break;
case MT_SLAW_NACK_20: //SLA+W 已发送接收到 NACK
SendStop(); //TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)发送停止信号并使能中断
break;
case MT_DATA_ACK_28: //数据(要读寄存器首地址)已经发送,接收到ACK
PORTA|=(1<<3);
reStartTwiMaster(); //发送RESTART信号
break;
case MR_SLAR_ACK_40: //SLA+R 已发送接收到ACK
PORTA|=(1<<4);
receive_data=TWDR; //读出cSendSlaveAddress地址中的数据
SendAck();
//SendStop(); //发送应答信号
break;
case MR_SLAR_NACK_48: //SLA+R 已发送接收到NACK
SendStop();
break;
case MR_DATA_ACK_50: //数据已经收到,应答
PORTA|=(1<<5);
SendStop();
break;
case MR_DATA_NACK_58:
PORTA|=(1<<6);
SendStop();
break;
}
}
/***********************发送模式*******************/
else
{
switch(cStatusCode)
{
case MT_START_08: //start已经发送,将来发送SLA+W
// PORTA|=(1<<0);
// TWDR =0XD0; //要写器件的地址+写信号
TWDR =cSendSlaveAddress; //要写器件的地址+写信号
LoadSLA_W();//主机发送,,,TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)发送地址,开中断
break;
case MT_RESTART_10: //重复START已发送,将来发送SLA+W或者SLA+R
// PORTA|=(1<<1);
TWDR =0XD0;//cSendSlaveAddress; //要写器件的地址+写信号
LoadSLA_W();//主机发送,,,TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)发送地址,开中断
break;
case MT_SLAW_ACK_18: //SLA+W 已发送;接收到 ACK
// PORTA|=(1<<2);
//TWDR=0X19;
TWDR=reg_address; //写入要写寄存器的地址
SendData(); //发送数据(地址),,,清零中断标志,TWI使能,TWI中断使能
break;
case MT_SLAW_NACK_20: //SLA+W 已发送接收到 NACK
SendStop(); //TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)发送停止信号并使能中断
break;
case MT_DATA_ACK_28: // (要读寄存器地址)已经发送,接收到ACK
if(i==0) //i==0时为发送数据,i!=1时发送STOP;
{
///PORTA|=(1<<3);
//TWDR =0x07;
TWDR = send_data; //将要写的数据写进寄存器
i+=1;
LoadSLA_W(); //写入数据
break;
}
else
{
i=0;
// PORTA|=(1<<4);
SendStop();
break;
}
case MT_DATA_NACK_30: //数据已经发送,接收到NACK
//SendStop();
break;
case MT_SLAW_DATA_LOST:
PORTA|=1<<7;
SendStop();
}
}
}
//*************************************************************************
// 主程序
//*************************************************************************/
void main(void)
{
uchar a;
cSendSlaveAddress=SlaveAddress;
DDRA=0XFF;
DDRE=0XFF;
PORTA=0X00;
twi_init(); //TWI相关初始化,波特率
delay_nms(10);
LCD_init();
//time0_init();
SREG|=0x80;
mpu6050_init();
bMastRead=1;
StartTwiMaster();
while(1)
{
Display10BitData(GetData(ACCEL_ZOUT_H),2,0); //显示X轴加速度
// delay_nms(100);
Display10BitData(GetData(ACCEL_XOUT_H),2,1); //显示X轴加速度
}
/*
while (1)
{
//Display10BitData(128,2,0); //显示X轴加速度
Display10BitData(GetData(ACCEL_XOUT_H),2,0); //显示X轴加速度
Display10BitData(GetData(ACCEL_YOUT_H),7,0); //显示Y轴加速度
Display10BitData(GetData(ACCEL_ZOUT_H),12,0); //显示Z轴加速度
Display10BitData(GetData(GYRO_XOUT_H),2,1); //显示X轴角速度
Display10BitData(GetData(GYRO_YOUT_H),7,1); //显示Y轴角速度
Display10BitData(GetData(GYRO_ZOUT_H),12,1); //显示Z轴角速度
} */
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|