使用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://www.cnblogs.com/emouse/archive/2011/04/25/2198154.html,如需转载请自行联系原作者

TLC2543和TLV5614的STM32程序相关推荐

  1. qt串口采用队列_基于STM32的RGB调色器——STM32程序和Qt上位机全开源

    前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制,可以混合出任意的颜色,今天整理了一下,开源这个Qt上位机和STM32代码. 项目介绍 基于u ...

  2. 树莓派 st-link master使用ST-LINK V2下载STM32程序 支持F0 F1 F2 等

    这段时间在研究怎么脱机实现STM32的下载,同时也了解了Windows和Linux的下载方式,st官方只提供了Windows的下载工具,Linux的版本并未提供,这里网上搜索后找到了st-link m ...

  3. 6-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(远程升级STM32程序,基于Wi-Fi,同时支持升级Wi-Fi,APP控制版)...

    https://www.cnblogs.com/yangfengwu/p/10456306.html 视频教程 https://www.bilibili.com/video/av54942955/ 请 ...

  4. ARM汇编语言编程-Keil环境搭建及STM32程序的编写

    目录 一.keil环境搭建 1.keil安装 2.注册LIC 3.支持包安装 二.STM32程序 1.新建工程 2.配置环境 三.总结 一.keil环境搭建 推荐百度网盘下载mdk531 mdk31安 ...

  5. Ubuntu20.04LTS环境下载STM32程序

    Ubuntu20.04LTS环境下载STM32程序 概述 安装步骤 下载BIN文件 概述 该文档主要是介绍ubuntu20.04LTS上安装st-link驱动并且下载bin文件的方法.STM32在li ...

  6. A_A03_005 STM32程序J-LINK下载

    一.软件下载 网盘链接    戳它跳转 提取码:7fvz 二.相关链接 J-LINK驱动安装       戳它跳转 MDK5下载与安装   戳它跳转 三.交流学习 安装过程如有疑问,可留言或者私聊交流 ...

  7. 基于STM32的RGB调色器——STM32程序和Qt上位机全开源

    文章目录 前言 项目介绍 uFUN开发板 STM32下位机 Qt上位机 我的评测文章 关于我 前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制 ...

  8. 简单的stm32程序

    编写一个简单的stm32程序 一 MDK的安装 二编写一个简单的stm32程序 准备工作 编写程序代码 一 MDK的安装 keil官网网址下载 http://www.keil.com/download ...

  9. MAX31856多类型热电偶温度检测方案芯片详解,附可实现的STM32程序代码

    背景: 热电偶的测温是工业现场常用的测温手段,但是欧洲系列的工控领域中使用的大部分都是J型热电偶,而日本以及台湾等地大部分使用的是K型热电偶.因为日本和台湾的工控产品较早地进入国内,因此国内大部分设备 ...

最新文章

  1. 号称用GPT-3开发的游戏,却活生生玩出了人性黑暗面
  2. etcd集群部署与遇到的坑(转)
  3. php文件里直接写上?xml version=1.0 encoding=utf-8?出错?
  4. PKI/CA (5)X.509公钥证书
  5. python wheel库(安装包查找)(适用于Python扩展程序包的非官方Windows二进制文件、Pypi官方库、清华大学开源软件镜像源)
  6. 如何采用python语言绘制一条_如何使用matplotlib绘制一条线?
  7. 求职中最吃香的编程语言:JavaScript、Java 和 Python
  8. ORB-SLAM2-金字塔求解-特征点的提取-描述子的计算
  9. 存储过程 锁定并发_Java并发教程–锁定:显式锁定
  10. 添加url白名单_赏金技巧 | URL跳转Bypass案例
  11. dll编译为html,如何为MSHTML v9编译.dll。我目前正在获取“MIDL 2035:预期的常量表达式”的100个错误...
  12. 电脑上有哪些特别好用的小工具?盘点4个PC工具,个个都精品
  13. 由对称性知定点一定在x轴上_圆锥曲线解答题的经典答案:由椭圆的对称性知,定点在x轴上?...
  14. 黑灰白箱测试+Ubuntu wireshark wifibluetooth
  15. 百家号在电脑上如何查看作者的其它文章
  16. 雷神黑武士5代shark评测
  17. 小米笔记本 wifi 频繁断开重连 解决方案
  18. android+小米文件管理器源码,小米开源文件管理器MiCodeFileExplorer-源码研究(1)-2个模型Model...
  19. NAND FLASH MT29F4G08
  20. 中国机械式停车设备行业投资建议与发展机遇研究报告2022版

热门文章

  1. 大龄程序员的前途令人担忧
  2. sinon spy_Sinon教程:使用嘲弄,间谍和存根进行JavaScript测试
  3. 【程序设计赛】华为 · 厦门开发者创新应用赛 #鸿蒙应用开发 #¥32,000
  4. C#创建和部署Windows Service程序
  5. TypeScript进阶 之 重难点梳理
  6. 计算机上根号5怎么打,根号怎么打(5种快速输入√与×号的方法)
  7. 【Oracle】插入数据时出现“ ORA-00001: unique constraint”
  8. JointJS+新的MindMap应用程序
  9. 这些是 Python 官方推荐的最好书籍(推荐)
  10. 【数据中心】容灾备份