stm8s与adxl345的程序请教

        请大家帮帮我,调试了几天,通过串口打印读出来的ADXL345三轴的加速度只是-1,拜托大牛们帮帮我
     IIC程序如下:

#include "iic.h"
/*
函数名称 : IIC_Config
功    能 : 基本配置
参    数 : 无
返 回 值 : 无
作    者 : 
库 版 本 : V2.3.0
文件版本 : V1.0
日    期 : 
*/      
void IIC_Config(void)
{
   I2C->CR1 &=~(1<<0);//禁用I2C模块
   CLK->PCKENR1 &=~(0X1<<0); 
   CLK->PCKENR1 |=(0X1<<0);//使能IIC外设时钟
   SCL_OUT();
   SDA_OUT();
   IIC_SCL(1);
   IIC_SDA(1);
   /*
   I2C->FREQR &=~(1<<5); //输入时钟频率16M
   I2C->FREQR |= (1<<5);
   I2C->TRISER &=~(0X1F<<0); //0x10 + 1
   I2C->TRISER |= (0X11<<0);
   I2C->CCRL &=~( 0xFF<<0); //16M / 100K / 2
   I2C->CCRL |=(0X50<<0);
   I2C->CCRH  = 0x00; 
   I2C->CR1 &=~(0X01<<0); //开启I2C外设
   I2C->CR1 |=(0X01<<0); 
   I2C->CR2 &=~(0X4<<0); //应答使能
   I2C->CR2 |=(0X4<<0);
   I2C->OARL   = 0x50; //自身地址
   I2C->OARH   = 0x00;
   SCL_H();//ODR4置位--发送1
   SDA_H();//ODR5置位--发送1 
   */  
}
/****************************
*函数名:IIC_start
*函数功能:模拟 iic 启动信号
*函数参数:无
*函数返回值:无
*作者:
*时间:
*版本:v1.0
*****************************/
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA(1);	  	  
	IIC_SCL(1);
	Delay_nus(4);
 	IIC_SDA(0);//START:when CLK is high,DATA change form high to low 
	Delay_nus(4);
	IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 
}	  
/****************************
*函数名:IIC_stop
*函数功能:模拟 iic 停止信号
*函数参数:无
*函数返回值:无
*版本:v1.0
*****************************/
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
        IIC_SDA(0);
	IIC_SCL(1);//STOP:when CLK is high DATA change form low to high
 	Delay_nus(4);
	//IIC_SCL(1); 
	IIC_SDA(1);//发送I2C总线结束信号
	Delay_nus(4);							   	
}
/**********************************
*函数名:IIC_waitAck
*函数功能:IIC master 等待应答信号
*函数参数:无
*函数返回值:无
*作者:
*版本:v1.0
**********************************/
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_WaitAck(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA(1);Delay_nus(1);	   
	IIC_SCL(1);Delay_nus(1);	 
	while(READ_SDA())
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL(0);//时钟输出0 	   
	return 0;  
} 
/****************************
*函数名:IIC_ack
*函数功能:给应答信号
*函数参数:无
*函数返回值:无
*作者:
*版本:v1.0
*****************************/
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(1);
	Delay_nus(2);
	IIC_SDA(0);//拉低应答
	Delay_nus(3);
	IIC_SCL(1);
	Delay_nus(4);
	IIC_SCL(0);
	Delay_nus(2);
	IIC_SDA(1);
}
/****************************
*函数名:IIC_nAck
*函数功能:不给应答信号
*函数参数:无
*函数返回值:无
*作者:
*时间:
*版本:v1.0
*****************************/
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(1);
	Delay_nus(2);
	IIC_SDA(1);
	Delay_nus(3);
	IIC_SCL(1);
	Delay_nus(4);
	IIC_SCL(0);
	Delay_nus(2);
	IIC_SDA(1);
}			
/****************************
*函数名:IIC_sendByte
*函数功能:发送一个字节
*函数参数:txd
*函数返回值:无
*作者:
*版本:v1.0
*****************************/
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_SendByte(u8 txd)
{                        
    u8 t;     
    SDA_OUT(); 	    
    IIC_SCL(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
			IIC_SDA((txd&0x80)>>7);//从高位到地位发
			txd<<=1; 	  
			Delay_nus(2);   //对TEA5767这三个延时都是必须的
			IIC_SCL(1);
			Delay_nus(2); 
			IIC_SCL(0);	
			Delay_nus(2);
    }	 
} 	    
/*
*函数名:IIC_readByte
*函数功能:读取一个字节
*函数参数:ack=0 时,发送 ACK,ack=1,发送 nACK
*函数返回值:返回读取到的数据
*作者:
*版本:v1.0
*/
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_ReadByte(unsigned char ack)
{
  u8 i,receive=0;
  SDA_IN();//SDA设置为输入
  for(i=0;i<8;i++)
	{
    IIC_SCL(0); 
    Delay_nus(2);
		IIC_SCL(1);
    receive<<=1;
    if(READ_SDA())receive++;   
		Delay_nus(1); 
   }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}
