金牌会员
- 积分
- 2762
- 威望
- 980
- 贡献
- 344
- 兑换币
- 29
- 注册时间
- 2011-8-27
- 在线时间
- 719 小时
|
那位大神发一个可以使用的K60读取MMA8451的I2C程序啊?我调试了好多天了,可是还是调试不出来,我用的是龙丘的程序,但是它一直读到的是255,而且ID验证也是失败的!求救~~~~~~~~~~~~~~~~
下面是程序:
/********************************************************
【平 台】龙丘CORTEX-M4开发板/系统板
【编 写】龙丘
【Designed】by Chiu Sir
【E-mail 】chiusir@yahoo.cn
【软件版本】V1.0
【最后更新】2011年12月25日
【相关信息参考下列地址】
【网 站】http://www.lqist.cn
【淘宝店铺】http://shop36265907.taobao.com
【dev.env.】Code Warrior 10.1
【Target 】CORTEX-M4
【Crystal 】50.000Mhz
【busclock】50.000MHz
【pllclock】 ?MHz
------------------------------------------------
------------------------------------------------
接线如下:
将D6引脚设置为模式3,即UART0_RX
将D7引脚设置为模式3,即UART0_TX
SA0接3.3V
SCL D8引脚启用I2C0 SCL功能
SDA D9引脚启用I2C0 SDA功能
3.3v
GND
使用PORTA BIT14,15,16,17流水灯程序
1012-02-06 待测试,测试没反应
*********************************************************/
#include <stdio.h>
#include "includes.h"
#include "mma8451.h"
#define MMA845X_ADD 0X38
uint8 mmadata=0;
void pllinit180M(void)
{
uint32_t temp_reg;
//使能IO端口时钟
SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK
| SIM_SCGC5_PORTB_MASK
| SIM_SCGC5_PORTC_MASK
| SIM_SCGC5_PORTD_MASK
| SIM_SCGC5_PORTE_MASK );
//这里处在默认的FEI模式
//首先移动到FBE模式
MCG_C2 = 0;
//MCG_C2 = MCG_C2_RANGE(2) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
//初始化晶振后释放锁定状态的振荡器和GPIO
SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK;
LLWU_CS |= LLWU_CS_ACKISO_MASK;
//选择外部晶振,参考分频器,清IREFS来启动外部晶振
//011 If RANGE = 0, Divide Factor is 8; for all other RANGE values, Divide Factor is 256.
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
//等待晶振稳定
//while (!(MCG_S & MCG_S_OSCINIT_MASK)){} //等待锁相环初始化结束
while (MCG_S & MCG_S_IREFST_MASK){} //等待时钟切换到外部参考时钟
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}
//进入FBE模式,
MCG_C5 = MCG_C5_PRDIV(0x0e);//分频在2~4MHz之间,分频后频率=晶振频率/(PRDIV+1) 3.3MHz
MCG_C6 = 0x0;//确保MCG_C6处于复位状态,禁止LOLIE、PLL、和时钟控制器,清PLL VCO分频器
temp_reg = FMC_PFAPR;//保存FMC_PFAPR当前的值
FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK
| FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK
| FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; //通过M&PFD置位M0PFD来禁止预取功能
///设置系统分频器
//MCG=PLL, core = MCG, bus = MCG/3, FlexBus = MCG/3, Flash clock= MCG/8
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2)
| SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(7);
FMC_PFAPR = temp_reg;//从新存FMC_PFAPR的原始值
//设置VCO分频器,使能PLL为100MHz, LOLIE=0, PLLS=1, CME=0, VDIV=26
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(30); //VDIV = 31 (x54)
//VDIV = 26 (x50)
while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set
while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set
//进入PBE模式
//通过清零CLKS位来进入PEE模式
// CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 &= ~MCG_C1_CLKS_MASK;
//等待时钟状态位更新
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
}
//IO口初始化
void IO_Init()
{
/* 打开各个端口的时钟源 */
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK |
SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
PORTA_PCR14=PORT_PCR_MUX(1);//A14引脚设置为GPIO模式
PORTA_PCR15=PORT_PCR_MUX(1);//A15引脚设置为GPIO模式
PORTA_PCR16=PORT_PCR_MUX(1);//A16引脚设置为GPIO模式
PORTA_PCR17=PORT_PCR_MUX(1);//A17引脚设置为GPIO模式
PORTD_PCR2 = PORT_PCR_MUX(1)|PORT_PCR_IRQC(0x9);//|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK;
//D2口GPIO功能,上升沿中断,PE启用拉电阻,PS上拉电阻
}
void uart_putchar(unsigned char data)
{
while(!(UART0_S1&UART_S1_TDRE_MASK));//等待发送缓冲区空
UART0_D=data;
}
unsigned char uart_getchar(void)
{
while(!(UART0_S1&UART_S1_RDRF_MASK));//等待数据到达
return UART0_D;
}
//UART0初始化,使用PTD6为UART0_RX,PTD7为UART0_TX
//波特率:9600
void putstr(char ch[])
{
unsigned char ptr=0;
while(ch[ptr])
{
uart_putchar((unsigned char)ch[ptr++]);
}
}
void UART0_Init(void)
{
unsigned long uartclk_khz=180000;//时钟180MHz
unsigned long baud=96000;//波特率96000
unsigned short sbr,brfa;
PORTD_PCR6|=PORT_PCR_MUX(3);//将D6引脚设置为模式3,即UART0_RX
PORTD_PCR7|=PORT_PCR_MUX(3);//将D7引脚设置为模式3,即UART0_TX
SIM_SCGC4|=SIM_SCGC4_UART0_MASK;//开启UART0时钟
//波特率96000 时钟180MHz
sbr=(unsigned short)((180000000)/(9600*16));//计算并设置波特率
UART0_BDH=(unsigned char)((sbr&0x1F00)>>8);
UART0_BDL=(unsigned char)(sbr&0x00FF);
brfa = (((uartclk_khz*32000)/(baud*16))-(sbr*32));
UART0_C4 = (unsigned char)(brfa & 0x001F);
UART0_C2|=(UART_C2_TE_MASK|UART_C2_RE_MASK);
UART0_C1=0;
}
void I2C0_Init(void)
{
SIM_SCGC4|=SIM_SCGC4_I2C0_MASK;//打开I2C时钟
PORTD_PCR8=PORT_PCR_MUX(2);//D8引脚启用I2C0 SCL功能
//PORTD_PCR8|=PORT_PCR_PE_MASK;
//PORTD_PCR8|=PORT_PCR_ODE_MASK;
PORTD_PCR9=PORT_PCR_MUX(2);//D9引脚启用I2C0 SDA功能
//PORTD_PCR9|=PORT_PCR_ODE_MASK;
//PORTD_PCR9|=PORT_PCR_PE_MASK;
// 4分频
//180/4/15=3M
I2C0_F=I2C_F_MULT(0)|I2C_F_ICR(0);//设置波特率
//I2C0_A1=0X12;
I2C0_C1|=I2C_C1_IICEN_MASK;//I2C0使能
I2C0_C1|=I2C_C1_MST_MASK;//主机模式
}
void MMA845x_writebyte(uint8 address, uint8 thedata)
{
I2C0_C1|=I2C_C1_MST_MASK;//主机模式,START信号
I2C0_C1|=I2C_C1_TX_MASK;//发送模式
I2C0_D=MMA845X_ADD;//发送地址
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;//清除标志位
I2C0_D=address;//发送要读取寄存器地址
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;
I2C0_D=thedata;//写数据
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;
I2C0_C1&=~I2C_C1_MST_MASK;//从机模式,STOP信号
}
void delay()
{
int i;
int j;
for(i=0;i<300;i++)
for(j=0;j<10;j++)
asm("nop");
}
void longdelay()
{
int i;
int j;
for(i=0;i<3000;i++)
for(j=0;j<1000;j++)
asm("nop");
}
//读取8451寄存器
//adress :寄存器地址
//8451地址 0x3A,A0接高电平
uint8 MMA845x_readbyte(unsigned char address)
{
uint8 ret=0;
I2C0_C1|=I2C_C1_MST_MASK;//主机模式,START信号
I2C0_C1|=I2C_C1_TX_MASK;//发送模式
I2C0_D=MMA845X_ADD;
while((I2C0_S&I2C_S_IICIF_MASK)==0);//interrupt
I2C0_S|=I2C_S_IICIF_MASK;
I2C0_D=address;
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;//清除标志位
I2C0_C1|=I2C_C1_RSTA_MASK;//repeat start
I2C0_D=(MMA845X_ADD+1);
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;
I2C0_C1&=~I2C_C1_TX_MASK;//接收模式
I2C0_C1|=I2C_C1_TXAK_MASK;//下一个字节接收完成自动产生NAK
ret=I2C0_D;//启动接收下一个字节
while((I2C0_S&I2C_S_IICIF_MASK)==0);//等待传输完成
I2C0_S|=I2C_S_IICIF_MASK;
I2C0_C1&=~I2C_C1_MST_MASK;//从机模式,STOP信号
ret=I2C0_D;//启动接收下一个字节
I2C0_C1|=I2C_C1_TX_MASK;//切换回发送模式
return ret;
}
void MMA845x_init(void)
{
MMA845x_writebyte(CTRL_REG1,(ASLP_RATE_20MS+DATA_RATE_5MS+ACTIVE_MASK)); //50HZ 20ms
delay();
MMA845x_writebyte(XYZ_DATA_CFG_REG, FULL_SCALE_2G); //
delay();
//MMA845x_writebyte(CTRL_REG1, ACTIVE_MASK); //激活状态
//delay();
}
void main(void)
{
unsigned char x=0,y,z,v;
char txtbuf[20];
pllinit180M();
IO_Init();
UART0_Init();
I2C0_Init();
MMA845x_init();
v= MMA845x_readbyte(WHO_AM_I_REG);
if((v == MMA8451Q_ID)||(v == MMA8452Q_ID)||(v == MMA8453Q_ID))
{
putstr("\nLQ_845XM OK!");
}
else
{
putstr("\nLQ_845XM failed!");
}
for(;;)
{
x = MMA845x_readbyte(OUT_X_MSB_REG);
y = MMA845x_readbyte(OUT_Y_MSB_REG);
z = MMA845x_readbyte(OUT_Z_MSB_REG);
sprintf(txtbuf,"x:%03d,y:%03d,z:%03d",x,y,z);
putstr(txtbuf);
putstr("\n\r");
longdelay();
}
//return 0;
}
|
|