风筝
发表于: 2017-8-24 00:29:34 | 显示全部楼层

该应用程序非常简单,主要展示了如何使用ATtiny85单片机驱动四个RGB LED指示灯。

fourrgb.jpg

每个LED可以设置为16个不同等级之一,从关闭到全亮,电路中预留一个I / O引脚用于其他应用。


电路

以下是本文采用的电路:

fourrgbleds.gif

该应用程序的主要工作原理是您可以通过使用Charlieplexing的方式利用四个I/O线驱动12个LED。下表显示了当您将一个I / O线设置为高电平,另一个I / O线设置为低电平时,哪个RGB LED指示灯会被点亮:

rgbleds.gif

指示灯与普通的阴极RGB LED封装兼容;我使用了低成本的四引线共阴极5mm RGB LED,但您可以使用任何类型的RGB LED。


显示复用

使用Timer / Counter1产生的中断,从Buffer[]中的值更新LED,delay()millis()使用Timer / Counter0。

Buffer[]数组的每个元素决定一个RGB LED的颜色和亮度。该值指定为三个十六进制数字,颜色为BGR。值为0表示零亮度,“F”值指定全亮度。例如:

  1. Buffer[0] = 0xF00; Buffer[1] = 0x0F0; Buffer[2] = 0x00F; Buffer[3] = 0x888;
复制代码

将四个LED分别设置为100%绿色、100%蓝色、100%红色和50%白色。

DisplaySetup()函数中定时器设置为CTC模式,计数到OCR1C:

  1. void DisplaySetup () {
  2.   // Set up Timer/Counter1 to multiplex the display
  3.   TCCR1 = 1<<CTC1 | 7<<CS10;    // CTC mode; divide by 64
  4.   OCR1C = 24;                   // Divide by 25 -> 5kHz
  5.   TIMSK = TIMSK | 1<<OCIE1A;    // Enable overflow interrupt
  6. }
复制代码

Timer / Counter1 Compare A中断显示下一行LED:

  1. ISR(TIM1_COMPA_vect) {
  2.   DisplayNextRow();
  3. }
复制代码

对于每个RGB LED指示灯,DisplayNextRow()函数调用了16次。每个LED指示灯的R、G和B元素的亮度值从Buffer[led]中的值读取,然后确定16个周期中有多少颜色将点亮:

  1. void DisplayNextRow() {
  2.   static int cycle = 0;
  3.   DDRB = DDRB & ~(1<<(cycle & 0x03));
  4.   cycle = (cycle + 1) & 0x3F;   // 64 cycles
  5.   int led = cycle & 0x03;
  6.   int count = cycle>>2;
  7.   int rgb = Buffer[led];
  8.   int r = rgb & 0x0F;
  9.   int b = rgb>>4 & 0x0F;
  10.   int g = rgb>>8 & 0x0F;
  11.   int bits = (count < r) | (count < b)<<1 | (count < g)<<2;
  12.   bits = bits + (bits & 0x07<<led);
  13.   DDRB = (DDRB & 0xF0) | bits;
  14.   PORTB = (PORTB & 0xF0) | bits;
  15.   DDRB = DDRB | 1<<led;
  16. }
复制代码

中断以5kHz的速率发生,所以DisplayNextRow()的64个周期的完整集合以大约78Hz发生,足够快以避免闪烁。


演示程序

以下loop()函数中的演示程序会慢慢地循环LED通过所有可能的颜色和亮度:

  1. int Step = 0;

  2. int red (int x) {
  3.   int y = x % 48;
  4.   if (y > 15) y = 31 - y;
  5.   return max(y, 0);
  6. }

  7. int green (int x) { return red(x + 32); }
  8. int blue (int x) { return red(x + 64); }

  9. void loop () {
  10.   for (int i=0; i<4; i++) {
  11.     Buffer[i] = green(Step + i*12)<<8 | blue(Step + i*12)<<4 | red(Step + i*12);
  12.   }
  13.   Step++;
  14.   delay(200);
  15. }
复制代码

编译程序

使用ATTiny Core编译程序,ATTiny Core支持所有ATtiny处理器,并取代了早期的ATtiny内核。在Boards菜单的ATtiny Universal标题下选择ATtinyx5 series选项。然后在接下来的菜单中选择Timer 1 Clock: CPU、 B.O.D. Disabled、ATtiny85、 8 MHz (internal)。选择Burn Bootloaderr适当地设置保险丝。然后将程序上传到ATtiny85。

整个工程的代码:Four RGB LED Program


译者注:本文翻译自Driving Four RGB LEDs from an ATtiny85,如有错漏,敬请指正。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 32 | 回复: 41



手机版|

GMT+8, 2024-4-26 19:39 , Processed in 0.059912 second(s), 11 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表