⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ledmodule.c

📁 WWVB receiver using AVR.
💻 C
字号:
/* $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();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -