通过手册找到的资料,实际应用了一下,
编译环境:AVR-GCC(WINAVR)
M16+8M晶振
SPI.C
#include <avr/io.h> //IO库
#include <avr/interrupt.h> //中断
#include <util/delay.h> //延时
#include "SPI.h"
//数码管 0 1 2 3 4 5 6 7 8 9 A B C D E F
uchar num[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
#define DOT 0x80 //小数点位置
#define DELAYTIME 1 //数码管显示延时时间
#define SPEEDTIME 1000 //定时时间ms
int count=0;
int count1=0;
int n=0;
void init()
{
DDRB = 0xFF;
DDRD = 0xFF;
//定时器0
TCCR0 |= BIT(CS01)|BIT(CS00); //8分频
TCNT0 = 0x7D; //1ms
TIMSK |= BIT(TOIE0); //溢出使能中断
}
int main()
{
init();
SPI_MasterInit();
sei();
while(1)
{
int ge,shi,bai,qian,wan;
wan = n/10000;
qian = n/1000 - wan*10;
bai = n/100 - qian*10 - wan*100;
shi = n/10 - bai*10 - qian*100 - wan*1000;
ge = n%10;
Send595(num[ge]);
PORTD = ~BIT(7);
_delay_ms(DELAYTIME);
if(n>9)
{
Send595(num[shi]);
PORTD = ~BIT(6);
_delay_ms(DELAYTIME);
}
if(n>99)
{
Send595(num[bai]);
PORTD = ~BIT(5);
_delay_ms(DELAYTIME);
}
if(n>999)
{
Send595(num[qian]);
PORTD = ~BIT(4);
_delay_ms(DELAYTIME);
}
if(n>9999)
{
Send595(num[wan]);
PORTD = ~BIT(3);
_delay_ms(DELAYTIME);
}
}
return 0;
}
ISR(TIMER0_OVF_vect) //定时器0中断
{
if(count>=SPEEDTIME)
{
count=0;
n++;
}
else
count++;
TCNT0 = 0x7D; //重装数值
}
SPI.h
void SPI_MasterInit() //初始化SPI
{
//MOSI与SCK为输出模式
DDRB |= BIT(5)|BIT(6);
//SEP : 使能SPI
//MSTR: 主机模式
//SPR1 = 0 , SPR0 = 1 为1/16频率 12M/16 = 750Kbps
SPCR |= BIT(SPE)|BIT(MSTR)|BIT(SPR0);
}
void SPI_SendData(char data)
{
SPDR = data; //传输数据
//发送结束后SPIF置位
while( ! (SPSR & BIT(SPIF)) );
}
void Send595(char db)
{
PORTB &= ~BIT(4); //RCK为低,等待数据
SPI_SendData(db);
PORTB |= BIT(4); //RCK为高,输出数据
}