/**************************************************************
* DCF-Uhr/Temperatur (via TWI) auf SDA5708 anzeigen
* =================================================
* Uwe Berger; 2009
*
* ... gerade keine Lust, was sinnvolles zu schreiben...
* siehe auch: http://bralug.de/wiki/Display_SDA5708
*
*
* ---------
* Have fun!
*
***************************************************************/
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "font.h"
#include "i2clcd.h"
#ifndef F_CPU
#define F_CPU 12000000UL
#endif
// TWI-Adressen
#define ADDR_TINY 0x20
#define ADDR_LM75 0x92
// Hardwarekonfiguration MCU
#define PORT_RESET PORTC
#define DDR_RESET DDRC
#define RESET PC2
#define PORT_SDCLK PORTC
#define DDR_SDCLK DDRC
#define SDCLK PC0
#define PORT_DATA PORTC
#define DDR_DATA DDRC
#define DATA PC1
#define PORT_LOAD PORTC
#define DDR_LOAD DDRC
#define LOAD PC3
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PB1
#define PRELOAD 62606 // ca. 4Hz Timerinterrupt
#define MODE_CHANGE_VALUE 30 // 0,125sx30 --> Mode-Wechsel
#define MODE_DATE 0
#define MODE_TIME 1
#define MODE_TEMP 2
volatile uint8_t click = 0;
uint8_t h_temp, l_temp;
uint8_t mode, mode_counter;
typedef struct {uint8_t hs, ss, mm, hh, dd, mt, yy, wd, mez, mesz;} date_time_t;
date_time_t dcf77;
//*********************************************************************
void reset_SDA5708(void)
{
// RESET toggeln
PORT_RESET &= ~(1<<RESET);
PORT_RESET |= (1<<RESET);
}
//*********************************************************************
void init_SDA5708(void)
{
// Ausgaenge initialisieren
DDR_RESET |= (1<<RESET);
DDR_SDCLK |= (1<<SDCLK);
DDR_DATA |= (1<<DATA);
DDR_LOAD |= (1<<LOAD);
reset_SDA5708();
}
//*********************************************************************
void send_byte_to_SDA5708(uint8_t byte)
{
uint8_t x;
// LOAD auf Low
PORT_LOAD &= ~(1<<LOAD);
// jede Byte-Stelle ans Display senden
for (x=0; x<=7;x++) {
// DATA entsprechend setzen
if ((byte>>x)&1) PORT_DATA |= (1<<DATA); else PORT_DATA &= ~(1<<DATA);
// SDCLK toggeln
PORT_SDCLK |= (1<<SDCLK);
PORT_SDCLK &= ~(1<<SDCLK);
}
// LOAD auf High
PORT_LOAD |= (1<<LOAD);
}
//*********************************************************************
void brightness_SDA5708(uint8_t val)
{
// Helligkeit von 0...8, wobei 0 ganz hell ist!
// mit dem 4.Bit koennte man noch die Multiplex-Impulslaenge des
// Display-Controllere manipulieren und damit das Ding noch dunkler
// machen... (siehe auch Hardware-/Protokoll-Beschreibung oben!)
send_byte_to_SDA5708(0b11100000|(val&0b00000111));
}
//*********************************************************************
void digit_to_SDA5708(uint8_t sign, uint8_t digit)
{
uint8_t i;
// anzeigbares Zeichen? Wenn nein, dann Leerzeichen!
if ((sign < 0x20) || (sign > 0x7F)) sign = 0x20;
// Digit im Bereich?
if (digit > 7) digit = 0;
// Digit-Adresse zum Display senden
send_byte_to_SDA5708(0b10100000|digit);
// jede Zeile des Fonts adressieren, lesen, ausgeben
for(i=0; i<7; i++) {
// Font ist linksbuendig, deshalb 3 Bit nach rechts schieben...
send_byte_to_SDA5708(pgm_read_byte(&font[(sign-0x20)*7+i])/8);
}
}
//************************************************************************
void my_delay_ms(uint16_t ms)
{
uint16_t i;
for (i=0; i<ms; i++) _delay_ms(1);
}
//************************************************************************
void lm75_init(void)
{
i2c_start(ADDR_LM75+I2C_WRITE);
i2c_write(0);
i2c_stop();
my_delay_ms(100);
}
//************************************************************************
void lm75_read(void)
{
i2c_start(ADDR_LM75+I2C_READ);
h_temp = i2c_readAck();
l_temp = i2c_readNak();
i2c_stop();
}
//***********************************************************
uint8_t dcf77_read(void)
{
// Anstoss senden
if (i2c_start(ADDR_TINY+I2C_WRITE)) return 1;
i2c_write(0);
i2c_stop();
// kleine Pause, weil der Tiny-Slave nicht hinterher kommt
my_delay_ms(30);
// Werte lesen
if (i2c_start(ADDR_TINY+I2C_READ)) return 1;
dcf77.ss = i2c_readAck();
dcf77.mm = i2c_readAck();
dcf77.hh = i2c_readAck();
dcf77.dd = i2c_readAck();
dcf77.mt = i2c_readAck();
dcf77.yy = i2c_readAck();
dcf77.wd = i2c_readAck();
dcf77.mez = i2c_readAck();
dcf77.mesz = i2c_readNak();
i2c_stop();
return 0;
}
//*********************************************************************
ISR(TIMER1_OVF_vect)
{
// Preload setzen
TCNT1 = PRELOAD;
// ... mach was in der Hauptschleife
click= 1;
// welcher Mode (Datum, Uhrzeit, Temperatur)?
mode_counter++;
if (mode_counter > MODE_CHANGE_VALUE) {
mode_counter=0;
mode++;
if (mode > MODE_TEMP) mode=MODE_DATE;
}
}
//*********************************************************************
void print_time(void)
{
digit_to_SDA5708(dcf77.hh/10+0x30, 0);
digit_to_SDA5708(dcf77.hh-dcf77.hh/10*10+0x30, 1);
digit_to_SDA5708(dcf77.mm/10+0x30, 3);
digit_to_SDA5708(dcf77.mm-dcf77.mm/10*10+0x30, 4);
digit_to_SDA5708(dcf77.ss/10+0x30, 6);
digit_to_SDA5708(dcf77.ss-dcf77.ss/10*10+0x30, 7);
digit_to_SDA5708(':', 2);
digit_to_SDA5708(':', 5);
}
//*********************************************************************
void print_date(void)
{
digit_to_SDA5708(dcf77.dd/10+0x30, 0);
digit_to_SDA5708(dcf77.dd-dcf77.dd/10*10+0x30, 1);
digit_to_SDA5708(dcf77.mt/10+0x30, 3);
digit_to_SDA5708(dcf77.mt-dcf77.mt/10*10+0x30, 4);
digit_to_SDA5708(dcf77.yy/10+0x30, 6);
digit_to_SDA5708(dcf77.yy-dcf77.yy/10*10+0x30, 7);
digit_to_SDA5708('.', 2);
digit_to_SDA5708('.', 5);
}
//*********************************************************************
void print_temp(void)
{
// Verzeichen ermitteln
if (h_temp >= 128) {
h_temp = ~(h_temp);
h_temp++;
digit_to_SDA5708('-',0);
} else {
digit_to_SDA5708('+',0);
}
// 100ter-Stelle
if (h_temp/100) {
digit_to_SDA5708(h_temp/100+0x30, 1);
} else {
digit_to_SDA5708(' ', 1);
}
// 10er-Stelle
if (h_temp/10) {
digit_to_SDA5708(h_temp/10+0x30, 2);
} else {
digit_to_SDA5708(' ', 2);
}
// 1er-Stelle
digit_to_SDA5708(h_temp-h_temp/10*10+0x30, 3);
// Nachkomma
if (l_temp >= 128) {
digit_to_SDA5708('5',5);
} else {
digit_to_SDA5708('0',5);
}
digit_to_SDA5708(',',4);
// in meinem Zeichensatz ist | das °-Zeichen ... ;-)
digit_to_SDA5708('|',6);
digit_to_SDA5708('C',7);
}
//*********************************************************************
//*********************************************************************
//*********************************************************************
int main(void)
{
// LED-PIN als Ausgang und ausschalten
LED_DDR = (1 << LED_PIN);
LED_PORT &= ~(1 << LED_PIN);
// Timerinterrupt konfigurieren
TCNT1 = PRELOAD;
TCCR1B |= (1 << CS02) | (1 << CS00);
TIMSK |= (1 << TOIE1);
// ... und Interrupts einschalten
sei();
// Port-Initialisierung fuer Display
init_SDA5708();
// Helligkeit Display einstellen
brightness_SDA5708(1);
// TWI-Zeugs initialisieren
i2c_init();
lm75_init();
while(1){
// ... es gibt was zu tun...
if (click) {
click = 0;
LED_PORT ^= (1 << LED_PIN);
// ... was gibt es zu tun?
switch (mode) {
// Datum anzeigen
case MODE_DATE: {
dcf77_read();
print_date();
break;
}
// Zeit anzeigen
case MODE_TIME: {
dcf77_read();
print_time();
break;
}
// Temperatur anzeigen
case MODE_TEMP: {
lm75_read();
print_temp();
break;
}
}
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
SDA-5708-Clock.rar_sda5708
共8个文件
c:3个
h:3个
makefile:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 190 浏览量
2022-09-23
13:21:32
上传
评论
收藏 16KB RAR 举报
温馨提示
SDA-5708 Atmega8 clock source...
资源推荐
资源详情
资源评论
收起资源包目录
SDA-5708-Clock.rar (8个子文件)
SDA-5708 Clock
main.c 7KB
twimaster.c 6KB
i2cmaster.h 6KB
i2cmaster.S 9KB
Makefile 827B
font.h 12KB
i2clcd.c 7KB
i2clcd.h 14KB
共 8 条
- 1
资源评论
林当时
- 粉丝: 95
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功