#ifndef _IIC_H_
#define _IIC_H_
#include "stm8s.h"
#include "delay.h"
#include "stdio.h"
#include "string.h"

//IO 方向
#define SCL_OUT(){GPIOB->DDR |=(1<<4);GPIOB->CR1 |=(1<<4);GPIOB->CR2 &=~(1<<4);}
#define SDA_IN() {GPIOB->DDR &=~(1<<5);GPIOB->CR1 &=~(1<<5);GPIOB->CR1 |=(1<<5);GPIOB->CR2 &=~(1<<5);} 
#define SDA_OUT() {GPIOB->DDR &=~(1<<5);GPIOB->DDR |=(1<<5);GPIOB->CR1 &=~(1<<5);GPIOB->CR1 |=(1<<5);GPIOB->CR2 &=~(1<<5);} 
#define IIC_SCL(x) x?(GPIOB->ODR &= ~(1<<4)):(GPIOB->ODR |= (1<<4))
#define IIC_SDA(x) x?(GPIOB->ODR &= ~(1<<5)):(GPIOB->ODR |= (1<<5))
#define READ_SDA() (GPIOB->IDR & (1<<5))

//IIC所有操作函数
void IIC_Config(void);            //初始化IIC的IO口				 
void IIC_Start(void);		//发送IIC开始信号
void IIC_Stop(void);	       //发送IIC停止信号
void IIC_SendByte(u8 txd);   //IIC发送一个字节
u8 IIC_ReadByte(unsigned char ack);//IIC读取一个字节
u8 IIC_WaitAck(void); //IIC等待ACK信号
void IIC_Ack(void);//IIC发送ACK信号
void IIC_NAck(void);//IIC不发送ACK信号
#endif

 串口程序如下:

#include "uart.h"
void UART1_Config(void)      //串口1初始化配置
{
    //PD5--UATI1_TX--推挽输出,PD6--UART1_RX--浮空输入
    //输出模式,推挽输出TXD
    GPIOD->DDR &= ~(1<<5); 
    GPIOD->CR1 |=  (1<<5); 
    //输入模式,浮空输入 RX
    GPIOD->DDR &= ~(1<<6); 
    GPIOD->CR1 &= ~(1<<6);
    u16 Uart1_DIV;
    Uart1_DIV = 16000000/115200;      //串口分频值
    UART1->BRR2 = (u8)((Uart1_DIV & 0xf000) >> 8)|(u8)((Uart1_DIV & 0x000f));
    UART1->BRR1 = (u8)((Uart1_DIV & 0x0ff0) >> 4);
    UART1->CR1 = 0;   //使能串口1,禁用奇偶校验
    UART1->CR2 &=~(0X7F<<2); //接收终端使能,接受使能,发送使能
    UART1->CR2 |= (0XB<<2);
    UART1->CR3 &=~(0X3<<4);//一个停止位
 }
