原来AVR的SPI接口是这样啊,写了个DS1302的驱动
本帖最后由 no11xizhong 于 2012-10-15 10:51 编辑我想使用使用单片机读取DS1302的秒数据,
然后每隔一段时间向串口调试助手发送
也可以用串口调试助手向单片机发送秒数据
进行设置更改
使用51单片机端口模拟时序验证过是好用的
但不用端口模拟,使用AVR的SPI口好像有问题,
在MISO和MOSI引脚之间连接了一个100K的电阻,
以保证能够正确读数,程序很简单如下,求各路高手指点迷津
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ds1302.h"
#include "UART.h"
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_IN PINB
#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7//5V时候为2Mhz,2V时候为500Khz
#define SPI_CS 4
#define BAUD 9600
#define F_CPU 11059200
volatile unsigned char flag,redata,txdata; //没volatile貌似也行,全局变量,只放在main函数里不可
void Ds1302_Init()
{
SPI_DDR=(1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_CS);;//将MOSI CS SCK引脚配置为输出
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<DORD);////使能SPI LSB首先发送 主机模式时钟16分频
}
unsigned char Ds1302Byte_RW(unsigned char wdata)//读的时候随便写个wdata即可
{
SPDR=wdata;
loop_until_bit_is_set(SPSR,SPIF);//while(!(SPSR|(1<<SPIF)));
wdata=SPDR;//return(SPDR);
return wdata;
}
unsigned char Single_SPI(unsigned char cmd,unsigned char wdata)
{
unsigned char rdata;
SPI_PORT|=(1<<SPI_CS);
delay1us(10);
Ds1302Byte_RW(cmd);//写控制字
delay1us(10);
rdata=Ds1302Byte_RW(wdata);//读数据
SPI_PORT&=~(1<<SPI_CS);
delay1us(10);
return rdata;
}
void uartinit()
{
UBRRH=(F_CPU/16/BAUD-1)/256;
UBRRL=(F_CPU/16/BAUD-1)%256;
UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);////发送位数必须设置好
UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
}
void delay1ms(unsigned int x)
{
unsigned int i,j;
for (i=0;i<x;i++)
{
for (j=0;j<112;j++);
}
}
void delay1us(unsigned int x)
{
unsigned int i,j;
for (i=0;i<x;i++)
{
for (j=0;j<10;j++);
}
}
int main(void)
{
uartinit();
Ds1302_Init();
sei();
while(1)
{
delay1ms(1000);
txdata=Single_SPI(0x81,0x03);
UDR=txdata;
while(!(UCSRA&(1<<TXC)));
UCSRA|=(1<<TXC);//没写似乎影响也不大,清零TXC
}
}
SIGNAL(SIG_UART_RECV)
{
txdata=redata;
Single_SPI(0x8e,0x00);//开保护
Single_SPI(0x80,redata);//设置为20秒;
Single_SPI(0x8e,0x80);//关保护
} 请用过没用过AVR SPI接口的讨论
页:
[1]