yishengjun2012 发表于 2012-9-18 00:04:05

求助M8控制MMA7455,SPI方式,目前没成功

本帖最后由 yishengjun2012 于 2012-9-18 00:14 编辑

//ICC-AVR application builder : 2012/9/16 22:07:45
// Target : M8
// Crystal: 7.3728Mhz

#include <iom8v.h>
#include <macros.h>
#include "1602.h"

#define SIZE 100   

unsigned char SPI_rx_buff;
unsigned char SPI_tx_buff;
unsigned char rx_wr_index,rx_rd_index,rx_counter,rx_buffer_overflow;
unsigned char tx_wr_index,tx_rd_index,tx_counter,SPI_ok;   
unsigned char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};


#pragma interrupt_handler spi_stc_isr:18   
void spi_stc_isr(void)   
{   
SPI_rx_buff = SPDR;    //从ISP口读出收到的字节
SPI_ok = 1;                         // SPI 空闲
if (++rx_wr_index == SIZE) rx_wr_index = 0;    //放入接收缓冲区,并调整队列指针   
if (++rx_counter == SIZE)   
{   
    rx_counter = 0;   
    rx_buffer_overflow = 1;   
}   
if (tx_counter)      //如果发送缓冲区中有待发的数据   
{   
   --tx_counter;   
   SPDR = SPI_tx_buff; //发送一个字节数据,并调整指针   
   if (++tx_rd_index == SIZE) tx_rd_index = 0;   
      SPI_ok = 0;                      // SPI 发送工作
}   
}   

unsigned char getSPIchar(void)   
{   
unsigned char data;   
while (rx_counter == 0);   //无接收数据,等待   
data = SPI_rx_buff;    //从接收缓冲区取出一个SPI收到的数据   
if (++rx_rd_index == SIZE) rx_rd_index = 0;    //调整指针   
CLI();   
--rx_counter;   
SEI();   
return data;
}   

void putSPIchar(char c)   
{   
while (tx_counter == SIZE);//发送缓冲区满,等待   
CLI();   
if (tx_counter || SPI_ok==0 )      //发送缓冲区已中有待发数据   
   {                //或SPI正在发送数据时   
    SPI_tx_buff = c;    //将数据放入发送缓冲区排队   
    if (++tx_wr_index == SIZE) tx_wr_index = 0;    //调整指针   
    ++tx_counter;   
}   
else
{   
    SPDR = c;      // 发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送   
    SPI_ok = 0;      // SPI 发送工作
}
SEI();   
}   
void spi_init(void)   
{   
unsigned char temp;   
DDRB|= 0b00101100;    //MISO=input and MOSI,SCK,SS = output   
PORTB|=0b00010000;    //MISO上拉电阻有效
PORTB&=~0b00000100;   
SPCR = 0xD3;    //SPI允许,主机模式,MSB,允许SPI中断,极性方式01,1/16系统时钟速率   
SPSR = 0x00;   
temp = SPSR;   
temp = SPDR;    //清空SPI,和中断标志,使SPI空闲   
SPI_ok = 1;   // SPI 空闲
}   



void main(void)   
{   
unsigned char i=0x0c;
unsigned char x100,x10,x1,d;   
CLI();      //关中断   
spi_init();    //初始化SPI接口   
SEI();      //开中断   
LCD_init();
LCD_write_char(0,0,'a');
while(1)   
{   
    putSPIchar(0xAc);   //写控制寄存器地址
        putSPIchar(0x41);   //写控制寄存器数据
       
    putSPIchar(0x2c);      //发送   
        d=getSPIchar();         //接收一个字节(第一个字节为空字节)
        x100=d/100;
        d=d-x100*100;
        x10=d/10;
        d=d-x10*10;
        x1=d;
    LCD_write_char(0,0,table);
        LCD_write_char(1,0,table);
        LCD_write_char(2,0,table);
        delay_nms(1000);   
}   
}   

这个程序师本坛马老师的例子,我修改到M8上面了,我把MOSI和MISO短接,1602上可以正确收发数据,所以收发程序应该没问题。

我的目的是M8控制MMA7455,这是个验证程序,就是将数据写入MMA7455方式寄存器,然后读出来,但是无论如何都不能读到数据。
我简单描述一下流程:
1、按照7455手册上的规范,首先向7455写入寄存器地址:1位读写状态(0=读,1=写)+6位地址(寄存器地址是0x16)+1位无作用位
   所以地址为1+010110+0=0XAC;
2、接着写入数据0X41;
3、接着读出数据,地址变为0+010110+0=00x2c;
4、转换读出的数据位三位字符给1602显示。

各位看看我程序的流程和操作有问题没有,为什么读不出数据?或者哪位用过7455给提供个范例也行啊,非常感谢。搞好久了,头大了。


yishengjun2012 发表于 2012-9-18 08:28:52

早上一通电,有反应了,哈哈,可以读出来了。
但是有时候读出来的是0,可能是没有使用7455的数据准备好中断,所以在数据没准备好的时候去读就出现0了。

fanice 发表于 2012-9-20 19:23:50

恭喜你了,我用IIC还是没有读出来啊。

yishengjun2012 发表于 2012-9-22 22:07:09

i2c过程有点复杂,SPI简单。

xihudelei 发表于 2012-11-25 21:50:46

我的没有读出来,全是00,而且时钟线也没信号,求指教啊QQ615213015
页: [1]
查看完整版本: 求助M8控制MMA7455,SPI方式,目前没成功