fork download
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. #include <stddef.h>
  5. #include <stdint.h>
  6.  
  7. #define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
  8.  
  9. static const struct traffic_light {
  10. const struct led {
  11. volatile uint8_t *port;
  12. uint8_t pin;
  13. } red, amber, green;
  14. } lights[] = {
  15. {{&PORTA, _BV(PA0)}, {&PORTA, _BV(PA1)}, {&PORTA, _BV(PA2)}},
  16. {{&PORTA, _BV(PA3)}, {&PORTA, _BV(PA4)}, {&PORTA, _BV(PA5)}},
  17. {{&PORTA, _BV(PA6)}, {&PORTA, _BV(PA7)}, {&PORTB, _BV(PB0)}},
  18. {{&PORTB, _BV(PB1)}, {&PORTB, _BV(PB2)}, {&PORTB, _BV(PB3)}},
  19. }, *light = lights;
  20.  
  21. #define NEXT_LIGHT (light - lights < (ptrdiff_t) (ARRAY_SIZE(lights) - 1u) \
  22.   ? light + 1u \
  23.   : lights)
  24.  
  25. typedef void (led_state)(const struct led *);
  26.  
  27. void set(const struct led *led) { *(led->port) |= led->pin; }
  28. void reset(const struct led *led) { *(led->port) &= ~(led->pin); }
  29.  
  30. void light_state(led_state *f, led_state *g, led_state *h) {
  31. f(&light->red);
  32. g(&light->amber);
  33. h(&light->green);
  34. }
  35.  
  36. void light_off(void) { light_state(&reset, &reset, &reset); }
  37. void light_red(void) { light_state(&set, &reset, &reset); }
  38. void light_amber(void) { light_state(&reset, &set, &reset); }
  39. void light_green(void) { light_state(&reset, &reset, &set); }
  40.  
  41. int main(void) {
  42. DDRA = 0xffu;
  43. DDRB |= 0x0fu;
  44. PORTA = 0b01001100;
  45. PORTB = 0b00000010;
  46. for (;; light = NEXT_LIGHT) {
  47. light_green();
  48. _delay_ms(10000);
  49. for (size_t i = 0u; i < 3u; ++i) {
  50. light_off();
  51. _delay_ms(500);
  52. light_green();
  53. _delay_ms(500);
  54. }
  55. light_off();
  56. _delay_ms(500);
  57. light_amber();
  58. _delay_ms(3000);
  59. light_red();
  60. }
  61. return 0;
  62. }
  63.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty