发帖 |
[资料] 原创atmel sam4s16c教程 之spi
2016-10-20 17:09:32  1936
收藏 0 收藏 推荐 0 推荐
分享
本帖最后由 lee_st 于 2016-10-21 11:35 编辑

按项目的要求,在原有的基础上增加了定时器功能
仔细研究Datasheet中关于spi的部分

框图见附图





最大的频率只能到达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,有时间整理一下再放上








框图

框图
· 2016-11-9 15:38:37
SPI_CHIP_SEL是什么
· 2016-11-10 08:55:36
片选,,,,,,,,,
· 2016-11-10 09:28:59
一般宏定义都能直接看懂是什么
· 2016-11-15 00:24:48
也被推荐了,谢谢

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

发资料
关闭

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

快速回复 返回顶部 返回列表