嘿 趁在回去吃饭前 总结一下基于AVR的SPI 功能实现 就先简单说一下SPI是什么吧 它是一个串行外部接口 允许AVR 与外部接口进行高速的同步数据传输 现在为了配合实现SPI功能 让它接上移位寄存器747HC595 这样通过595直接驱动4位7段共阴数码管显示
具体的接口安排如下 MOSI接595的串口数据输入端D 即14脚 SCK接595的时钟信号端CLK 即11脚 PB4接595的数据控制端 即12脚
代码实现如下:
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
uchar diap[ ] = { 0xC0, 0xF9, 0xA4,0xb0,0x99,0x82,0xF8,0x80,0x90} ;
//延时子函数
void DelayMs ( uchar i)
{
uchar j ;
while ( i--) ;
{
j=167; //1MHZ 1ms延时
while ( j--) ;
}
}
//SPI初始化为主机
/*SPI控制寄存器
SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
SPIE 中断使能 SPE SPI使能 DORD 数据次序 1为LSB首先发送,0为MSB首先发送
MSTR 主从选择 1为主,0为从MSTR置位时选择主机模式,否则为从机.如果MSTR为"1",
SS配置为输入,但被拉低,则MSTR 被清零,寄存器SPSR 的SPIF 置位.用户必须重新设置
MSTR 进入主机模式。
CPOL: 时钟极性见ATMEGA16L(中文)P130
CPHA: 时钟相位
SPR1, SPR0: SPI 时钟速率选择1 与0 SPR1 和SPR0 对从机没有影响。
使能SPI 主机模式,设置时钟速率为fck/128 */
void SPIMasterInit ( void )
{
DDRB |= (1<<PB5) | (1<<PB7);
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);
}
//SPI数据发送
void SPIMasterTransmit ( uchar TranData)
{
SPDR = TranData ; //启动数据传输
while ( !( SPSR & ( 1<< SPIF ) ) ) ; // 等待数据传输结束
}
//595的输出显示
void SPI595out ( uchar i )
{
PORTB &= ~ ( 1<<4 ) ; //准备锁存数据
SPIMasterTranmit ( i ) ;
PORTB |= ( 1<< 4 ) ; /*锁存数据*/ 即是把595中移位寄存器中的数放到数据寄存器中*/
}
//主函数
void main ( void )
{
uchar i ;
DDRB = 0xFF; /*方向输出*/
PORTB = 0xF0; /*电平设置*/
SPImasterInit ( ) ;
while ( 1 )
{
i++ ;
if ( i > 9) i =0 ;
DelayMs ( 250 ) ;
DelayMs ( 250 ) ;
SPI595out ( diap[ i ]) ;
}
}