avrwj 发表于 2009-11-18 22:43:44

SPI 通信问题请教

请教一下傻孩子师兄一个简单的问题:我用SPI的时候怎么不能同时显示:主机发送后,从机要复位才能接受一个数据呢?
      88主机发送:
            #include <iom88v.h>
#include <macros.h>
#defineuchar unsigned char
#defineuintunsigned int
#include "SP027DriverV2.h"
#define ChangeEdge          EICRA ^= BIT(ISC10)
#define SS PB2      //chip select
#define MOSI PB3    //input
#define MISO PB4    //output
#define SCK PB5   //clock
#define SS_SET (PORTB|=(1<<SS))
#define SS_CLR (PORTB &= ~(1<<SS))
signed long PlusCounter=0;                         //脉冲计数器,用于计算从上电开始计算的相对脉冲个数
int lap=0;
unsigned char ss=0;
void delay(uint ms)
{
      uint i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
}
void port_init(void)
{
PORTB = 0xFF;
DDRB= 0xFF;
PORTC = 0xFF; //m103 output only
DDRC= 0xFF;
PORTD = 0xFF;
DDRD= 0xFF;
}
#pragma interrupt_handler int1_isr:iv_INT1//编码器程序,原打算发送它的
void int1_isr(void)
{   
    ChangeEdge;
   if((PIND&0X08)!=0)
       if((PINC&0X01)==0)
          {
               PlusCounter++;
                }
                else
          {
          PlusCounter--;
          }
    else
           if((PINC&0X01)!=0)
          {
               PlusCounter++;
                }
           else
          {
             PlusCounter--;
          }
}

#pragma interrupt_handler pcint1_isr:iv_PCINT1
void pcint1_isr(void)              //PCINT0中断服务函数
{   
   if((PINC&0X01)!=0)
       if((PIND&0X08)!=0)
          {
               PlusCounter++;
                }
                else
          {
          PlusCounter--;
          }
    else
           if((PIND&0X08)==0)
          {
               PlusCounter++;
                }
           else
          {
             PlusCounter--;
          //DispNum16(PlusCounter);
          }
}
void init_devices(void)
{
CLI(); //disable all interrupts
port_init();

MCUCR = 0x00;
EICRA = 0x08; //extended ext ints
EIMSK = 0x02;

TIMSK0 = 0x00; //timer 0 interrupt sources
TIMSK1 = 0x00; //timer 1 interrupt sources
TIMSK2 = 0x00; //timer 2 interrupt sources

PCMSK0 = 0x00; //pin change mask 0
PCMSK1 = 0x01; //pin change mask 1
PCMSK2 = 0x00; //pin change mask 2
PCICR = 0x02; //pin change enable
PRR = 0x00; //power controller
SEI(); //re-enable interrupts
}
void Spi_Transmit( char cData)
{
    // 启动数据发送
    SPDR = cData;
    // 等待发送完成
    while (!(SPSR & BIT(SPIF)));
    //return SPDR;
}

void main(void)
{   
        char i=0;
        init_devices();
        DDRB =(1<<MOSI)|(1<<SCK)|(1<<SS);
        DDRB &=~(1<<MISO);
        PORTB |= BIT(SS)|BIT(MISO);//主机空闲、带上拉
        SPCR = 0x53;
         SPSR = 0x00;

           while(1)
      {
          SS_CLR;
                Spi_Transmit(i);
                SS_SET;
                i++;
                if(i>50)
                   {
                     i=0;
                   }
               
          DispNum16(i);//SP027显示
          delay(1000);
           }
}
         16从机用串口再发送给电脑:
      #include <iom16v.h>                       
#include <macros.h>
#include "SP027DriverV2.h"
#defineuchar unsigned char
#defineuintunsigned int

#definemclk   8000000
#define SS PB4      //chip select
#define MOSI PB5    //input
#define MISO PB6    //output
#define SCK PB7   //clock
#define SS_SET (PORTB|=(1<<SS))
#define SS_CLR (PORTB &= ~(1<<SS))

#define ChangeEdge0MCUCR ^= BIT(ISC00)
#define ChangeEdge1MCUCR ^= BIT(ISC10)          
unsigned char ss;
long PlusCounter=0;
void delay(void)
{
      unsigned char i;
                for(i=0;i<255;i++);
}

