基于GCCAVR的模拟SPI程序

简介:

AVR的SPI接口很多只有一个,如果驱动较多的以SPI接口的外设时就必须通过IO来模拟,实际上对于低速外设来说IO模拟的方式也很方便,网上关于模拟SPI的程序很多,我的程序是基于GCCAVR来写的,其他编译器的都类似,写的时候我尽量做到规范和方便后期使用时改动调整。

 

使用时需要注意以下几点:

1、根据外设的时序要求,区分是在上升沿更新数据还是下降沿。

2、发送数据时高位在前还是地位在前。

3、外设对SPI通信有无速度要求,有些时候过快的通信速率可能无法读取和写入数据

4、CLK,数据等引脚的平时电平

上面几点只要对照着外设的时序图一眼就能弄清楚,程序里面写的很清楚相应的改动一下就可以了。

程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**************************(C) COPYRIGHT emouse 2011***************************
名称:main.c
功能:模拟SPI程序测试
作者:emouse
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
#include"avr/io.h"
#include"avr/interrupt.h"
#include"util/delay.h"
  
#define SetBit(Port,N)  (Port|=(1<<N))    //设置IO某一位
#define ClrBit(Port,N)  (Port&=~(1<<N))   //清空IO某一位
#define ReverBit(Port,N)  (Port^=(1<<N))   //取反IO某一位
#define GetBit(Pin,N)   ((Pin>>N)&0x01)   //读取IO某一位
/***************模拟SPI的相关宏定义********************/
#define SPI1_Port PORTC     //设置使用的端口
#define SPI1_DDR DDRC
#define SPI1_PIN PINC
#define SPI1_CS 0           //设置每个信号对应的引脚
#define SPI1_MISO 1
#define SPI1_MOSI 2
#define SPI1_CLK 3
#define SPI1_CS_H (SPI1_Port|=(1<<SPI1_CS))
#define SPI1_CS_L (SPI1_Port&=~(1<<SPI1_CS))
#define SPI1_GetMISO ((SPI1_PIN>>SPI1_MISO)&0x01)
#define SPI1_MOSI_H (SPI1_Port|=(1<<SPI1_MOSI))
#define SPI1_MOSI_L (SPI1_Port&=~(1<<SPI1_MOSI))
#define SPI1_CLK_H (SPI1_Port|=(1<<SPI1_CLK))
#define SPI1_CLK_L (SPI1_Port&=~(1<<SPI1_CLK))
unsigned  char  spi_delay;     //设置信号的持续时间,相当于设置SPI的速度
/*******************************************************************************
名称:void SPI1_Init()
功能:模拟SPI时序的端口初始化工作
参数:无
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
void  SPI1_Init()
{
     SPI1_Port|=((1<<SPI1_CS)|(1<<SPI1_MISO)|(1<<SPI1_MOSI)|(1<<SPI1_CLK));
     SPI1_DDR|=(((1<<SPI1_CS)|(1<<SPI1_MOSI)|(1<<SPI1_CLK))&(~(1<<SPI1_MISO)));
     SPI1_CS_H;
     SPI1_CLK_L;
     spi_delay=5;
}
/*******************************************************************************
名称:SPI1_Send(unsigned char data)
功能:发送SPI数据
参数:unsigned char data
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
void  SPI1_Send(unsigned  char  data)
{
     unsigned  char  i;
     SPI1_CS_L;       //拉低片选信号
     SPI1_CLK_L;      //时钟空闲时为低电平
     SPI1_MOSI_L;
     _delay_us(spi_delay);
     for (i=0;i<8;i++)
     {
         if (data&(0x80>>i)) //高位在前,低位在前改为(0x01<<i)
             SPI1_MOSI_H;
         else
             SPI1_MOSI_L;
         _delay_us(spi_delay);
         SPI1_CLK_H;      //在上升沿更新数据
         _delay_us(spi_delay);
         SPI1_CLK_L;
     }
     _delay_us(spi_delay);
     SPI1_CS_H;       //拉高片选,完成一次数据传输
}
/*******************************************************************************
名称:unsigned char SPI1_Get()
功能:接收SPI数据
参数:返回data
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
unsigned  char  SPI1_Get()
{
     unsigned  char  i;
     unsigned  char  data=0x00;
     SPI1_CS_L;       //拉低片选信号
     SPI1_CLK_L;      //时钟空闲时为低电平
     SPI1_MOSI_L;
     _delay_us(spi_delay);
     for (i=0;i<8;i++)
     {
         if (SPI1_GetMISO)
             data|=(0x80>>i);
         _delay_us(spi_delay);
         SPI1_CLK_H;      //在上升沿更新数据
         _delay_us(spi_delay);
         SPI1_CLK_L;
     }
     _delay_us(spi_delay);
     SPI1_CS_H;       //拉高片选,完成一次数据传输
     return  data;
}
/*******************************************************************************
名称:void USART0_Init(void)
功能:串口0初始化
参数:无
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
void  USART0_Init( void )
{
UCSR0A=0x20;  //波特率不加倍,单机通信模式
UCSR0B=0x18;  //中断不使能,允许发送和接收
UCSR0C=0x06; //异步模式,无校验,8位数据,1位停止位
UBRR0H=0x00;
UBRR0L=51; //9600波特率   晶振8M
}
/*******************************************************************************
名称:void USART0_Putc(unsigned char c)
功能:发送一个字符
参数:unsigned char c
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
void  USART0_Putc(unsigned  char  c)
{
     while (!(UCSR0A&(1<<UDRE0)));   //等待发送缓冲空
     UDR0=c;     //发送数据
}
/*******************************************************************************
名称:void USART0_Puts(unsigned char * str)
功能:发送字符串
参数:unsigned char * str 待发送的字符串
时间:2011.1.11
版本:1.0
注意:无
*******************************************************************************/
void  USART0_Puts(unsigned  char  * str)
{
     while (*str)
     {
         USART0_Putc(*str++);
     }
}
int  main( void )
{   
     unsigned  char  i=0;
     USART0_Init();   //初始化USART0接口  
     DDRA=0XFF;
     PORTA=0XFF;
     SPI1_Init();
     USART0_Puts( "SPI test" );
     while (1)
     {     
         SPI1_Send(0x04);
         USART0_Putc(SPI1_Get());
         ReverBit(PORTA,0);
         _delay_ms(500);        
     }
}

  本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2011/01/11/2198186.html,如需转载请自行联系原作者

