zoukankan      html  css  js  c++  java
  • TLC2543和TLV5614的STM32程序

    使用STM32的两个硬件SPI完成数据的读写,具体的见程序注释

      1 /**************************(C) COPYRIGHT SunHao 2011***************************
      2 名称:ADDA.c
      3 功能:ADDA的相关配置以及读取函数
      4 作者:孙浩
      5 时间:2011.4.25
      6 版本:1.0
      7 注意:对照TLC2543时序图,确保对应时序一致,读写速度不宜太快
      8 *******************************************************************************/
      9 #include "STM32Lib//stm32f10x.h"
     10 #include "hal.h"
     11 //模拟开关CD4051对应的通道选择IO定义
     12 #define A_OFF    GPIO_ResetBits(GPIOF, GPIO_Pin_8)
     13 #define A_ON     GPIO_SetBits(GPIOF, GPIO_Pin_8)
     14 #define B_OFF    GPIO_ResetBits(GPIOF, GPIO_Pin_7)
     15 #define B_ON     GPIO_SetBits(GPIOF, GPIO_Pin_7)
     16 #define C_OFF    GPIO_ResetBits(GPIOF, GPIO_Pin_6)
     17 #define C_ON     GPIO_SetBits(GPIOF, GPIO_Pin_6)
     18 /*******************************************************************************
     19 名称:void ADDA_Config(void)
     20 功能:配置ADDA对应的SPI和IO
     21 参数:无
     22 时间:2011.4.20
     23 版本:1.0
     24 注意:配置类似函数一定要注意外设时钟使能,所有用到引脚时钟使能
     25 *******************************************************************************/
     26 void ADDA_Config(void)
     27 {
     28     SPI_InitTypeDef  SPI_InitStructure;
     29     GPIO_InitTypeDef GPIO_InitStructure;
     30     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
     31     RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
     32     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);
     33     /*TLC2543相关IO口定义  */
     34     /* PA5-SCK PA7-MOSI */
     35     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5 |GPIO_Pin_7 ;
     36     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     37     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     38     GPIO_Init(GPIOA, &GPIO_InitStructure);
     39     /*PA4-CS*/
     40     GPIO_SetBits(GPIOA, GPIO_Pin_4);
     41     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
     42     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     43     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     44     GPIO_Init(GPIOA, &GPIO_InitStructure);    
     45 
     46     /*PA6-MISO*/
     47     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
     48     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     49     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
     50     GPIO_Init(GPIOA, &GPIO_InitStructure);
     51     
     52     /*TLV5614相关IO口定义  */
     53     /* PB13-SCK PB15-MOSI */
     54     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13 |GPIO_Pin_15 ;
     55     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     56     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     57     GPIO_Init(GPIOB, &GPIO_InitStructure);
     58     /*PB12-CS PB11-FS*/
     59     GPIO_SetBits(GPIOB, GPIO_Pin_11);//帧同步信号和片选信号初始化为高电平
     60     GPIO_ResetBits(GPIOB, GPIO_Pin_12);
     61     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
     62     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     63     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     64     GPIO_Init(GPIOB, &GPIO_InitStructure);    
     65 
     66     /* SPI1 configuration 具体的SPI时序严格参照TLC2543数据手册*/
     67     SPI_Cmd(SPI1, DISABLE);                                                 //必须先禁能,才能改变MODE
     68     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;        //两线全双工
     69     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                            //
     70     SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;                        //16位
     71     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                                //时钟脚空闲时保持低电平
     72     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                            //在第一个时钟沿采样数据信号
     73     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                //软件NSS,片选信号由软件产生
     74     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    //256分频
     75     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                        //高位在前
     76     
     77     SPI_Init(SPI1, &SPI_InitStructure);
     78     SPI_Cmd(SPI1, ENABLE); 
     79     /* SPI2 configuration 具体的SPI时序严格参照TLV5614数据手册*/
     80     SPI_Cmd(SPI2, DISABLE);                                                 //必须先禁能,才能改变MODE
     81     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;        
     82     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                            //
     83     SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;                        //16位
     84     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                                //时钟脚空闲时保持低电平
     85     SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                            //在第一个时钟沿采样数据信号
     86     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                //软件NSS,片选信号由软件产生
     87     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    //256分频
     88     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                        //高位在前
     89     
     90     SPI_Init(SPI2, &SPI_InitStructure);
     91     SPI_Cmd(SPI2, ENABLE); 
     92     //模拟开关通道选择IO口定义    
     93     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
     94     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //开漏输出
     95     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //50M时钟速度
     96     GPIO_Init(GPIOF, &GPIO_InitStructure);
     97     A_OFF;
     98     B_OFF;
     99     C_OFF;
    100     GPIO_SetBits(GPIOB, GPIO_Pin_11);//帧同步信号初始化为高电平
    101     GPIO_ResetBits(GPIOB, GPIO_Pin_12);
    102 }
    103 /*******************************************************************************
    104 名称:u16 Read_AD(u16 chan)
    105 功能:读取对应通道的AD值
    106 参数:chan对应的通道,取值0-15,返回值0-4095
    107 时间:2011.4.20
    108 版本:1.0
    109 注意:后八个通道是通过模拟开关切换,受模拟开关切换速度影响,能够读取的速度要比
    110       前八个通道慢
    111 *******************************************************************************/
    112 u16 Read_AD(u16 chan)
    113 {
    114     u16 i,ADCdata,chanaddr;
    115     if(chan<=7)
    116     {
    117         chanaddr= chan <<12;
    118         chanaddr|=0x0C00; 
    119     }
    120     else
    121     {
    122         chanaddr=8;//通过模拟开关进行输入,模拟开关接入第八通道
    123         chanaddr<<=12;
    124         chanaddr|=0x0C00; 
    125         switch (chan)
    126         {
    127             case 8:
    128                 A_OFF;
    129                 B_OFF;
    130                 C_OFF;
    131                 break;
    132             case 9:
    133                 A_ON;
    134                 B_OFF;
    135                 C_OFF;
    136                 break;
    137             case 10:
    138                 A_OFF;
    139                 B_ON;
    140                 C_OFF;
    141                 break;
    142             case 11:
    143                 A_ON;
    144                 B_ON;
    145                 C_OFF;
    146                 break;
    147             case 12:
    148                 A_OFF;
    149                 B_OFF;
    150                 C_ON;
    151                 break;
    152             case 13:
    153                 A_ON;
    154                 B_OFF;
    155                 C_ON;
    156                 break;
    157             case 14:
    158                 A_OFF;
    159                 B_ON;
    160                 C_ON;
    161                 break;
    162             case 15:
    163                 A_ON;
    164                 B_ON;
    165                 C_ON;
    166                 break;
    167             default:
    168                 break;
    169         }
    170         for(i=0;i<2000;i++);   //模拟开关切换之后需要等待一段时间来消除上一通道数据影响
    171         //这个延时是根据测试所得,如果需要更好精度而不是速度的话可以加长延时
    172     }
    173     
    174     GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);                             //拉低CS引脚电平
    175     for(i=0;i<100;i++);                                                     //加入延时,速度过快则读不到数据
    176     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET); 
    177     SPI_I2S_SendData(SPI1,chanaddr);                                            //写入一个数据,包括采样通道和数据格式  
    178     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET) ;  
    179     ADCdata=SPI_I2S_ReceiveData(SPI1); 
    180     for(i=0;i<100;i++); 
    181     ADCdata>>=4;                                                            //读取的数据为16位,低四位为0
    182     GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);                                 //CS高 
    183     
    184     //在多通道采样时,当前读取的数据时上一次选择的通道值,如果在速度要求不高的情况下可以进行两次操作
    185     GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);                             //拉低CS引脚电平
    186     for(i=0;i<100;i++);                                                     //加入延时,速度过快则读不到数据
    187     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET); 
    188     SPI_I2S_SendData(SPI1,chanaddr);                                            //写入一个数据,包括采样通道和数据格式  
    189     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET) ;  
    190     ADCdata=SPI_I2S_ReceiveData(SPI1); 
    191     for(i=0;i<100;i++); 
    192     ADCdata>>=4;                                                            //读取的数据为16位,低四位为0
    193     GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET); 
    194     return ADCdata;
    195 }
    196 /*******************************************************************************
    197 名称:void Write_DA(u16 chan,u16 data)
    198 功能:向对应的通道写入数据
    199 参数:chan对应的通道,取值0-3,data写入的数据取值0-4095
    200 时间:2011.4.25
    201 版本:1.0
    202 注意:
    203 *******************************************************************************/
    204 void Write_DA(u16 chan,u16 data)
    205 {
    206     u16 Send_data,i;
    207     for(i=0;i<50;i++);    
    208     GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_RESET); 
    209     for(i=0;i<50;i++);    
    210     //具体参照TLV5614数据手册,SPD位设置为1,设置为快速方式
    211     Send_data=0x1000;
    212     Send_data|=(chan<<14);
    213     data&=0x0FFF;
    214     Send_data|=data;
    215     while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);
    216     SPI_I2S_SendData(SPI2,Send_data);
    217     for(i=0;i<1200;i++);//上一句只是把数据写入发送的寄存器,实际上并没有发送完全
    218     //因此这里并不能立刻拉高,这个延时是通过逻辑分析仪测试得到    
    219     GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET); //数据发送完成后先拉高帧同步信号
    220     //按理说发送一遍应该可以了,实际测试有一个很奇怪的问题,就是连续发送四个通道数据
    221     //的时候第二和第四通道数据发送不正确,于是这里干脆直接发送两遍。
    222     for(i=0;i<50;i++);    
    223     GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_RESET);
    224     while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);
    225     SPI_I2S_SendData(SPI2,Send_data);
    226     for(i=0;i<1200;i++);    
    227     GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET); //数据发送完成后先拉高帧同步信号
    228     
    229 }
    ★emouse 思·睿博客文章★ 原创文章转载请注明:http://emouse.cnblogs.com
  • 相关阅读:
    js 产生随机数
    基于bootstrap的multiple-select下拉控件使用
    jqgrid 单列排序和组合排序
    jqgrid 配置行号及行号的宽度
    jqgrid 配置分页大小及下拉项
    jqgrid 滚动分页
    jqgrid 宽度自适应
    jqgrid 行选中multiboxonly属性说明
    jqgrid 谈谈给表格设置列头事件、行事件、内容事件
    jqgrid 加入右键菜单按钮管理
  • 原文地址:https://www.cnblogs.com/emouse/p/2198154.html
Copyright © 2011-2022 走看看