lee_avr 发表于 2009-7-11 17:24:20

AVR用IO模拟SPI时序,读取寄存器问题

主要表现为读出来的STATUS和寄存器的数据都是0xFF 不知道哪里的问题 希望大侠给指点指点
CPU是Mega16L晶振12MHz



#include "global.h"
#include "lcd.h"

//#################################################################################################
//nRF24L01 Interface
//#################################################################################################
#define NRF_DDR                                                DDRA
#define NRF_PORT                                        PORTA
#define NRF_PIN                                                PINA

#define NRF_CE                                                3                //output
#define NRF_CSN                                                0                //output
#define NRF_SCK                                                4                //output
#define NRF_MOSI                                        1                //output
#define NRF_MISO                                        5                //input
#define NRF_IRQ                                                2                //input
//#################################################################################################
//SPI Commands
//#################################################################################################
#define NRF_READ_REG                                0x00        //000A AAAA                Read command and status registers.
#define NRF_WRITE_REG                                0x20        //001A AAAA                Write command and status registers.
#define NRF_R_RX_PAYLOAD                        0x61        //0110 0001                Read RX-payload: 1~32 bytes.
#define NRF_W_TX_PAYLOAD                        0xA0        //1010 0000                Write TX-payload: 1~32 bytes.
#define NRF_FLUSH_TX                                0xE1        //1110 0001                Flush TX FIFO, used in TX mode
#define NRF_FLUSH_RX                                0xE2        //1110 0010                Flush RX FIFO, used in RX mode
#define NRF_REUSE_TX_PL                                0xE3        //1110 0011                Used for a PTX device Reuse last transmitted payload.
#define NRF_ACTIVATE                                0x50        //0101 0000
#define NRF_NOP                                                0xFF        //1111 1111
//#################################################################################################
//SPI Registers
//#################################################################################################
#define NRF_CONFIG                                        0x00
#define NRF_EN_AA                                        0x01
#define NRF_EN_RXADDR                                0x02
#define NRF_SETUP_AW                                0x03
#define NRF_SETUP_RETR                                0x04
#define NRF_RF_CH                                        0x05
#define NRF_RF_SETUP                                0x06
#define NRF_STATUS                                        0x07
#define NRF_OBSERVE_TX                                0x08
#define NRF_RPD                                                0x09
#define NRF_RX_ADDR_P0                                0x0A
#define NRF_RX_ADDR_P1                                0x0B
#define NRF_RX_ADDR_P2                                0x0C
#define NRF_RX_ADDR_P3                                0x0D
#define NRF_RX_ADDR_P4                                0x0E
#define NRF_RX_ADDR_P5                                0x0F
#define NRF_TX_ADDR                                        0x10
#define NRF_RX_PW_P0                                0x11
#define NRF_RX_PW_P1                                0x12
#define NRF_RX_PW_P2                                0x13
#define NRF_RX_PW_P3                                0x14
#define NRF_RX_PW_P4                                0x15
#define NRF_RX_PW_P5                                0x16
#define NRF_FIFO_STATUS                                0x17
//#################################################################################################
//Functions
//#################################################################################################
void nrf_init(void);
void nrf_select(void);
void nrf_unselect(void);
unsigned char nrf_spi_cmd(unsigned char cmd);
void nrf_spi_read(unsigned char * data, unsigned char len);
void nrf_spi_write(unsigned char * data, unsigned char len);
//#################################################################################################
//#################################################################################################
void nrf_init(void)
{
        NRF_DDR |= ( _BV(NRF_CE)|_BV(NRF_CSN)|_BV(NRF_SCK)|_BV(NRF_MOSI) );
        NRF_DDR &= ~( _BV(NRF_MISO)|_BV(NRF_IRQ) );
        NRF_PORT |= ( _BV(NRF_MISO)|_BV(NRF_IRQ) );
}
//#################################################################################################
//#################################################################################################
void nrf_select(void)
{
        CBIT(NRF_PORT, NRF_CSN);                //CSN = 0
        delay_us(10);
}
//#################################################################################################
//#################################################################################################
void nrf_unselect(void)
{
        SBIT(NRF_PORT, NRF_CSN);                //CSN = 1
        delay_us(10);
}
//#################################################################################################
//#################################################################################################
unsigned char nrf_spi_cmd(unsigned char cmd)
{
        CBIT(NRF_PORT, NRF_SCK);                                //SCK = 0
        delay_us(10);
        for (unsigned char i=0; i<8; i++)
        {
                if ( cmd & 0x80 )
                        SBIT(NRF_PORT, NRF_MOSI);                //MOSI = 1
                else
                        CBIT(NRF_PORT, NRF_MOSI);                //MOSI = 0
                cmd = cmd<<1;
                delay_us(2);
                SBIT(NRF_PORT, NRF_SCK);                        //SCK = 1
                delay_us(2);
                if ( NRF_PIN & _BV(NRF_MISO) )
                        cmd |= 0x01;
                else
                        cmd &= 0xFE;
                CBIT(NRF_PORT, NRF_SCK);                        //SCK = 0
                delay_us(10);
        }
        return cmd;
}
//#################################################################################################
//#################################################################################################
void nrf_spi_read(unsigned char * data, unsigned char len)
{
        CBIT(NRF_PORT, NRF_SCK);                                        //SCK = 0
        delay_us(10);
        for (unsigned char i=0; i<len; i++)
        {
                unsigned char n = 0x00;
                for (unsigned char j=0; j<8; j++)
                {
                        n = n<<1;
                        SBIT(NRF_PORT, NRF_SCK);                        //SCK = 1
                        delay_us(2);
                        if ( NRF_PIN & _BV(NRF_MISO) )
                                n |= 0x01;
                        else
                                n &= 0xFE;
                        CBIT(NRF_PORT, NRF_SCK);                        //SCK = 0
                        delay_us(2);
                }
                * (data+i) = n;
        }
}
//#################################################################################################
//#################################################################################################
void nrf_spi_write(unsigned char * data, unsigned char len)
{
        for (unsigned char i=0; i<len; i++)
        {
                unsigned char n = *(data+i);
                for (unsigned char j=0; j<8; j++)
                {
                        if ( n & 0x80 )
                                SBIT(NRF_PORT, NRF_MOSI);                //MOSI = 1
                        else
                                CBIT(NRF_PORT, NRF_MOSI);                //MOSI = 0
                        n = n<<1;
                        SBIT(NRF_PORT, NRF_SCK);                        //SCK = 1
                        delay_us(10);
                        CBIT(NRF_PORT, NRF_SCK);                        //SCK = 0
                        delay_us(10);
                }
        }
}
//#################################################################################################
//主函数
//#################################################################################################
int main(void)
{
        lcd_init();
        lcd_clear();
        nrf_init();
        unsigned char status = 0;
        unsigned char data;
        while (1)
        {
                //-------------------------------------------------------------------------------
                nrf_select();
                status = nrf_spi_cmd(NRF_READ_REG|NRF_CONFIG);
                nrf_spi_read(data, 1);
                nrf_unselect();
                lcd_view_data(0, 0, &status, 1);
                lcd_print_string(4, 0, "CONFIG");
                lcd_view_data(0, 1, data, 1);
                delay_ms(500);
                //-------------------------------------------------------------------------------

        }
}
//#################################################################################################

lee_avr 发表于 2009-7-13 09:05:16

程序无问题,24L01 ic虚焊
手压着可以读出来寄存器数据 松开一会就不行了。。。
结果尝试着吹下, 结果吹飞了, 请教QFN怎么焊接?

hztour 发表于 2009-7-13 09:54:08

呵呵,焊接还得请教高手,虽然我也焊,也能用,但水平实在不敢来这里炫,^_^

aaron96031 发表于 2010-1-12 16:55:14

mark

clarepeng 发表于 2011-8-29 12:18:25

./emotion/em001.gif......

lixc2008 发表于 2011-10-2 20:33:01

今天收缩看到此贴。
想问下,MEGA16L支持12M时钟吗?L系列的最高支持到8M外部时钟

40560335 发表于 2011-10-2 21:14:41

告诉你个小秘密,什么1117啊、7805啊之类的出来的纹波那是相当的大,最好加个0.1或者10uf的电容,我当初就是忽略了这点,导致我的1101、2401间间断断长达8个月才调通了,一直以为是程序的问题,后来发现纹波会严重影响这类模块的正常工作!~
页: [1]
查看完整版本: AVR用IO模拟SPI时序,读取寄存器问题