搜索
bottom↓
回复: 4

SPI 通信问题请教

[复制链接]

出0入0汤圆

发表于 2009-11-18 22:43:44 | 显示全部楼层 |阅读模式
请教一下傻孩子师兄一个简单的问题:我用SPI的时候怎么不能同时显示:主机发送后,从机要复位才能接受一个数据呢?
        88主机发送:
            #include <iom88v.h>
#include <macros.h>
#define  uchar unsigned char
#define  uint  unsigned 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"
#define  uchar unsigned char
#define  uint  unsigned int

#define  mclk   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 ChangeEdge0  MCUCR ^= BIT(ISC00)
#define ChangeEdge1  MCUCR ^= 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);
         }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入296汤圆

发表于 2009-11-19 21:42:10 | 显示全部楼层
感觉你做的东西和我之前作的一个东西很类似。
也是(编码器+SPI主) + (SPI从 +UART) 送给PC

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

出0入0汤圆

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

出0入296汤圆

发表于 2009-11-20 13:01:41 | 显示全部楼层
我记得原来的程序就是32位的啊……
你要记住要点:要传输的数据类型并不重要(float, double, long 或者是结构体),关键是
你要搞懂指针……
建议你仔细研究我以前程序里面的一个宏的作用
TYPE_CONVERSION()

出0入0汤圆

 楼主| 发表于 2009-11-20 17:14:18 | 显示全部楼层
谢谢师兄了!我现在还是一个初学者,要弄懂的只是还很多啊,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 18:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表