==================================================
难道楼主是:《AVR单片机原理及测控工程应用》的作者??
《AVR单片机原理及测控工程应用》78 页
2.4.5两个AVR实现硬件SPI双机通信
例程中,将要发送的数据加载到发送缓冲区的函数fill_tx_buffer
和从接收缓冲区读出数据的函数read_rx_buffer未给出, 根据各自需求请自己完成。
==============================================================================
#define SS 4
#define MOIS 5
#define MISO 6
#define SCK 7
#define SPI_RX_BUFFER_SIZE10
#define SPI_RX_BUFFER_MASK(SPI_RX_BUFFER_SIZE-1)
#define SPI_TX_BUFFER_SIZE10
#define SPI_TX_BUFFER_MASK(SPI_TX_BUFFER_SIZE-1)
#define PIN_SS_L {PINB&(~BIT(SS))}
unsigned char SPI_RxBuf;
volatile unsigned char SPI_RxHead = 0;
unsigned char SPI_TxBuf;
volatile unsigned char SPI_TxHead = 0;
volatileunsigned char Spi_Trans_Com = 0;//接收完成标志
volatileunsigned char Spi_Mode = 0; //接收或者发送状态标志
volatileunsigned char Spi_Sending = 0;//正在发送标志
void Init_Spi(void)
{
SPCP = BIT(SPE)|BIT(MSTR);//初始化为主机方式
SPI_TxHead = 0;
SPI_RxHead = 0;
}
void Spi_Send(void)
{
if (Spi_Sending == 0)//发送中标志为0,表明SPI发送空闲
{
Fill_Tx_Buffer();//调用Fill_Tx_Buffer()函数,将要发送的数据加载到发送缓冲区
while (PIN_SS_L==0);//ss为低,总线被接受方式占用,等待接收方式发送
Init_Spi();//初始化为主机方式
DDRB|=BIT(SS)|BIT(MOIS)|BIT(MISO);
PORTB &= ~BIT(SS);//降SS拉低强迫接收方进入接收方式
Spi_Mode = 1;
_delay_us(10);
Spi_Sending = 1;
SPDR = 0XFF;
SPCR |= 1<<SPIE; //开SPI中断
SPI_TxHead = 0;//已发送数据计数器清零
}
}
//一个字节发送或接收完成中断
SIGNAL(SIG_SPI)
{
unsigned char data = 0;
if (Spi_Mode == 0)//如果Spi_Mode = 0为0,表明是接收状态
{
data = SPDR; //读取接收到的数据
SPI_RxBuf =data;//降接收到的数据存入接收缓冲区
if (SPI_RxHead==SPI_RX_BUFFER_MASK)//如果是接收帧的最后一个数
{
SPI_RxHead = 0;//已接收数据还原
SPCR |= 1<<MSTR; //接收完成,将SPI设置成主方式
Spi_Trans_Com = 1;//设置接收完成标志
}
else
{
SPI_RxHead++;//已发送计数器加一
}
}
else //如果是Spi_Mode = 1,表明是发送状态
{
if (SPI_TxHead<=SPI_TX_BUFFER_MASK)
{
SPDR = SPI_TxBuf;
SPI_TxHead++;
}
else
{
SPI_TxHead = 0; //已发送数据计数器还原
DDRB &= ~BIT(SS);
PORTB |=BIT(SS); //释放总线以接收方式进入主发送
Spi_Mode = 0; //进入接收状态
Spi_Sending = 0;//清空发送中标志
}
}
} 记号 刚学。。不是很清楚、、先谢了!! 回romanticye:
我不是写那本书的人.请看一下我发这个贴的日期:2005-01-05,16:13:55 ,我不知道《AVR单片机原理及测控工程应用》是什么时候出版的,但我可以肯定不会早过发贴的日期.
《AVR单片机原理及测控工程应用》作者是哪位? LZ你好!这是主从都可以用的程序?
请问M16可以套用你这个程序吗?
好像都差不多,只要加个头文件就可以? 是的,主从都用这个程序,基本适合所有AVR.
92楼有一个实例.
顶楼的代码通讯中如有一方复位将导致以后一直出错,92楼的就没有这个问题了. 不错,顶一下, 好东东,顶 顶一下,好贴! 我这有一本《AVR单片机原理及测控工程应用》--基于mega48/mega16 刘海成编著
上面的SPI代码和楼主的一模一样
不知道是不是一个人 那本書是08年出的,而lz的是05年,我感覺是lz本人的原創 不错 好东西正在做谢谢! 收藏 mark1 mark1 好東西,頂頂!!! mark 看了樓主92樓的程序, 有點暈, 不知道如何執行,流程?
知道,看得懂的請說一下...
while (1)
{
if(spi_trans_com==1)
read_rx_buffer();
if(send_failure==1)
spi_send();
};
都沒看到哪個機子發送初始數據, 究竟主從是入何操作數據?(發送,接收) ,沒看到有誰開始 發數據......... 好难 ding 谢谢分享! 谢谢分享! 好贴,正在学习中。。。 mark mark 顶你格非 9494 狂挺你 mark mark 收藏先 mark mark MARK mark 不错。 mark mark 好贴,实用性很强,谢谢Paul 不错! ding 有没有51的SPI的 有个问题:
就是如果主从机都用那个代码那怎么定义SS脚呢连接的主从机不是电平一样吗??
while(PINB.4==0) //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
{;}
这句怎么初始化理解?? 回复【楼主位】Paul
-----------------------------------------------------------------------
dddddddddddddd 有个问题:
就是如果主从机都用那个代码那怎么定义SS脚呢连接的主从机不是电平一样吗??
while(PINB.4==0) //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
{;}
这句怎么初始化理解??
急急急急急!!!!!!!!! 没有通讯时两个都是一样的都在主模式,SS都是输入上拉,任何一方想发就把SS设为输出并拉低,这样另一方就进入从模式了。看看AVR的手册,讲的很明白的。 mark! mark M mark好贴! 我的意思是两通信机 的SS脚连在一起自然他的电平就是一样的啊读取PINA.4的时候怎么去分辨主从机呢???
高手指点???????? 谢谢分享~ 有个问题:
就是如果主从机都用那个代码
while(PINB.4==0) //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
{;}
那怎么定义SS脚呢连接的主从机不是电平一样吗??
怎么初始化理解?? 怎么就没人回答呢
俺比较菜啊
高手指点下啊
急急急急急!!!!!!!!! mark 记号 回复【171楼】wulong
-----------------------------------------------------------------------
其实你和我想法一样的,,我也不太明白。。其实按道理说主从机的SS线是连到一起的,那么电平应该是一样的才对啊。。(本人没有用过AVR硬件SPI。。呵呵。。今天研究了一下,所以又点不太明白) mark mark 学习 mark 写得不错 mark 有年头的贴子! 好,MARK mark 学习了 顶! 回复【92楼】Paul
-----------------------------------------------------------------------
有个问题不太明白:
在 read_rx_buffer()函数中,以下两句代码:
DDRB.2=1;
SET_SPI_BUS_MODE=0; //处理数据中,禁止发送方发送
如此,发送方岂不是一下子变为从机?而且进入了一次SPI中断?那进入中断后的数据(无效数据)怎么处理? 学习中,谢谢楼主的无私奉献! 学习 看看 谢谢楼主分享 我写STM32与FPGA通信都10天了 数据总数不全正确希望能在这里找到错误 楼主有没有用单片机的SPI结合CH432T芯片来扩展串口呢?我最近在做这个,但是网上很少有这方面的例程,搞得我无从下手
页:
1
[2]