相关文章
|
5月前
|
传感器 Linux API
如何实现 MCU软件中多个模块初始化函数的优雅调用
如何实现 MCU软件中多个模块初始化函数的优雅调用
|
4月前
单片机IO口模拟串口实现原理
单片机IO口模拟串口实现原理
45 5
【STM32】详解独立看门狗的本质和使用步骤&代码
【STM32】详解独立看门狗的本质和使用步骤&代码
|
5月前
|
Perl
【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例
【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例
448 0
|
内存技术
如何看懂时序图(以SPI/I2C为例)
如何看懂时序图(以SPI/I2C为例)
164 1
Linux驱动分析之SPI控制器
之前对SPI驱动的整体架构做了介绍,现在来分析具体的驱动程序。之前说过,SPI驱动分为设备驱动和控制器驱动。先来分析控制器驱动。我们以RockChip的控制器来作为分析。
|
Linux 芯片
Linux驱动分析之SPI设备
前面我们对SPI控制器驱动进行了分析,接下来来分析SPI设备驱动。我们以DS1302驱动作为分析对象。DS1302是一款RTC芯片,估计很多人在学单片机时用到过。RTC芯片算是比较简单的,也方便分析理解。
Linux驱动分析之SPI设备
|
芯片
LED驱动程序外部框架
LED驱动程序外部框架
68 0
|
芯片
【STC15单片机】初始化程序原理
【STC15单片机】初始化程序原理
257 0
UART子系统(八)UART驱动情景分析_注册
UART子系统(八)UART驱动情景分析_注册
71 1
UART子系统(八)UART驱动情景分析_注册