|
芯片 mega32 4线 SPI 与ADXL345通信 数据用串口输出 可以正确读出 芯片 ID号 0xE5 但是读三轴输出数据都是首次读出数据, 比如先读 DATAX0 再读DATAY0,DATAZ0 , DATAY0和DATAZ0与DATAX0都是一样的输出。
我把CS线在不断电源的情下 断开再接上 数据就会刷新一下 ,但是 从第二次以后的数据又和第一次读出的一样
另 把 CS 或 CLK在不断点的情况下 对地短接一下 ,数据会刷新 ,从第二次以后的数据又和第一次读出的一样
是否是我的 SPI时序有问题 还是配置有问题,请帮忙看下
程序:
/****************************************************
CPU MEGA32L
时钟 3.6864MHz
编译 ICCAVR7.14
软件: 2010-07-25
//熔丝配置
**********************************************/
#include <iom32v.h>
#include <macros.h>
#include <eeprom.h>
#include <math.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define YES 0xff
#define NO 0x00
#define OK 0xaa
#define FAIL 0x00
#define ON 0xff
#define OFF 0x00
#define USE 0xaa
#define EMPTY 0x00
#define BTMEA_EN PORTC|=0x10 //允许电池测量PC4
#define BTMEA_DIS PORTC&=0xe7 //禁止电池测量PC4
#define LED_BLACK PORTC|=0x80 //RUN灯灭
#define LED_LIGHT PORTC&=0x7f //RUN灯亮
#define ADS_EN PORTC |= (1 << PC5) //PORTC|=0x20 //启动测量电源 PC5
#define ADS_DIS { PORTC &= ~(1 << PC5); ADCSR=0x00; } //禁止测量电源,关闭ADC
#define DATAX0 0X32
#define DATAX1 0X33
#define DATAY0 0X34
#define DATAY1 0X35
#define DATAZ0 0X36
#define DATAZ1 0X37
#define TX_EN PORTC|=0x40 //串口发送使能 PC6
#define TX_DIS PORTC&=0xbf //禁止串口发送
#define FMCS_EN PORTC&=0xfb //M25P16有效
#define FMCS_DIS PORTC|=0x04 //禁止M25P16
#define CS_ON PORTB&=0XEF
#define CS_OFF PORTB|=0X10
//串口接收中断数据定义
uchar ComSynFlag; //=YES同步建立,内部私有
uchar ComReceiveCounter; //接收字节计数,内部私有
uchar ComReceiveData[48]; //接收缓冲,内部私有
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
//4MHz软件延时n us
void DelayNus(uint n)
{
for(; n; n-- );
}
//4MHz软件延时0-250ms
void DelayNms(uint m)
{
uchar i, j;
for(; m; m-- ){
for(i=0; i<192; i++){
for(j=0;j<3;j++);
}
}
}
//LED闪光,调试用
void LED(void)
{
LED_LIGHT ;
DelayNms(1);
LED_BLACK;
}
/*---------------------------------------------------------------------*/
/********************************************
串口发送1个字节
115.2Kbps传输1byte耗时0.1ms,
发送前等待串口空闲,限时0.5ms退出。
********************************************/
void comtx(uchar dat)
{
uint x;
UCSRB&=0xef; //禁止UART接收
for( x=2000; (UCSRA&0x20)!=0x20 && x; x-- );
UDR=dat;
for( x=2000; (UCSRA&0x20)!=0x20 && x; x-- );
UCSRB|=0x10; //允许UART接收
}
/**********************************
UART初始化
baud rate: 9600bps
**********************************/
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x02;
UCSRC = 0x86; //
UBRR = 47; // 3.686M晶振 9600bps-47, 57600bps-7, 115200bps-3
UCSRB = 0x98; //接收中断
}
/**********************************
UART接收中断
**********************************/
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
uchar x, y;
uint checksum1,checksum2; //checksum of ComReceiveData[]
x=UDR;
}
/**********************************
SPI 初始化 主机模式,速率Fosc/2
**********************************/
void SPI_INIT(void)
{
FMCS_DIS;
CS_OFF;
// DDRB|=0xb0; //SCK MOSI SS 输出 MISO输入
DDRB |=0xbb;
// PORTB&=0xF0;
PORTB |= 0xFf; //SS PB4高电平,其余初始状态低电平
SPCR=0x5D;
}
/**********************************
SPI 字节写
**********************************/
void SPI_Master_tx(uchar x)
{
SPDR=x;
while(!(SPSR&0x80));
}
/**********************************
SPI 字节读
**********************************/
uchar SPI_Master_re(void)
{
SPDR=0;
while(!(SPSR&0x80));
return SPDR;
}
void SPI_WritData(uchar addr,uchar data)
{
CLI();
CS_ON;
DelayNus(500);
SPI_Master_tx(addr);
SPI_Master_tx(data);
DelayNus(500);
CS_OFF;
SEI();
DelayNms(10);
}
uchar SPI_ReadData(uchar addr)
{
uchar Data;
CS_ON;
CLI();
DelayNus(500);
SPI_Master_tx(addr);
Data=SPI_Master_re();
DelayNus(500);
CS_OFF;
SEI();
return Data;
}
void ADXL345_init(void)
{
SPI_WritData(0x31,0x2b);
SPI_WritData(0x1E,0x00); //X轴误差补偿; (15.6mg/LSB)
SPI_WritData(0x1F,0x00); //Y轴误差补偿; (15.6mg/LSB)
SPI_WritData(0x20,0x00); //Z轴误差补偿; (15.6mg/LSB)
SPI_WritData(0x21,0x00); //敲击延时0:禁用; (1.25ms/LSB)
SPI_WritData(0x22,0x00); //检测第一次敲击后的延时0:禁用; (1.25ms/LSB)
SPI_WritData(0x23,0x00); //敲击窗口0:禁用; (1.25ms/LSB)
SPI_WritData(0x24,0x01); //保存检测活动阀值; (62.5mg/LSB)
SPI_WritData(0x25,0x01); //保存检测静止阀值; (62.5mg/LSB)
SPI_WritData(0x26,0x2B); //检测活动时间阀值; (1s/LSB)
SPI_WritData(0x27,0x00); //
SPI_WritData(0x28,0x09); //自由落体检测推荐阀值; (62.5mg/LSB)
SPI_WritData(0x29,0xFF); //自由落体检测时间阀值,设置为最大时间; (5ms/LSB)
SPI_WritData(0x2A,0x80); //
//SPI_Read(0x2B); //只读寄存器,状态读取
SPI_WritData(0x2C,0x0A); //
SPI_WritData(0x2D,0x28); //开启Link,测量功能;关闭自动休眠,休眠,唤醒功能
SPI_WritData(0x2E,0x00); //所有均关闭
SPI_WritData(0x2F,0x00); //中断功能设定,不使用中断
//SPI_Read(0x30); //只读寄存器,状态读取
SPI_WritData(0x38,0x81); //FIFO模式设定,Stream模式,触发连接INT1,31级样本缓冲
//SPI_Read(0x39); //只读寄存器,状态读取
}
/*------------------------------------------------------------------*/
/**************************
CPU设备初始化
**************************/
void init_devices(void)
{
uchar i;
uchar tm[4];
CLI();
//低功耗策略
PORTA = 0xf0; //PA0-PA3禁止上拉电阻防止影响AD627
DDRA = 0xf0; //PA0-PA3输入,其余输出
PORTB = 0xff;
DDRB = 0xbb; //PB6 PB2输入,其余输出
PORTC = 0xf0;
DDRC = 0xff; //全输出
PORTD = 0xff;
DDRD = 0xe2; //PD0 PD2~PD4输入,其余输出
SPI_INIT(); //SPI 初始化
uart0_init();
}
/*------------------------------------------------------------------*/
void main(void)
{
uchar i;
uint m;
uchar sum[10]={0};
for(i=0;i<10;i++){ //上电延迟等待电源稳定
DelayNms(100);
}
init_devices();
ADXL345_init();
while(1)
{
i=0;
sum[0]=SPI_ReadData(DATAX0); //读出的数据都是第一次的数据信息 ?
comtx(sum[0]);
DelayNms(500);
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|