你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32CUBEMX--SPI,TLC5947外部PWM移植

[复制链接]
STMCU小助手 发布时间:2022-4-29 23:30
概述
SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如 EEPROM,FLASH,实时时钟,AD转换器。
TLC5947是一款SPI接口的PWM脉宽调制24路LED驱动模块/RGB LED驱动器芯片,它能驱动24路的PWM。

硬件准备
首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:

H0)1(DOD46`N0X`9J48V~LL.png


选择芯片型号
使用STM32CUBEMX选择芯片stm32f030r8,如下所示:



配置时钟源
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:

3I~E5[66G3QWMV3W``VG_LQ.png

配置时钟树
STM32F0的最高主频到48M,所以配置48即可:

20200604204550406.png

SPI配置
本次实验使用的SPI与Flash通信,配置如下。
SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。
(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;
(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;
(3)SCLK – Serial Clock,时钟信号,由主设备产生;
(4)CS – Chip Select,从设备使能信号,由主设备控制。

接线方式

2@E`[W1X]_0VQR`N}%OL%{1.png

负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCLK时钟线存在的原因,由SCLK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。因此,至少需要8次时钟信号的改变(上沿和下沿为一次),才能完成8位数据的传输。
时钟信号线SCLK只能由主设备控制,从设备不能控制。同样,在一个基于SPI的设备中,至少有一个主设备。这样的传输方式有一个优点,在数据位的传输过程中可以暂停,也就是时钟的周期可以为不等宽,因为时钟线由主设备控制,当没有时钟跳变时,从设备不采集或传送数据。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。芯片集成的SPI串行同步时钟极性和相位可以通过寄存器配置,IO模拟的SPI串行同步时钟需要根据从设备支持的时钟极性和相位来通讯。
最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。

20210627194827850.png

其中,CS是从芯片是否被主芯片选中的控制信号,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),主芯片对此从芯片的操作才有效。这就使在同一条总线上连接多个SPI设备成为可能。
TLC5947需要配置2个CS线,分别是BLANK和LAT。

20210627195354888.png

生成工程设置
注意在生产工程设置中不能出现中文,不然会报错。

20210627195732778.png

生成代码

20200604205807980.png

配置keil


20200604210002645.png

TLC5947的原理及应用
BLANK:所有恒流输出关闭。当blank 接高时,所有恒流输出(输出0通过out23)强制关闭,脉宽调制PWM定时控制器初始化,灰度计数器重置为0。当blank接低时,所有恒流输出由灰度脉宽调制定时控制器控制。
GND:负极
IREF:设置恒定电流值,设置T0到T23引脚输出的电流值。通过在IREF和GND之间连接一个外部电阻所需要的值。
SCLK:串行数据移位时钟。
SIN:灰度数据的串行输入。
SOUT:串行数据输出。
VCC:供电
XLAT:灰度数据转换。灰度移位寄存器中的数据以从低到高的方式移动到灰度数据锁存器,在XLAT引脚上转换。当XLAT.上升沿被输入时,所有恒流输出被强制关闭,直到下一个灰度显示周期。灰度计数器不会随着XLAT边沿的上升而重置为0。

PM0GL23A`ZBPAB37N2)Z7QH.png

由于芯片为开漏输出,故接线如下所示。

20210627201319812.png

时序图如下所示。

20210627201552404.png

代码
本例程向通道0中写入呼吸灯程序通道1输出12.5%,通道2输出25%,通道3-通道22输出50%,通道23输出75%,例程代码如下。
变量定义。
  1. /* USER CODE BEGIN PV */
  2. uint16_t leds[24]=
  3. {
  4. 512,512,1024,2048,2048,2048,
  5. 2048,2048,2048,2048,2048,2048,
  6. 2048,2048,2048,2048,2048,2048,
  7. 2048,2048,3000,2048,2048,3072
  8. };
  9. void TLC_Update(void);
  10. void TLC_Write(uint8_t data);
  11. int i=0;
  12. int flag=0;
  13. /* USER CODE END PV */
复制代码

SPI发送函数定义。

  1. /* USER CODE BEGIN 4 */
  2. void TLC_Update(void)
  3. {      
  4.     HAL_GPIO_WritePin(BLANK_GPIO_Port, BLANK_Pin, GPIO_PIN_SET);
  5. //                HAL_Delay(1);        
  6.     for (int8_t i = 23; i >= 0; i -= 2)
  7.     {
  8.         uint8_t send1 = 0;
  9.         uint8_t send = leds<i> >> 4;
  10.         TLC_Write(send);
  11.         send = (leds<i> & 0x000F);
  12.         send <<= 4;
  13.         send1 = (leds[i-1]) >> 8;   
  14.         send |= send1;
  15.         TLC_Write(send);
  16.         send = leds[i-1];
  17.         TLC_Write(send);
  18.     }   

  19.     HAL_GPIO_WritePin(XLAT_GPIO_Port, XLAT_Pin, GPIO_PIN_SET);
  20. //                HAL_Delay(1);        
  21.     HAL_GPIO_WritePin(XLAT_GPIO_Port, XLAT_Pin, GPIO_PIN_RESET);
  22. //                HAL_Delay(1);        
  23.     HAL_GPIO_WritePin(BLANK_GPIO_Port, BLANK_Pin, GPIO_PIN_RESET);

  24.     return ;
  25. }


  26. void TLC_Write(uint8_t data)
  27. {
  28.     HAL_SPI_Transmit(&hspi1, &data, sizeof(data), 0);
  29.     while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_RESET);

  30.     return ;
  31. }
  32. /* USER CODE END 4 */</i></i>
复制代码

主程序。
  1.   /* USER CODE BEGIN WHILE */
  2.   while (1)
  3.   {
  4.     /* USER CODE END WHILE */

  5.     /* USER CODE BEGIN 3 */
  6.                 if(flag==0)//灯渐亮
  7.                                 i+=5;
  8.                 else//灯渐灭
  9.                                 i-=5;
  10.                
  11.                 if(flag==0&&i==4095)//灯最亮
  12.                 {
  13.                         HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  14.                         flag=1;
  15.                 }
  16.                 if(flag==1&&i==0)//灯最暗
  17.                 {
  18.                         HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  19.                         flag=0;
  20.                 }                        
  21.                 leds[0]=i;//更新通道0的PWM
  22.                 TLC_Update();//更新PWM
  23.                 HAL_Delay(1);               
  24.   }
  25.   /* USER CODE END 3 */
  26.         
  27.         
  28. }
复制代码


收藏 评论0 发布时间:2022-4-29 23:30

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版