查看: 44|回复: 2

[SAM4S] 原创atmel sam4s16c教程 之spi

[复制链接]

51

主题

1

好友

2856

积分

进士

Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    昨天 00:00
  • 签到天数: 496 天

    [LV.9]以坛为家II

    发表于 2016-11-17 14:35:31 |显示全部楼层
    仔细研究Datasheet中关于spi的部分
    框图见附图

    框图
    [url=][/url]




    最大的频率只能到达MCK(系统主时钟的6分频),假如单片机主频MCK120MSPI的速率最大也就是20M。在SAM4中有3SPI模块,分别是一个SPI,两个USART下的SPI模式,分别由USART0USART1产生。
    见附图
    SPI的四种模式如下图:这四种模式选择要根据你所要通信的器件所支持的方式而选择。
    见附图

    代码分这几部走:
    1)管脚的配置部分:把管脚设置为USART模式,代码如下:
    gpio_configure_pin(PIO_PA22_IDX,(PIO_PERIPH_A | PIO_DEFAULT));
    gpio_configure_pin(PIO_PA23_IDX,(PIO_PERIPH_A | PIO_DEFAULT));
    2USART_SPI的参数配置,代码如下:
    usart_spi_init(USART1);//初始化SPI,主要是使能USART的时钟
    //设置SPI的传输数据的模式和频率,这里我设置到最大20M,单片机的主频为120M
    usart_spi_setup_device(USART1,&USART_SPI_DEVICE_EXAMPLE,SPI_MODE_0, 20000000, 0);
    usart_spi_enable(USART1);//使能SPI
    oled的底层SPI驱动的修改:

    本项目的spi通讯有2个slave,eeprom和oled
    分别通过2个片选控制。

    代码如下:
    spi初始化
    void spi_master_initialize(void)
    {
            // Configure an SPI peripheral.
            spi_enable_clock(SPI);
            spi_disable(SPI);
            spi_reset(SPI);
            spi_set_lastxfer(SPI);
            spi_set_master_mode(SPI);
            spi_disable_mode_fault_detect(SPI);
            spi_set_peripheral_chip_select_value(SPI, SPI_CHIP_SEL);
            spi_set_clock_polarity(SPI, SPI_CHIP_SEL, SPI_CLK_POLARITY);
            spi_set_clock_phase(SPI, SPI_CHIP_SEL, SPI_CLK_PHASE);
            
            spi_set_bits_per_transfer(SPI, SPI_CHIP_SEL, SPI_CSR_BITS_12_BIT);  
            
            spi_set_baudrate_div(SPI, SPI_CHIP_SEL, 30);
            
            spi_set_transfer_delay(SPI, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT);
            
            
            spi_set_clock_polarity(SPI, SPI_CHIP1_SEL, 0);
            spi_set_clock_phase(SPI, SPI_CHIP1_SEL, 1);
            spi_set_bits_per_transfer(SPI, SPI_CHIP1_SEL, SPI_CSR_BITS_8_BIT);
            
            spi_set_baudrate_div(SPI, SPI_CHIP1_SEL, 120); //EEPROM工作在1MHz

            spi_set_transfer_delay(SPI, SPI_CHIP1_SEL, SPI_DLYBS, SPI_DLYBCT);
            
            spi_enable(SPI);
            spi_set_peripheral_chip_select_value(SPI, SPI_CHIP_SEL);
    }


    void spi_read1(Spi *p_spi, uint16_t *spi_data)
    {

            static uint32_t reg_value;

            reg_value = p_spi->SPI_RDR;

            *spi_data = (uint16_t) (reg_value & SPI_RDR_RD_Msk);

    }

    void write_data(uint8_t int_dat)  
    {
            uint16_t flag = 0x300;
            uint16_t switch_dat;
            
            switch_dat = flag + int_dat;
            switch_dat = switch_dat * 2;
            spi_master_transfer(&switch_dat,1);
            
    }

    关于分别用在oled和eeprom,有时间整理一下再放上
    回复

    使用道具 举报

    0

    主题

    0

    好友

    -177

    积分

    禁止发言

  • TA的每日心情
    开心
    2016-11-18 09:31
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-11-18 15:02:57 |显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复

    使用道具 举报

    -1

    主题

    0

    好友

    -50

    积分

    禁止发言

  • TA的每日心情
    奋斗
    2016-11-18 10:59
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-11-18 15:05:33 |显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /6 下一条


    手机版|爱板网 |网站地图  

    GMT+8, 2016-12-5 06:22 , Processed in 0.201855 second(s), 13 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部