S3C6410 SPI 裸机驱动

发布者:Haifeeng最新更新时间:2017-02-26 来源: eefocus关键字:S3C6410  SPI  裸机驱动 手机看文章 扫描二维码
随时随地手机看文章

刚刚写的SPI驱动,想移植到LINUX上面用来读写SD卡

只测试了发送,没有测试接收.


spi.c


  1. /************************************************************************************************************* 

  2.  * 文件名: spi.c 

  3.  * 功能:      S3C6410 SPI底层驱动函数 

  4.  * 作者:      陈鹏 

  5.  * 创建时间:    2012年9月8日20:35 

  6.  * 最后修改时间:2012年9月8日 

  7.  * 详细:      SPI始化,发送,接收,配置等 

  8.  *          使用的是手动控制片选,因为在实际使用过程中手动控制片选较为灵活,但是也有个问题,就是何时取消片选,应为数据写入到发送FIFO并 

  9.  *          不代表数据已经发送完成了,如果在数据没有发送完成之前取消了片选会导致数据传输错误,因此简单的方法就是在发送数据后加入一定 

  10.  *          的延时,让数据发送完成后取消片选 

  11. *************************************************************************************************************/  

  12. #include "system.h"  

  13. #include "spi.h"  

  14. #include "delay.h"  

  15.   

  16. //SPI通道数量  

  17. #define SPI_CH_N    2  

  18. //SPI外设结构  

  19. const SPI_TypeDef *SPI_CH[SPI_CH_N] = {SPI0,SPI1};  

  20.   

  21. //默认模式1  

  22. //主设备模式,空闲时钟低电平,第一个时钟边沿有效(上升沿有效),使能发送接收,数据宽度8bit,关闭DMA,使能手动控制片选  

  23. const SPI_Config_TypeDef SPI_DEFAULT_01 = {0,0,0,1,1,8,0,0,0,0};  

  24.   

  25.   

  26. /************************************************************************************************************************* 

  27. *函数    :    void SPI_SetSpeed(u8 ch,u8 Speed) 

  28. *功能    :    设置SPI速度 

  29. *参数    :    CH:SPI通道选择;Speed:SPI速度设置 

  30. *返回    :    无 

  31. *依赖 :   底层宏定义 

  32. *作者     :   cp1300@139.com 

  33. *时间     :   20121005 

  34. *最后修改时间:    20121005 

  35. *说明     :   修改的时候注意SPI应该处于空闲或者无效状态,使用的时钟是PCLK 

  36. *           SPI 时钟输出 = 时钟源 / ( 2 ×(预分频值 +1)) 

  37. *************************************************************************************************************************/  

  38. void SPI_SetSpeed(u8 ch,u8 Speed)  

  39. {  

  40.     SPI_TypeDef *SPI;  

  41.           

  42.     if(ch >= SPI_CH_N)  

  43.         return;         //通道号超出范围  

  44.     SPI = (SPI_TypeDef *)SPI_CH[ch];    //获取对应通道寄存器结构指针  

  45.     SPI->CLKCFG = 0; //清空设置并关闭时钟  

  46.     SPI->CLKCFG = Speed;//设置预分频值  

  47.     SPI->CLKCFG |= BIT8;//使能时钟  

  48. }  

  49.   

  50.   

  51. /************************************************************************************************************************* 

  52. *函数    :    u8 SPI_Init(u8 ch,SPI_Config_TypeDef *config,u8 Speed) 

  53. *功能    :    SPI初始化 

  54. *参数    :    CH:SPI通道选择;config:配置结构指针;Speed:SPI速度设置 

  55. *返回    :    0:初始化成功;1:初始化失败 

  56. *依赖 :   底层宏定义 

  57. *作者     :   cp1300@139.com 

  58. *时间     :   20121005 

  59. *最后修改时间:    20121005 

  60. *说明     :   无 

  61. *************************************************************************************************************************/  

  62. u8 SPI_Init(u8 ch,const SPI_Config_TypeDef *config,u8 Speed)  

  63. {  

  64.     u32 chcfg = 0;  

  65.     u32 modcfg = 0;  

  66.     u32 slavecfg = 0;  

  67.     SPI_TypeDef *SPI;  

  68.       

  69.     if(ch >= SPI_CH_N)  

  70.         return 1;       //通道号超出范围  

  71.     SPI = (SPI_TypeDef *)SPI_CH[ch];        //获取对应通道寄存器结构指针  

  72.       

  73.     SPI->CHCFG |= BIT5;  //SPI软复位  

  74.     Delay_US(10);       //适当延时  

  75.     switch(ch)  

  76.     {  

  77.         case 0: //通道0  

  78.         {  

  79.             Set_GateClk(PCLK_SPI0,ENABLE);  //使能SPI0门控时钟  

  80.             rGPCCON &= ~0xfff;  

  81.             rGPCCON |= 0x222;               //初始化SPI0 MISO CLK MOSI 相关IO  

  82.         }break;  

  83.         case 1: //通道1  

  84.         {  

  85.             Set_GateClk(PCLK_SPI1,ENABLE);  //使能SPI1门控时钟  

  86.             rGPCCON &= ~(0xfff << 16);  

  87.             rGPCCON |= (0x222 << 16);     //初始化SPI1 MISO CLK MOSI 相关IO  

  88.         }break;  

  89.         default:break;  

  90.     }  

  91.       

  92.     SPI->CLKCFG &= ~BIT8;    //关闭SPI时钟  

  93.     SPI->CHCFG = 0;      //清除设置并关闭SPI发送接收通道  

  94.     if(config->EnSlave)  //使能从设备模式  

  95.     {  

  96.         chcfg |= BIT4;  

  97.     }  

  98.     if(config->EnCPOH)   //使能空闲时钟高电平  

  99.     {  

  100.         chcfg |= BIT3;  

  101.     }  

  102.     if(config->EnCPHB)   //使能第二个时钟边沿有效  

  103.     {  

  104.         chcfg |= BIT2;  

  105.     }  

  106.     if(config->EnRx) //使能接收  

  107.     {  

  108.         chcfg |= BIT1;  

  109.     }  

  110.     if(config->EnTx) //使能发送  

  111.     {  

  112.         chcfg |= BIT0;  

  113.     }  

  114.     switch(config->SetTranSize)//设置传输数据位宽  

  115.     {  

  116.         case 16: modcfg |= (1 << 29);modcfg |= (1 << 17);break; //半字  

  117.         case 32: modcfg |= (2 << 29);modcfg |= (2 << 17);break; //字  

  118.         default : break;    //字节  

  119.     }  

  120.     if(config->EnRxDMA)  //使能接收DMA  

  121.     {  

  122.         modcfg |= BIT2;  

  123.     }  

  124.     if(config->EnTxDMA)  //使能发送DMA     

  125.     {  

  126.         modcfg |= BIT1;  

  127.     }  

  128.     if(config->EnDMA4Burst)  //设置DMA传输类型为4个脉冲  

  129.     {  

  130.         modcfg |= BIT0;  

  131.     }  

  132.     if(config->EnAutoCS) //使能自动片选  

  133.     {  

  134.         slavecfg |= BIT1;  

  135.         switch(ch)  

  136.         {  

  137.             case 0: //通道0  

  138.             {  

  139.                 rGPCCON &= ~0xf000;  

  140.                 rGPCCON |= 0x2000;              //初始化CS 相关IO  

  141.             }break;  

  142.             case 1: //通道1  

  143.             {  

  144.                 rGPCCON &= ~(0xf0000000);  

  145.                 rGPCCON |= (0x2000 << 16);                //初始化CS 相关IO  

  146.             }break;  

  147.             default:break;  

  148.         }  

  149.     }  

  150.     //写入配置数据  

  151.     SPI->CHCFG = chcfg;  

  152.     SPI->MODECFG = modcfg;  

  153.     SPI->SLAVE = slavecfg;  

  154.     SPI->CLKCFG |= BIT8; //使能SPI时钟  

  155.     SPI_SetSpeed(ch,Speed); //设置SPI速度  

  156.       

  157.     SPIx_ReadWriteData(ch,0xaa);    //启动第一次传输  

  158.     return 0;  

  159. }  

  160.   

  161.   

  162.   

  163. /************************************************************************************************************************* 

  164. *函数    :    u32 SPIx_ReadWriteData(u8 ch,u32 TxData) 

  165. *功能    :    SPI发送接收数据 

  166. *参数    :    CH:SPI通道选择;TxData:要发送的数据 

  167. *返回    :    收到的数据 

  168. *依赖 :   底层宏定义 

  169. *作者     :   cp1300@139.com 

  170. *时间     :   20121005 

  171. *最后修改时间:    20121005 

  172. *说明     :   发送和接收的数据宽度要看配置,可以是8bit,16bit,32bit 

  173. *           发送完成后要加延时,因为数据写入到FIFO后并没有马上发送完,当发送完成之前片选可能就已经取消了,因此需要适当的添加延时 

  174. *           因为我们无法判断数据是否已经从移位寄存器中发送完毕,只能检测FIFO 

  175. *************************************************************************************************************************/  

  176. u32 SPIx_ReadWriteData(u8 ch,u32 TxData)  

  177. {         

  178.     u16 retry = 0;  

  179.     SPI_TypeDef *SPI;  

  180.     u8 temp;  

  181.           

  182.     if(ch >= SPI_CH_N)  

  183.         return 1;       //通道号超出范围  

  184.     SPI = (SPI_TypeDef *)SPI_CH[ch];        //获取对应通道寄存器结构指针   

  185.       

  186.     do  

  187.     {  

  188.         temp = (SPI->STATUS >> 6) & 0x7f;  //获取发送FIFO数据数量  

  189.         retry ++;  

  190.         if(retry > 8000)                       

  191.             return 0;  

  192.     }  

  193.     while(temp > 63);                        //发送FIFO满了,等待  

  194.     SPI->TXDATA = TxData;                    //发送数据        

  195.                                   

  196.     retry = 0;  

  197.     do  

  198.     {  

  199.         temp = (SPI->STATUS >> 13) & 0x7f; //获取接收FIFO数据数量  

  200.         retry ++;  

  201.         if(retry > 8000)                       

  202.             return 0;  

  203.     }  

  204.     while(temp == 0);                       //接收FIFO为空,等待  

  205.       

  206.     return SPI->RXDATA;                      //返回受到的数据                                         



spi.h


  1. /************************************************************************************************************* 

  2.  * 文件名: spi.h 

  3.  * 功能:      S3C6410 SPI底层驱动函数 

  4.  * 作者:      陈鹏 

  5.  * 创建时间:    2012年9月8日20:35 

  6.  * 最后修改时间:2012年9月8日 

  7.  * 详细:      SPI始化,发送,接收,配置等 

  8. *************************************************************************************************************/  

  9. #ifndef SPI_H_  

  10. #define SPI_H_  

  11.   

  12. #include "system.h"  

  13.   

  14.   

  15.   

  16. //SPI配置结构定义  

  17. typedef struct  

  18. {  

  19.     u8  EnSlave;        //使能SPI从设备模式  

  20.     u8  EnCPOH;         //使能空闲时钟高电平  

  21.     u8  EnCPHB;         //使能时钟第二个边沿有效,否则为第一个边沿有效  

  22.     u8  EnRx;           //使能接收  

  23.     u8  EnTx;           //使能发送  

  24.     u8  SetTranSize;    //设置传输数据宽度,8bit,16bit,32bit;  

  25.     u8  EnRxDMA;        //使能接收DMA  

  26.     u8  EnTxDMA;        //使能发送DMA  

  27.     u8  EnDMA4Burst;    //设置DMA传输类型为4个脉冲  

  28.     u8  EnAutoCS;       //使能自动片选  

  29. }SPI_Config_TypeDef;  

  30.   

  31.   

  32.   

  33. //默认模式1  

  34. //主设备模式,空闲时钟低电平,第一个时钟边沿有效(上升沿有效),使能发送接收,数据宽度8bit,关闭DMA,使能手动控制片选  

  35. extern const SPI_Config_TypeDef SPI_DEFAULT_01;  

  36.   

  37. void SPI_SetSpeed(u8 ch,u8 Speed);  

  38. u8 SPI_Init(u8 ch,const SPI_Config_TypeDef *config,u8 Speed);  

  39. u32 SPIx_ReadWriteData(u8 ch,u32 TxData);  

  40.   

  41.   

  42.   

  43.   

  44.   

  45.   

  46.   

  47.   

  48.   

  49.   

  50.   

  51.   

  52. #endif /*SPI_H_*/  


main.c


测试


  1. #include "system.h"  

  2. #include "uart.h"  

  3. #include "tft_lcd.h"  

  4. #include "other.h"  

  5. #include "delay.h"  

  6. #include "timer.h"  

  7. #include "spi.h"  

  8.   

  9.   

  10. //LED1闪烁程序,在定时器0中断服务程序中闪烁,周期400MS  

  11. void LED1_flash(void)  

  12. {  

  13.     LED1_FLASH();  

  14. }  

  15.   

  16.   

  17.   

  18.   

  19. int main(void)  

  20. {     

  21.     u8 i = 0;  

  22.       

  23.     LCD_Init();                 //初始化LCD  

  24.     UART0_Init(DISABLE,115200); //初始化串口,失能中断接收,波特率115200  

  25.     LED_Init();                 //初始化LED  

  26.     rGPCCON |= 1 << 12;  

  27.     rGPCDAT |= BIT3;  

  28.   

  29.     Timer1_Init(400000-1,ENABLE,LED1_flash);    //初始化定时器0,周期400ms  

  30.       

  31.     lcd_printf("Get_FCLK : %d Hz\n",Get_FCLK());      

  32.     lcd_printf("Get_PCLK : %d Hz\n",Get_PCLK());  

  33.       

  34.     SPI_Init(0,&SPI_DEFAULT_01,100);  

  35.   

  36.     while(1)  

  37.     {  

  38.         LED2_FLASH();       //LED2闪烁  

  39.         //Delay_US(600000);  

  40.         rGPCDAT &= ~BIT3;  

  41.         SPIx_ReadWriteData(0,i++);  

  42.         Delay_US(1);    //适当添加延时  

  43.         rGPCDAT |= BIT3;  

  44.         Delay_US(6);  

  45.     }  

  46. }  




测试了一下硬件控制片选,发现片选信号非常完美

上图



补充SPI寄存器结构


  1. //SPI  

  2. typedef struct  

  3. {  

  4.     vu32    CHCFG;          //配置寄存器  

  5.     vu32    CLKCFG;         //时钟配置寄存器  

  6.     vu32    MODECFG;        //FIFO控制寄存器  

  7.     vu32    SLAVE;          //从属器选择寄存器  

  8.     vu32    INTEN;          //中断启动寄存器  

  9.     vu32    STATUS;         //状态寄存器  

  10.     vu32    TXDATA;         //发送数据寄存器  

  11.     vu32    RXDATA;         //接收数据寄存器  

  12.     vu32    CNT;            //计数,主控器收到多少数据  

  13.     vu32    CLR;            //状态清除  

  14.     vu32    SWAPCFG ;       //交换配置寄存器  

  15.     vu32    FBCLK;          //反馈时钟选择寄存器   

  16. }SPI_TypeDef;  

  17.   

  18.   

  19. //SPI  

  20. #define SPI0_BASE   0x7f00b000  

  21. #define SPI1_BASE   0x7f00c000  

  22.   

  23.   

  24. //SPI0  

  25. #define SPI0    ((SPI_TypeDef*)SPI0_BASE)  

  26.   

  27. //SPI1  

  28. #define SPI1    ((SPI_TypeDef*)SPI1_BASE)  



关键字:S3C6410  SPI  裸机驱动 引用地址:S3C6410 SPI 裸机驱动

上一篇:S3C6410裸机AC97驱动
下一篇:S3C6410 裸机硬件JPEG解码

推荐阅读最新更新时间:2024-03-16 15:34

基于FPGA的串行外围接口SPI设计与实现
  引言   SPI(串行外围接口)总线,是一个同步串行接口的数据总线,它具有全双工、信号线少、协议简单、传输速度快等优点。由于串行总线的信号线比并行总线更少、更简单,越来越多的系统放弃使用并行总线而采用串行总线。在众多串行总线中,SPI 总线与I2C 总线、CAN 总线、USB 等其他常用总线相比有很大优势,如SPI 总线的数据传输速度可达若干Mbps, 比I2C 总线快很多。SPI 总线最典型的应用就是主机与外围设备(如EEPROM、Flash RAM、A/D 转换器、LED 显示器、实时时钟等)之间的通信。   FPGA(现场可编程门阵列)是在PAL、GAL、PLD 等可编程器件的基础上进一步发展的产物,具有设计周期
[嵌入式]
51单片机-SPI接口
SPI(Serial Peripheral Interface)接口是同步串行接口,利用时钟线对数据位进行同步,时钟的上升沿和下降沿锁存数据。SPI的两种类型: 四线制SPI:CS,SCK(同步时钟),MOSI(master out slaver in),MISO:全双工 三线制SPI:CS,SCK,DIO:半双工,只能分时进行收发 SPI时序图举例:四线制,低电平使能,上升沿锁存,先发送最高位。 DS1302的接口时序:三线制,高电平使能,写上升沿锁存,读下降沿锁存,先发送最低位。 DS1302是典型的三线制SPI接口,DS1302的时间信息以寄存器的形式存储在芯片内部,通过SPI接口,对相应的寄
[单片机]
51单片机-<font color='red'>SPI</font>接口
STM8S学习01——SPI&IIC
1、温习IIC总线协议 1)I2C 总线的一些特征 1 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL 2 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地址 主机可以作为主机发送器或主机接收器 3 它是一个真正的多主机总线 如果两个或更多主机同时初始化数据传输可以通过冲突检测和仲裁,防止数据被破坏 4 串行的 8 位双向数据传输位速率在标准模式下可达 100kbit/s 快速模式下可达 400kbit/s 高速模式下可达 3.4Mbit/s 5 片上的滤波器可以滤去总线数据线上的毛刺波 保证数据完整 6 连接到相同总线的 IC 数量只受到总线的最大电容 400pF 限制
[单片机]
MSP430 SD卡SPI读写操作(3) —— SD卡读写实现(以MSP430F5438A为例)
本节提供了MSP430F5438A SPI读写SD卡的示例代码,使用官方函数库msp430_driverlib_2_60_00_02,使用IAR for msp430 6.3通过编译。 本节代码未对SD卡进行区分,因此只针对SDHC卡进行操作,程序在金士顿 8GB SDHC microSD卡经过验证可以正常运行。 sdhc.h #ifndef _SDHC_H_ #define _SDHC_H_ #define SDHC_INIT_CLK 125000 #define SDHC_HIGH_CLK 3125000 #define SDHC_CS_PORT GPIO_PORT_P9 #define SDHC_CS_PIN
[单片机]
基于S3C6410的ARM11学习(十二) 代码拷贝及led测试输入日志
之前已经将ddr进行初始化了,这样就可以使用ddr了。首先就要将代码从stepping stone拷贝到ddr中。最后在ddr中运行程序。如果外部nandflash还有剩余的程序,还要将剩下程序拷贝到ddr中。 Stepping stone的起始地址是0x0c000000,DDR的起始地址是0x50000000。在上电的时候,CPU会自动把NANDFLASH的前8K代码拷贝到stepping stone中。但是现在写的代码是比较小的,还没有超过4K。所以这里就设定拷贝的代码是前4K代码。 这样,代码就比较好写了。 R0保存的是stepping stone的起始地址,r1保存的是要拷贝的ddr的地址,这里地址是0x
[单片机]
基于<font color='red'>S3C6410</font>的ARM11学习(十二) 代码拷贝及led测试输入日志
东芝推出面向车载应用的5A 2通道H桥电机驱动IC
东芝电子元件及存储装置株式会社(“东芝”)今日宣布,推出两种应用于电子节气门等车载应用的直流有刷 电机驱动 IC ——“TB9054FTG”和“TB9053FTG”。其中“TB9054FTG”采用可润湿侧翼 VQFN 封装,“TB9053FTG”采用功率型 QFN 封装。TB9054FTG 现已提供样品,预计在 2022 年 3 月开始量产;TB9053FTG 将从 2021 年 2 月开始提供样品,预计在 2022 年 5 月开始量产。 电子节气门和各种车用阀门的 H 桥电机驱动用量正在增加,这刺激了对系统小型化和降低成本的需求。此外,第二代车载自诊断设备要求(OBDII)将于 2022 年监管落实,要求汽车 电机驱
[汽车电子]
东芝推出面向车载应用的5A 2通道H桥电机<font color='red'>驱动</font>IC
ARM9的SPI
实验前须知: SPI的原理: 注: CLK传输时钟 MISO主机输入从机输出 MOSI主机输出从机输入 CS片选信号,由于SPI控制器可以外接多个SPI设备,所以这个用于选中SPI设备。 SPI的操作流程大体如下图所示: 实验的目的: 用s3c2440的SPI控制器操作SPI总线上的两个设备,分别是OLED和FLASH 实验的源程序: 07th_spi_i2c_adc_mini2440_tq2440_spi_controller.rar 实验的问题总结: 1 我们主要分析一下s3c2440_spi.c这个文件 /*************************************s3c2440_spi.c*****
[单片机]
ARM9的<font color='red'>SPI</font>
Linear推出6通道SPI/数字或I2C μModule隔离器LTM2883
凌力尔特公司 (Linear Technology Corporation) 推出 6 通道 SPI / 数字或 I2C 数字微型模块 (µModule®) 隔离器 LTM2883,该器件具备 3 个稳压的电源轨以用于 3.3V 和 5V 系统。在工业系统应用中,地电位可能变化非常大,常常超过可容许的范围,这有可能中断通信,甚至毁坏组件。LTM2883 通过电气方式隔离通信信号以断开地环路,从而隔离了内部电感隔离势垒每一侧的逻辑电平接口,该势垒可承受非常大并高达 2,500VRMS 的共模电压范围。LTM2883 的低 EMI 隔离型 DC-DC 转换器为通信接口供电,并提供可调的 5V、 +12.5V 和 -12.5V 电源输出
[传感器]
Linear推出6通道<font color='red'>SPI</font>/数字或I2C μModule隔离器LTM2883
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved