背景信息:
A使用的芯片 TM4C123GH6PMI
B 硬件环境 TM4C123G Launchpad
C 软件环境 TivaWare_C_Series-2.1.0.12573
D其它 CCS6.0.1 加速度传感器为mpu6500
使用SSI0模块
ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK); //PA2功能配置为SSI0CLK,时钟线
ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS); //PA3功能配置为SSI0FSS,片选线
ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX); //PA5功能配置为SSI0TX,数据发送线
ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX); //PA4功能配置为SSI0RX,数据接收线
第一次弄这种与外接传感器通信读取数据的,很多地方不太明白,请大家多多帮助!
问题1: 用示波器观察PA5引脚的数据发送情况,发现接和不接传感器时波形不同?图一为不接传感器。图二为接上传感器后,在时钟空闲时仍存在数据变换,但是都是一些无用的数据,应该没有影响的吧?
问题2:SPI_Write_register和SPI_Read_register这两个函数中我分别对引入的参数WriteReg做了如下操作:WriteReg+=0x80;和WriteReg&=0x7F;目的是按照SPI的要求在进行写操作时把第一个字节的首位变为1,读操作的时候把第一个字节的首位变为0。请问这样的做法是否正确?
//往MPU6500的寄存器写入
uint8_t SPI_Write_register(uint8_t WriteReg,uint8_t Value)//WriteReg要写的寄存器地址,Value要写的寄存器值
{
uint8_t status;
WriteReg+=0x80;
// ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
status=SPI_RW(WriteReg);
SPI_RW(Value);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
return(status);
}
//读取MPU6500指定寄存器的值
uint8_t SPI_Read_register(uint8_t WriteReg)
{
uint8_t status;
WriteReg&=0x7F;
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
//status=SPI_RW(WriteReg);
SPI_RW(WriteReg);
status=SPI_RW(0);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
return(status);
}
问题3:用示波器观察PA4引脚的数据接收情况,发现一直处于低电平,既读出的数据一直为零。是不是我对mpu6500的寄存器的写操作没有成功,使得mpu6500没有被成功配置造成的?
下面是我的代码:
//----------------------------------------------------------------------------
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/ssi.h"
#include "driverlib/pin_map.h"
#include "driverlib/adc.h"
#include "mpu6500.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
//----------------------------------------------------------------------------
unsigned char BUF[10]; //接收数据缓存区
short T_X,T_Y,T_Z,T_T; //X,Y,Z轴,温度
void delay()
{
unsigned int counter = 0;
while(counter < 10000){
counter++;
}
}
//-------------------------------------------------------------------------------------------
// @brief SSI模块使能,并且设置相关端口初始状态
// @param none
// @return none
// _______________
// |
// PA2(SSI0Clk)|-->*** 时钟信号端
// TIVA PA3(SSI0Fss)|-->SYNC 帧信号端
// PA5(SSI0Tx) |-->SDIN SSI数据发送端(LM4F120->DAC8802)
// PA4(SSI0Rx) |-->SDOUT
// ________________|
//
//-------------------------------------------------------------------------------------------
void ssi_en()
{
uint32_t ui32Data;
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); //使能外设SSI0模块
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); //使能SSI0使用的外设GPIOA
//SSI0端口功能使能
ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK); //PA2功能配置为SSI0CLK,时钟线
ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS); //PA3功能配置为SSI0FSS,帧信号
ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX); //PA5功能配置为SSI0TX,数据发送线
ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX); //PA4功能配置为SSI0RX,数据发送线
ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5); //配置PA2,PA3,PA4,PA5供外设SSI0使用
ROM_SSIConfigSetExpClk(SSI0_BASE, ROM_SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 1000000, 8); //端口模式:1MHZ,8位数据
ROM_SSIEnable(SSI0_BASE); //使能SSI
while(SSIDataGetNonBlocking(SSI0_BASE, &ui32Data)){};//清除缓冲区的数据,确保读到的数据时正确的。
}
/*unsigned char ssi_send_2_dac8802(unsigned long val)
{
if(val > 16384) return 0;
ROM_SSIDataPut(SSI0_BASE, DAC_AB + val); //发数据+
while(ROM_SSIBusy(SSI0_BASE)); //等待发送完成
//数据发送结束时,LDAC线需要一个电平的跳变(H->L->H)
ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0);
delay();
ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_PIN_2);
delay();
return 1;
}*/
//**********************************************************************
//
uint8_t SPI_RW(uint8_t value)
{
uint32_t ui32Data;
uint8_t ui8Data;
SSIDataPut(SSI0_BASE,value);
while (ROM_SSIBusy(SSI0_BASE))
{
}
ROM_SSIDataGet(SSI0_BASE, &ui32Data);
ui8Data = ui32Data & 0xff;
return(ui8Data);
}
//********************************************************************
//********************************************************************
//往MPU6500的寄存器写入
uint8_t SPI_Write_register(uint8_t WriteReg,uint8_t Value)//WriteReg要写的寄存器地址,Value要写的寄存器值
{
uint8_t status;
WriteReg+=0x80;
// ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
status=SPI_RW(WriteReg);
SPI_RW(Value);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
return(status);
}
//**********************************************************************
//读取MPU6500指定寄存器的值
uint8_t SPI_Read_register(uint8_t WriteReg)
{
uint8_t status;
WriteReg&=0x7F;
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
//status=SPI_RW(WriteReg);
SPI_RW(WriteReg);
status=SPI_RW(0);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
return(status);
}
//初始化MPU9250,根据需要请参考pdf进行修改************************
void Init_MPU9250(void)
{
SPI_Write_register(PWR_MGMT_1, 0x00); //解除休眠状态
SPI_Write_register(SMPLRT_DIV, 0x07);
SPI_Write_register(CONFIG, 0x06);
SPI_Write_register(GYRO_CONFIG, 0x18);
SPI_Write_register(ACCEL_CONFIG, 0x19);
}
//******读取MPU9250数据****************************************
void READ_MPU9250_ACCEL(void)
{
BUF[0]=SPI_Read_register(ACCEL_XOUT_L);
BUF[1]=SPI_Read_register(ACCEL_XOUT_H);
T_X= (BUF[1]<<8)|BUF[0];
// T_X/=164; //读取计算X轴数据
BUF[2]=SPI_Read_register(ACCEL_YOUT_L);
BUF[3]=SPI_Read_register(ACCEL_YOUT_H);
T_Y= (BUF[3]<<8)|BUF[2];
// T_Y/=164; //读取计算Y轴数据
BUF[4]=SPI_Read_register(ACCEL_ZOUT_L);
BUF[5]=SPI_Read_register(ACCEL_ZOUT_H);
T_Z= (BUF[5]<<8)|BUF[4];
// T_Z/=164; //读取计算Z轴数据
}
void READ_MPU9250_GYRO(void)
{
BUF[0]=SPI_Read_register(GYRO_XOUT_L);
BUF[1]=SPI_Read_register(GYRO_XOUT_H);
T_X= (BUF[1]<<8)|BUF[0];
T_X/=16.4; //读取计算X轴数据
BUF[2]=SPI_Read_register(GYRO_YOUT_L);
BUF[3]=SPI_Read_register(GYRO_YOUT_H);
T_Y= (BUF[3]<<8)|BUF[2];
T_Y/=16.4; //读取计算Y轴数据
BUF[4]=SPI_Read_register(GYRO_ZOUT_L);
BUF[5]=SPI_Read_register(GYRO_ZOUT_H);
T_Z= (BUF[5]<<8)|BUF[4];
T_Z/=16.4; //读取计算Z轴数据
// BUF[6]=Single_Read(GYRO_ADDRESS,TEMP_OUT_L);
// BUF[7]=Single_Read(GYRO_ADDRESS,TEMP_OUT_H);
// T_T=(BUF[7]<<8)|BUF[6];
// T_T = 35+ ((double) (T_T + 13200)) / 280;// 读取计算出温度
}
/*
void READ_MPU9250_MAG(void)
{
Single_Write(GYRO_ADDRESS,0x37,0x02);//turn on Bypass Mode
Delayms(10);
Single_Write(MAG_ADDRESS,0x0A,0x01);
Delayms(10);
BUF[0]=Single_Read (MAG_ADDRESS,MAG_XOUT_L);
BUF[1]=Single_Read (MAG_ADDRESS,MAG_XOUT_H);
T_X=(BUF[1]<<8)|BUF[0];
BUF[2]=Single_Read(MAG_ADDRESS,MAG_YOUT_L);
BUF[3]=Single_Read(MAG_ADDRESS,MAG_YOUT_H);
T_Y= (BUF[3]<<8)|BUF[2];
//读取计算Y轴数据
BUF[4]=Single_Read(MAG_ADDRESS,MAG_ZOUT_L);
BUF[5]=Single_Read(MAG_ADDRESS,MAG_ZOUT_H);
T_Z= (BUF[5]<<8)|BUF[4];
//读取计算Z轴数据
}*/
void check(void)
{
BUF[9]=SPI_Read_register(WHO_AM_I);
}