通过74HC595移位寄存器改变LED强度
我目前正在开发一个项目,需要使用两个级联移位寄存器 74HC595 控制 13 个白色 LED 和一个 RGB LED。 我在 windows
上使用 SAMD21 XPLAINED PRO
板 (µC samd21j18a
) 和 ATMEL Studio
作为 IDE。
目前,我基本上使用 SPI
来完成此操作(我在 ATMEL Start
上定义了项目的大部分参数)。
#include <atmel_start.h>
#define message_size 2
bool RgbColors[7][3] = {
{1, 0, 0}, //Red
{0, 1, 0}, //Green
{0, 0, 1}, //Blue
{1, 1, 0}, //Yellow
{1, 0, 1}, //Pink
{0, 1, 1}, //Cyan
{1, 1, 1}, //White
};
uint8_t spi_transfer_array[message_size];
struct spi_xfer spi_driver_xfer;
// Send a 16 bits message through SPI
void spi_16bits_transfer(uint16_t data);
// Control a frame of 13 white LEDs and 1 RGB LED
void turn_led_model_on(uint8_t led, bool red, bool green, bool blue);
int main(void)
{
atmel_start_init();
spi_m_sync_enable(&SPI_0);
uint8_t i = 0;
bool red = 0;
bool green = 0;
bool blue = 0;
while (1) {
// Test
for (uint8_t led = 0; led <= 13; led++){
// RGB modulation
if (i <= 6){
red = RgbColors[i][0];
green = RgbColors[i][1];
blue = RgbColors[i][2];
i++;
}
else {
i = 0;
}
turn_led_model_on(led, red, green, blue);
delay_ms(200);
}
for (uint8_t led = 0; led <= 13; led++){
// RGB modulation
if (i <= 6){
red = RgbColors[i][0];
green = RgbColors[i][1];
blue = RgbColors[i][2];
i++;
}
else {
i = 0;
}
turn_led_model_on(13 - led, red, green, blue);
delay_ms(200);
}
}
}
void spi_16bits_transfer(uint16_t data){
spi_transfer_array[0] = ~data >> 8;
spi_transfer_array[1] = ~data & 0xFF;
spi_driver_xfer.txbuf = spi_transfer_array;
spi_driver_xfer.size = message_size;
gpio_set_pin_level(EN_pin, false);
gpio_set_pin_level(SPI_SS, false);
spi_m_sync_transfer(&SPI_0, &spi_driver_xfer);
gpio_set_pin_level(SPI_SS, true);
gpio_set_pin_level(EN_pin, true);
delay_ms(1);
gpio_set_pin_level(EN_pin, false);
}
void turn_led_model_on(uint8_t led, bool red, bool green, bool blue){
if (led > 13) led = 13;
uint16_t mask = 0;
if (led > 0){
for (uint8_t i = 1; i <= led; i++){
mask |= (1 << (led - i));
}
}
mask |= (red << 13);
mask |= (green << 14);
mask |= (blue << 15);
spi_16bits_transfer(mask);
}
我目前面临的问题是我希望能够改变光强度,但我不知道如何使用 74HC595
做到这一点,并且我不知道是否可以使用 做到这一点>SPI
。目标不仅是改变白色 LED 的强度,最重要的是获得更多选择 RGB LED 颜色的可能性(目前我只有 7 种可能性)。
我感觉可以使用定时器创建一种PWM
来选择LED的点亮频率,从而修改它们的强度,但我没能做到。
另外,我不知道是否可以独立改变每个 LED 的强度(这就是我需要的 RGB LED)。
谢谢
I'm currently working on a project for which I need to control 13 white LEDs and one RGB LED with two shift registers 74HC595
in cascade.
I work on windows
with a SAMD21 XPLAINED PRO
board (µC samd21j18a
) and ATMEL Studio
as IDE.
For the moment I manage to do it quite basically using SPI
(I define most of my project's parameters on ATMEL Start
).
#include <atmel_start.h>
#define message_size 2
bool RgbColors[7][3] = {
{1, 0, 0}, //Red
{0, 1, 0}, //Green
{0, 0, 1}, //Blue
{1, 1, 0}, //Yellow
{1, 0, 1}, //Pink
{0, 1, 1}, //Cyan
{1, 1, 1}, //White
};
uint8_t spi_transfer_array[message_size];
struct spi_xfer spi_driver_xfer;
// Send a 16 bits message through SPI
void spi_16bits_transfer(uint16_t data);
// Control a frame of 13 white LEDs and 1 RGB LED
void turn_led_model_on(uint8_t led, bool red, bool green, bool blue);
int main(void)
{
atmel_start_init();
spi_m_sync_enable(&SPI_0);
uint8_t i = 0;
bool red = 0;
bool green = 0;
bool blue = 0;
while (1) {
// Test
for (uint8_t led = 0; led <= 13; led++){
// RGB modulation
if (i <= 6){
red = RgbColors[i][0];
green = RgbColors[i][1];
blue = RgbColors[i][2];
i++;
}
else {
i = 0;
}
turn_led_model_on(led, red, green, blue);
delay_ms(200);
}
for (uint8_t led = 0; led <= 13; led++){
// RGB modulation
if (i <= 6){
red = RgbColors[i][0];
green = RgbColors[i][1];
blue = RgbColors[i][2];
i++;
}
else {
i = 0;
}
turn_led_model_on(13 - led, red, green, blue);
delay_ms(200);
}
}
}
void spi_16bits_transfer(uint16_t data){
spi_transfer_array[0] = ~data >> 8;
spi_transfer_array[1] = ~data & 0xFF;
spi_driver_xfer.txbuf = spi_transfer_array;
spi_driver_xfer.size = message_size;
gpio_set_pin_level(EN_pin, false);
gpio_set_pin_level(SPI_SS, false);
spi_m_sync_transfer(&SPI_0, &spi_driver_xfer);
gpio_set_pin_level(SPI_SS, true);
gpio_set_pin_level(EN_pin, true);
delay_ms(1);
gpio_set_pin_level(EN_pin, false);
}
void turn_led_model_on(uint8_t led, bool red, bool green, bool blue){
if (led > 13) led = 13;
uint16_t mask = 0;
if (led > 0){
for (uint8_t i = 1; i <= led; i++){
mask |= (1 << (led - i));
}
}
mask |= (red << 13);
mask |= (green << 14);
mask |= (blue << 15);
spi_16bits_transfer(mask);
}
The problem I am currently facing is that I want to be able to change light intensity but I don't know how to do it with 74HC595
and I don't know if I can do it using SPI
. The goal is not only to change white LEDs intensity but most of all to get more possibility for the choice of the color of the RGB LED (for the moment I only have 7 possibilities).
I have the feeling it's possible to create a kind of PWM
using a timer to choose the frequency of lighting of the LEDs and thus to modify their intensity, but I don't manage to do it.
Also, I don't know if it is possible to change the intensity of each LED independently (that's what I would need for the RGB LED).
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,我正在开发一个效果非常好的软件解决方案。
我创建了一个“硬写”值表,它是一种固定 LED 频率的仪表。
我的仪表包含 26 个值(前 13 个值是“0”,后 13 个值是“1”)。我根据我想要的强度浏览包含 13 个值的样本的仪表(样本中的值从仪表 [强度] 到仪表 [强度 + 12])。
(当强度为 0 时,我的样本仅包含 13 个 0。当强度为 1 时,我的样本仅包含 12 个 0 和 1 个 1。)。
根据这些值,我打开或关闭 LED 来调节强度。
我仍然需要对其进行研究才能将其用于 RGB 调制,但现在应该不会那么复杂。
Ok, I'm working on a software solution that works really good.
I create an "hard written" values table which is a kind of gauge to fix the LED frequency.
My gauge contains 26 values (the first 13 values are "0" and the last 13 values are "1"). I browse this gauge with a sample of 13 values depending on the intensity I want (the values in my sample start at gauge[intensity] to gauge[intensity + 12]).
(When intensity is 0, my sample contains only 13 times 0. When intensity is 1, my sample contains only 12 times 0 and one 1.).
Based on these values, I turn on or off my LEDs to modulate the intensity.
I still have to work on it to use it for RGB modulation but it shouldn't be that complex now.