/*
函数名称 : UART1_SendByte
功    能 : UART1发送一个字符
参    数 : Data --- 数据
返 回 值 : 无
作    者 :
时   间  :2018年10月27日10:18:35
*/
void UART1_SendByte(uint8_t Data)
{
  while((UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
  UART1_SendData8(Data);
  while((UART1_GetFlagStatus(UART1_FLAG_TC)==RESET));
}

/*
函数名称 : UART1_SendNByte
功    能 : 串口1发送N个字符
参    数 : pData ---- 字符串
            Length --- 长度
返 回 值 : 无
作    者 : 
时   间  :2018年10月27日10:18:35
*/
void UART1_SendNByte(uint8_t *pData, uint16_t Length)
{
  while(Length--)
  {
    UART1_SendByte(*pData);
    pData++;
  }
}
/*
  函数名:fputc
  描述  :重定向c库函数printf到USART1
  输入  :无
  输出  :无
  调用  :由printf调用
*/
int fputc(int ch, FILE *f)
{  
 /*将Printf内容发往串口*/ 
  UART1->DR=(unsigned char)ch;
  while (!(UART1->SR & UART1_FLAG_TXE));
  return (ch);
}

/*
函数名称 : UART1_Printf
功    能 : 串口1打印输出
参    数 : String --- 字符串
返 回 值 : 无
作    者 :
时   间  :2018年10月27日10:18:35
*/
void UART1_Printf(float *String)
{
  while((*String) != '\0')
  {
    UART1_SendByte((int)*String);
    String++;
  }
}
#ifndef _UART_H_
#define _UART_H_
#include "stm8s.h"
#include "stdio.h"
#include "string.h"

void UART1_Config(void);
void UART1_SendByte(uint8_t Data);
void UART1_SendNByte(uint8_t *pData, uint16_t Length);
//int fputc(int ch, FILE *f);
void UART1_Printf(float *String);

#endif

ADXL345与main函数程序如下: 

#include "adxl345.h" 
//初始化ADXL345.
//返回值:0,初始化成功;1,初始化失败.
u8 ADXL345_Config(void)
{				  
   IIC_Config();//初始化IIC总线
   if(ADXL345_RD_Reg(DEVICE_ID)==0XE5)	//读取器件ID
     {  
	ADXL345_WR_Reg(DATA_FORMAT,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 
	ADXL345_WR_Reg(BW_RATE,0x0A);		//数据输出速度为100Hz
	ADXL345_WR_Reg(POWER_CTL,0x28);	   	//链接使能,测量模式
	ADXL345_WR_Reg(INT_ENABLE,0x00);	//不使用中断		 
	ADXL345_WR_Reg(OFSX,0x00);
        ADXL345_WR_Reg(OFSY,0x00);
	ADXL345_WR_Reg(OFSZ,0x00);	
	return 0;
      }			
   return 1;	   								  
}   
//写ADXL345寄存器
//addr:寄存器地址
//val:要写入的值
//返回值:无
void ADXL345_WR_Reg(u8 addr,u8 val) 
{
   IIC_Start();  				 
   IIC_SendByte(ADXL_WRITE);     	//发送写器件指令	 
   IIC_WaitAck();	   
   IIC_SendByte(addr);   			//发送寄存器地址
   IIC_WaitAck(); 	 										  		   
   IIC_SendByte(val);     		//发送值					   
   IIC_WaitAck();  		    	   
   IIC_Stop();						//产生一个停止条件 	   
}
//读ADXL345寄存器
//addr:寄存器地址
//返回值:读到的值
u8 ADXL345_RD_Reg(u8 addr) 		
{
    u8 temp=0;		 
    IIC_Start();  				 
    IIC_SendByte(ADXL_WRITE);	//发送写器件指令	 
    temp=IIC_WaitAck();	   
    IIC_SendByte(addr);   		//发送寄存器地址
    temp=IIC_WaitAck(); 	 										  		   
    IIC_Start();  	 	   		//重新启动
    IIC_SendByte(ADXL_READ);	//发送读器件指令	 
    temp=IIC_WaitAck();	   
    temp=IIC_ReadByte(0);		//读取一个字节,不继续再读,发送NAK 	    	   
    IIC_Stop();					//产生一个停止条件 	    
    return temp;				//返回读到的值
}  
//读取ADXL的平均值
//x,y,z:读取10次后取平均值
void ADXL345_RD_Avval(short *x,short *y,short *z)
{
   short tx=0,ty=0,tz=0;	   
   u8 i;  
   for(i=0;i<10;i++)
      {
         ADXL345_RD_XYZ(x,y,z);
	 Delay_nms(10);
	 tx+=(short)*x;
	 ty+=(short)*y;
	 tz+=(short)*z;	   
       }
    *x=tx/10;
    *y=ty/10;
    *z=tz/10;
} 
//自动校准
//xval,yval,zval:x,y,z轴的校准值
void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval)
{
   short tx,ty,tz;
   u8 i;
   short offx=0,offy=0,offz=0;
   ADXL345_WR_Reg(POWER_CTL,0x00);	   	//先进入休眠模式.
   Delay_nms(100);
   ADXL345_WR_Reg(DATA_FORMAT,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 
   ADXL345_WR_Reg(BW_RATE,0x0A);		//数据输出速度为100Hz
   ADXL345_WR_Reg(POWER_CTL,0x28);	   	//链接使能,测量模式
   ADXL345_WR_Reg(INT_ENABLE,0x00);	//不使用中断		 

   ADXL345_WR_Reg(OFSX,0x00);
   ADXL345_WR_Reg(OFSY,0x00);
   ADXL345_WR_Reg(OFSZ,0x00);
   Delay_nms(12);
   for(i=0;i<10;i++)
      {
         ADXL345_RD_Avval(&tx,&ty,&tz);
         offx+=tx;
         offy+=ty;
         offz+=tz;
      }	 		
   offx/=10;
   offy/=10;
   offz/=10;
   *xval=-offx/4;
   *yval=-offy/4;
   *zval=-(offz-256)/4;	  
   ADXL345_WR_Reg(OFSX,*xval);
   ADXL345_WR_Reg(OFSY,*yval);
   ADXL345_WR_Reg(OFSZ,*zval);	
} 
//读取3个轴的数据
//x,y,z:读取到的数据
void ADXL345_RD_XYZ(short *x,short *y,short *z)
{
    u8 buf[6];
    u8 i;
    IIC_Start();  				 
    IIC_SendByte(ADXL_WRITE);	//发送写器件指令	 
    IIC_WaitAck();	   
    IIC_SendByte(0x32);   		//发送寄存器地址(数据缓存的起始地址为0X32)
    IIC_WaitAck(); 	 										  		   
 
    IIC_Start();  	 	   		//重新启动
    IIC_SendByte(ADXL_READ);	//发送读器件指令
    IIC_WaitAck();
    for(i=0;i<6;i++)
       {
          if(i==5)buf[i]=IIC_ReadByte(0);//读取一个字节,不继续再读,发送NACK  
          else buf[i]=IIC_ReadByte(1);	//读取一个字节,继续读,发送ACK 
       }	        	   
    IIC_Stop();					//产生一个停止条件
    *x=(short)(((u16)buf[1]<<8)+buf[0]); 	    
    *y=(short)(((u16)buf[3]<<8)+buf[2]); 	    
    *z=(short)(((u16)buf[5]<<8)+buf[4]); 	   
}
//读取ADXL345的数据times次,再取平均
//x,y,z:读到的数据
//times:读取多少次
void ADXL345_Read_Average(short *x,short *y,short *z,u8 times)
{
   u8 i;
   short tx,ty,tz;
   *x=0;
   *y=0;
   *z=0;
   if(times)//读取次数不为0
     {
        for(i=0;i

 

 stm8s与adxl345的程序请教_第1张图片

你可能感兴趣的:(开发,运动检测)