void delay1(uint ms)
{
      uint i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
}
void port_init(void)
{
DDRA= 0xFF;
PORTA = 0xFF;
PORTB = 0xFF;
DDRB= 0xFF;
PORTC = 0xFF; //m103 output only
DDRC= 0xFF;
PORTD = 0xFF;
DDRD= 0x00;
}
void uart_init(uint baud)
{
    UCSRB=0x00;
   UCSRA=0x00;                   //控制寄存器清零
   UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0);   
                                                      //选择UCSRC,异步模式,禁止                        
                                                   //   校验,1位停止位,8位数据位
   baud=mclk/16/baud-1        ;   //波特率最大为65K
   UBRRL=baud;                                                        
   UBRRH=baud>>8;                    //设置波特率
   UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
                                                       //接收、发送使能,接收中断使能
   SREG|=BIT(7);                      //全局中断开放
   DDRD|=0X02;                      //配置TX为输出(很重要?

}
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
   ss=UDR;
}
void UART_Transmit(unsigned char ch_Data)
{
        while(!(UCSRA & (1<<UDRE)));
           //UCSRB &= ~(1<<TXB8);
           //if(ch_Data & 0x0100)
        //{
           //UCSRB |= (1<<TXB8);
        //}
           UDR = ch_Data;
}
void UART_Send_Int(signed long Data)
{       
        unsigned char ch_Temp = 0;
        unsigned char Temp_A_L;                                //必须为Unsignged                                               
        signed char Temp_A_H;
        signed char Temp_B_L;
        signed char Temp_B_H;
       
        Temp_A_L = Data;                               //发送第一个8位字节
        Temp_A_H = Data>>8;
        Temp_B_L = Data >> 16;
        Temp_B_H = Data >> 24;
       
        UART_Transmit(0xaa);                        //开始发送位
        UART_Transmit(0x09);
        UART_Transmit(0x01);
       
        ch_Temp ^= 0x09;                                //校验9位
        ch_Temp ^= 0x01;
        ch_Temp ^= Temp_B_H;
        ch_Temp ^= Temp_B_L;
        ch_Temp ^= Temp_A_H;
        ch_Temp ^= Temp_A_L;
       
        UART_Transmit(Temp_B_H);
        UART_Transmit(Temp_B_L);
        UART_Transmit(Temp_A_H);
        UART_Transmit(Temp_A_L);
        UART_Transmit(ch_Temp);
       
        UART_Transmit(0x55);                           //结束位
}

unsigned char SpiReadByte(void)
{
    PORTC ^= BIT(2);
        while(!( SPCR&BIT(SPIF) ))
        ;
    return SPDR;
}
void main(void)                                        
{
   signed char i;
   port_init();
   uart_init(38400);
   DDRB = BIT(MISO);
   DDRB &=~(BIT(MOSI)|BIT(SS)|BIT(SCK));
   DDRB |= BIT(1)|BIT(0);
   PORTB |=BIT(MOSI)|BIT(SS)|(SCK);//上拉
   
   SPCR = 0xC0;
   SPSR = 0x00;
   PORTC ^=BIT(2);

    while(1)
   {
           i = SpiReadByte();
              UART_Send_Int(i);
           DispNum16(i);//SP027显示
           delay1(10);
       }
}

Gorgon_Meducer 发表于 2009-11-19 21:42:10

感觉你做的东西和我之前作的一个东西很类似。
也是(编码器+SPI主) + (SPI从 +UART) 送给PC

这是一个使用了滑环的东西……你听说过《差分全向被动码盘定位系统》么?
突然看到SP027……我知道你在玩什么了……我以前的程序你手上没有么?

avrwj 发表于 2009-11-20 09:34:37

《差分全向被动码盘定位系统》没听说过,是不是双码盘定位啊,我这里有你以前的程序,但是这次我们负责人要求我用SPI进行32位通信,就如UART的32位那种通信,搞了好久都没出来,现在上面那个8位SPI发送已经解决了,下次把全部源文件传上来,请傻孩子师兄解决一下32位的SPI通信

Gorgon_Meducer 发表于 2009-11-20 13:01:41

我记得原来的程序就是32位的啊……
你要记住要点:要传输的数据类型并不重要(float, double, long 或者是结构体),关键是
你要搞懂指针……
建议你仔细研究我以前程序里面的一个宏的作用
TYPE_CONVERSION()

avrwj 发表于 2009-11-20 17:14:18

谢谢师兄了!我现在还是一个初学者,要弄懂的只是还很多啊,
页: [1]
查看完整版本: SPI 通信问题请教