no11xizhong 发表于 2012-10-15 10:45:08

原来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);//关保护

}

no11xizhong 发表于 2012-10-15 10:52:42

请用过没用过AVR SPI接口的讨论
页: [1]
查看完整版本: 原来AVR的SPI接口是这样啊,写了个DS1302的驱动