?? ledmodule.c
字號(hào):
/* $Id: ledmodule.c,v 1.17 2005/10/30 19:44:38 simimeie Exp $ * Functions for communicating with the LED module. * The module is connected through an i2c bus, it consists of two SAA 1064 * drivers. */ #define BV _BV#include <avr/io.h>#include <avr/delay.h>#include "ledmodule.h"#include "debugconsole.h"/* The Port used for the connection */#define LEDPORT PORTB#define LEDPIN PINB#define LEDDDR DDRB/* Which pins of the port */#define SDAPIN PB0#define SCLPIN PB1/* the I2C addresses of the SAA 1064 LED drivers */#define SAA_AD1 0x70#define SAA_AD2 0x76#define I2C_READ 0x01#define I2C_WRITE 0x00/* Should be at least 27 (80 / 3) at 8 MHz *//* This was the conservative value used for testing. However, half as much * should work as well. */#define DELAYVAL 14/* For reference: * The mapping of the LED panel is as follows: * Bit Pin Segment * 3 1 e * Segments: * 2 2 d * aaaa * 1 4 c * f b * 0 5 P * f b * 4 6 b * gggg * 5 7 a * e c * 6 9 f * e c * 7 10 g * dddd P *//* This is basically a "font" for the digits */uint8_t led_digits[16] = { 0x7E, /* 0 */ 0x12, /* 1 */ 0xBC, /* 2 */ 0xB6, /* 3 */ 0xD2, /* 4 */ 0xE6, /* 5 */ 0xEE, /* 6 */ 0x32, /* 7 */ 0xFE, /* 8 */ 0xF6, /* 9 */ 0xFA, /* A */ 0xCE, /* B */ 0x6C, /* C */ 0x9E, /* D */ 0xEC, /* E */ 0xE8 /* F */ };uint8_t led_brightness;uint8_t led_statusleds;uint8_t led_dispoverride[7];uint8_t led_dispovcnt;void led_init(void) { /* activate pullups */ LEDPORT |= BV(SCLPIN); LEDPORT |= BV(SDAPIN);}/* Send START, defined as high-to-low SDA with SCL high. * Expects SCL and SDA to be high already! * Returns with SDA and SCL low. */static void I2C_start(void) { /* Change to output mode. */ LEDDDR |= BV(SDAPIN); LEDDDR |= BV(SCLPIN); /* change SDA to low */ LEDPORT &= (uint8_t)~BV(SDAPIN); _delay_loop_1(DELAYVAL); /* and SCL too */ LEDPORT &= (uint8_t)~BV(SCLPIN); _delay_loop_1(DELAYVAL);}/* Send STOP, defined as low-to-high SDA with SCL high. * Expects SCL and SDA to be low already! * Returns with SDA and SCL high. */static void I2C_stop(void) { /* Set SCL */ LEDPORT |= BV(SCLPIN); _delay_loop_1(DELAYVAL); /* Set SDA */ LEDPORT |= BV(SDAPIN); _delay_loop_1(DELAYVAL); /* Probably safer to tristate the bus */ LEDDDR &= (uint8_t)~BV(SDAPIN); LEDDDR &= (uint8_t)~BV(SCLPIN);}/* Transmits the byte in what. * Returns 1 if the byte was ACKed, 0 if not. * Expects SCL and SDA to be low already! * Returns with SDA and SCL low. */static uint8_t I2C_transmit_byte(uint8_t what) { uint8_t i; for (i = 0; i < 8; i++) { /* First put data on the bus */ if (what & 0x80) { LEDPORT |= BV(SDAPIN); } _delay_loop_1(DELAYVAL); /* Then set SCL high */ LEDPORT |= BV(SCLPIN); _delay_loop_1(DELAYVAL); /* Take SCL back */ LEDPORT &= (uint8_t)~BV(SCLPIN); _delay_loop_1(DELAYVAL); /* And SDA too */ LEDPORT &= (uint8_t)~BV(SDAPIN); _delay_loop_1(DELAYVAL); what <<= 1; } /* OK that was the data, now we read back the ACK */ /* We need to tristate SDA for that */ LEDPORT |= BV(SDAPIN); LEDDDR &= (uint8_t)~BV(SDAPIN); /* Give the device some time */ _delay_loop_1(DELAYVAL); _delay_loop_1(DELAYVAL); _delay_loop_1(DELAYVAL); /* Then set SCL high */ LEDPORT |= BV(SCLPIN); _delay_loop_1(DELAYVAL); _delay_loop_1(DELAYVAL); _delay_loop_1(DELAYVAL); i = LEDPIN & BV(SDAPIN); /* Read ACK */#if 0 if (i) { debugconsole_print("!"); } else { debugconsole_print("A"); }#endif /* Take SCL back */ LEDPORT &= (uint8_t)~BV(SCLPIN); _delay_loop_1(DELAYVAL); /* No more tristate, we pull SDA again */ LEDPORT &= (uint8_t)~BV(SDAPIN); LEDDDR |= BV(SDAPIN); _delay_loop_1(DELAYVAL); return (i == 0);}void set_led_digit(uint8_t digit, uint8_t val) { I2C_start(); /* Address device */ I2C_transmit_byte((digit < 4) ? (SAA_AD1 | I2C_WRITE) : (SAA_AD2 | I2C_WRITE)); I2C_transmit_byte((digit & 3) + 1); /* Address Digit Register on device */ I2C_transmit_byte(val); /* Send value for Digit */ I2C_stop();}void set_led_brightness(void) { I2C_start(); I2C_transmit_byte(SAA_AD1 | I2C_WRITE); /* Address first driver */ I2C_transmit_byte(0); /* Address Config Register on device */ I2C_transmit_byte(((led_brightness & 0x07) << 4) | 0x07); /* Send Settings */ I2C_stop(); I2C_start(); I2C_transmit_byte(SAA_AD2 | I2C_WRITE); /* Address second driver */ I2C_transmit_byte(0); /* Address Config Register on device */ I2C_transmit_byte(((led_brightness & 0x07) << 4) | 0x07); /* Send Settings */ I2C_stop();}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -