initial commit

This commit is contained in:
2026-09-25 10:48:51 +10:00
commit b90beea8ae
1020 changed files with 131665 additions and 0 deletions
+405
View File
@@ -0,0 +1,405 @@
/********************************************************
* Clock Library for Studuino mini
* 2016/3/29 ArTec Co.,Ltd.
* Software SPI
*
*
********************************************************/
#include "Clock.h"
volatile clockparams_t clockparams;
byte rFirst;
unsigned long lastUpdateTime;
unsigned long lastUpdateDate;
unsigned long lastUpdateAlarm;
unsigned long lastUpdateMode;
unsigned long lastUpdateTemp;
boolean fSending;
byte alarmState; // 0:off 1:on 2:snooze
boolean fOnAlarm; // false:off true:on
boolean pushMonitor;
boolean fBackLightOff;
unsigned long lastPushTime;
unsigned long t2counter;
//割り込み関数
// Pushボタン、Alarmボタンの監視をする
ISR(TIMER1_COMPB_vect)
{
if(pushMonitor) {
byte pushed = (clockparams.mode >> 6) & 0x01;
byte almode = (clockparams.mode >> 2) & 0x03;
if(pushed == 1) {
if(alarmState == 1) {
alarmState = 0;
if(fOnAlarm) {
noTone(8);
fBackLightOff = true;
fOnAlarm = false;
pushMonitor = false;
lastPushTime = clockparams.hour * 60 + clockparams.minute;
}
}
}
if(almode == 0) {
alarmState = 0;
if(fOnAlarm) {
noTone(8);
fBackLightOff = true;
fOnAlarm = false;
pushMonitor = false;
lastPushTime = clockparams.hour * 60 + clockparams.minute;
}
}
} else {
if(fBackLightOff) {
byte data[3];
data[0] = 0xa5;
data[1] = 0;
data[2] = 0;
writeCommand(data, 3);
fBackLightOff = false;
}
}
if(lastPushTime != (clockparams.hour * 60 + clockparams.minute)) alarmState = 1;
}
ISR(TIMER2_OVF_vect)
{
t2counter++;
}
void writeCommand(byte* command, byte length) {
fSending = true;
rFirst = 1;
for(byte i = 0; i < length; i++) {
writeByteData(command[i]);
}
delayMicroseconds(DELAY1);
fSending = false;
}
byte writeByteData(byte _send) { // This function is what bitbangs the data
byte Read_Write_Count = 0;
for(Read_Write_Count = 0; Read_Write_Count < 8; Read_Write_Count++) { // There are 8 bits in a byte
PORTB |= B00100000; // SCK high
delayMicroseconds(DELAY_WRITE1); // Delay_2US(100);
if(_send & 0x80) {
PORTB |= B00001000; // MOSI high
} else {
PORTB &= B11110111; // MOSI low
}
delayMicroseconds(DELAY_WRITE2); // Delay_2US(30);
_send = (_send << 1);
PORTB &= B11011111; // SCK low
if(rFirst) {
rFirst = 0;
delayMicroseconds(DELAY_WRITE3); // Delay_2US(2000);
} else {
delayMicroseconds(DELAY_WRITE4); // Delay_2US(100);
}
}
PORTB |= B00101000; // MOSI, SCK high
return _send; // Return the received data
}
byte readByteData() { // This function is what bitbangs the data
byte Read_Write_Count = 0;
byte _receive = 0;
rFirst = 1;
for(Read_Write_Count = 0; Read_Write_Count < 8; Read_Write_Count++) { // There are 8 bits in a byte
PORTB |= B00100000; // SCK high
delayMicroseconds(DELAY_READ1); // Delay_2US(100);
PORTB &= B11011111; // SCK low
if(rFirst) {
rFirst = 0;
delayMicroseconds(DELAY_READ2); // Delay_2US(2000);
} else {
delayMicroseconds(DELAY_READ3); // Delay_2US(50);
}
_receive = _receive << 1;
if(digitalRead(MISO_pin))
_receive |= 0x01;
delayMicroseconds(DELAY_READ4); // Delay_2us(60);
PORTB |= B00100000; // SCK high
delayMicroseconds(DELAY_READ5); // Delay_2US(80);
}
delayMicroseconds(DELAY_READ6); // Delay_2US(200);
PORTB |= B00100000; // SCK high
return _receive; // Return the received data
}
// update functions
void updateTime() { // 0: hour 1: minute
if(!fSending) {
if(millis() - lastUpdateTime + T2CYCLE * t2counter > UPD_INTVAL_TIME) {
rFirst = 1;
writeByteData(0xb1);
byte buf = readByteData();
clockparams.hour = (buf / 16) * 10 + (buf % 16);
buf = readByteData();
clockparams.minute = (buf / 16) * 10 + (buf % 16);
lastUpdateTime = millis() + T2CYCLE * t2counter;
}
}
}
void updateDate() {
if(!fSending) {
if(millis() - lastUpdateDate + T2CYCLE * t2counter > UPD_INTVAL_DATE) {
rFirst = 1;
writeByteData(0xb2);
byte buf = readByteData();
clockparams.year = 2000 + (buf / 16) * 10 + (buf % 16);
buf = readByteData();
clockparams.month = (buf / 16) * 10 + (buf % 16);
buf = readByteData();
clockparams.day = (buf / 16) * 10 + (buf % 16);
lastUpdateDate = millis() + T2CYCLE * t2counter;
}
}
}
void updateMode() {
if(!fSending) {
if(millis() - lastUpdateMode + T2CYCLE * t2counter > UPD_INTVAL_MODE) {
rFirst = 1;
writeByteData(0xb3);
clockparams.mode = readByteData();
lastUpdateMode = millis() + T2CYCLE * t2counter;
}
}
}
void updateAlarm() {
if(!fSending) {
if(millis() - lastUpdateAlarm + T2CYCLE * t2counter > UPD_INTVAL_ALARM) {
rFirst = 1;
writeByteData(0xb4);
byte buf = readByteData();
clockparams.alhour = (buf / 16) * 10 + buf % 16;
buf = readByteData();
clockparams.alminute = (buf / 16) * 10 + buf % 16;
lastUpdateAlarm = millis() + T2CYCLE * t2counter;
}
}
}
void updateTemperature() {
if(!fSending) {
if(millis() - lastUpdateTemp + T2CYCLE * t2counter > UPD_INTVAL_TEMP) {
rFirst = 1;
writeByteData(0xb5);
byte data[2];
data[0] = readByteData();
data[1] = readByteData();
byte var = data[0] / 16;
clockparams.temperature = (data[0] % 16) * 100 + (data[1] / 16) * 10 + (data[1] % 16);
if(var != 0)
clockparams.temperature = 1000 - clockparams.temperature;
lastUpdateTemp = millis() + T2CYCLE * t2counter;
}
}
}
void updateAll() {
fSending = true;
updateTime();
delayMicroseconds(5000);
updateDate();
delayMicroseconds(5000);
updateAlarm();
delayMicroseconds(5000);
updateMode();
delayMicroseconds(5000);
fSending = false;
}
/***** Clock class function definitions *****/
Clock::Clock() {
}
// 液晶時計に使用するピンを初期化し、SCK_pinをHIGHに設定する
void Clock::initClockPinSet() {
pinMode(SCK_pin, OUTPUT);
pinMode(MISO_pin, INPUT);
pinMode(MOSI_pin, OUTPUT);
pinMode(BZR_pin, OUTPUT);
digitalWrite(SCK_pin, HIGH);
digitalWrite(MOSI_pin, HIGH);
// タイマー1コンペアB割り込みを使用する。
// Servoライブラリが使用するコンペアAの設定と合わせる。
TCCR1A = 0b00000000;
TCCR1B = 0b00000010;
OCR1BH = 0x00;
OCR1BL = 0xff;
TIMSK1 |= 0b00000100;
// タイマー2オーバーフロー割り込みを使用する
TCCR2A = 0;
TCCR2B = 7; // 分周比 1/1024
delay(2000);
TIMSK2 = 1;
alarmState = 1;
}
/* :::::::::::::: 設定用関数 ::::::::::::::::::::::::::: */
// 時間の設定
void Clock::setTime(byte hour, byte minute) {
byte data[3];
data[0] = 0xa1;
data[1] = (hour / 10) * 16 + (hour % 10);
data[2] = (minute / 10) * 16 + (minute % 10);
writeCommand(data, 3);
}
// 日付の設定
void Clock::setDate(byte year, byte month, byte day) {
byte data[4];
data[0] = 0xa2;
data[1] = (year / 10) * 16 + (year % 10);
data[2] = (month / 10) * 16 + (month % 10);
data[3] = (day / 10) * 16 + (day % 10);
writeCommand(data, 4);
}
// 12h/24h, C/Fの設定
void Clock::setTimeTempMode(byte mode) {
byte data[2];
data[0] = 0xa3;
data[1] = mode;
writeCommand(data, 2);
}
// アラーム時間の設定
void Clock::setAlarm(byte hour, byte minute) {
byte data[3];
data[0] = 0xa4;
data[1] = (hour / 10) * 16 + (hour % 10);
data[2] = (minute / 10) * 16 + (minute % 10);
writeCommand(data, 3);
}
// 液晶バックライトの設定
void Clock::setBackLight(boolean on, byte red, byte green, byte blue) {
byte data[3];
data[0] = 0xa5;
data[1] = on * 16 + red;
data[2] = blue * 16 + green;
writeCommand(data, 3);
delay(50); // Only for this function.
}
/* :::::::::::::: データ取得用関数 ::::::::::::::::::::::::::: */
// 時間取得
byte Clock::getHour() {
updateTime();
return clockparams.hour;
}
byte Clock::getMinute() {
updateTime();
return clockparams.minute;
}
// 日付取得
unsigned int Clock::getYear() {
updateDate();
return clockparams.year;
}
byte Clock::getMonth() {
updateDate();
return clockparams.month;
}
byte Clock::getDay() {
updateDate();
return clockparams.day;
}
// モード取得
byte Clock::getMode() {
updateMode();
return clockparams.mode;
}
byte Clock::getTimeMode() {
return getMode() % 2;
}
byte Clock::getTempMode() {
return (getMode() >> 1) % 2;
}
byte Clock::getAlarmMode() {
return (getMode() >> 2) & 0x03;
}
byte Clock::getPushed() {
return (getMode() >> 6) & 0x01;
}
// アラーム時間取得
byte Clock::getAlarmHour() {
updateAlarm();
return clockparams.alhour;
}
byte Clock::getAlarmMinute() {
updateAlarm();
return clockparams.alminute;
}
// 温度取得
int Clock::getTemperature() {
updateTemperature();
return clockparams.temperature;
}
boolean Clock::isAlarmTime() {
if(getAlarmMode() == 0) return false;
int delta = (getHour() - getAlarmHour()) * 60 + (getMinute() - getAlarmMinute());
if(getAlarmMode() == 1 && (delta != 0)) return false;
if(getAlarmMode() == 2 && ((delta % SNOOZE_TIME) != 0)) return false; // Snooze
if(alarmState == 0) return false;
//TIMSK1 |= 0b00000100; //アラーム時間になった時のみ、Timer1でプッシュボタンを監視する
pushMonitor = true;
fOnAlarm = true;
return true;
}
void Clock::buzzer(boolean on, unsigned int frequency) {
if(on) {
if(alarmState == 1) {
updateMode();
tone(BZR_pin, frequency);
}
} else {
noTone(BZR_pin);
}
}
void Clock::buzzer(unsigned int frequency, unsigned long duration) {
if(alarmState == 1) {
updateMode();
tone(BZR_pin, frequency);
delay(duration);
noTone(BZR_pin);
}
}
+115
View File
@@ -0,0 +1,115 @@
#ifndef __CLOCK_H__
#define __CLOCK_H__
#include <Arduino.h>
//#define SS_pin SS // 10
#define SCK_pin SCK // 13
#define MISO_pin MISO // 12
#define MOSI_pin MOSI // 11
#define BZR_pin 8
#define STUDUINO_MINI 1
#ifdef STUDUINO_MINI
// Delay time after writeCommand.
#define DELAY1 10000 // > 5000 * 1.5
// Delay times for write.
#define DELAY_WRITE1 300 // Delay_2US(100);
#define DELAY_WRITE2 90 // Delay_2US(30);
#define DELAY_WRITE3 6000 // Delay_2US(2000);
#define DELAY_WRITE4 300 // Delay_2US(100);
// Delay times for read.
#define DELAY_READ1 300 // Delay_2US(100);
#define DELAY_READ2 6000 // Delay_2US(2000);
#define DELAY_READ3 150 // Delay_2US(50);
#define DELAY_READ4 180 // Delay_2us(60);
#define DELAY_READ5 240 // Delay_2US(80);
#define DELAY_READ6 600 // Delay_2US(200);
#else
// Delay time after writeCommand.
#define DELAY1 6000 // > 5000 * 1.5
// Delay times for write.
#define DELAY_WRITE1 200 // Delay_2US(100);
#define DELAY_WRITE2 60 // Delay_2US(30);
#define DELAY_WRITE3 4000 // Delay_2US(2000);
#define DELAY_WRITE4 200 // Delay_2US(100);
// Delay times for read.
#define DELAY_READ1 200 // Delay_2US(100);
#define DELAY_READ2 4000 // Delay_2US(2000);
#define DELAY_READ3 100 // Delay_2US(50);
#define DELAY_READ4 120 // Delay_2us(60);
#define DELAY_READ5 160 // Delay_2US(80);
#define DELAY_READ6 400 // Delay_2US(200);
#endif
#define KEYTONE_ENABLE 0x10
#define ALARM_FNCT_ENABLE 0x20
#define T2CYCLE (256 * 1024UL / (F_CPU / 1000)) // 21.3ms@12MHz
typedef struct {
byte hour;
byte minute;
byte year;
byte month;
byte day;
int temperature;
byte mode;
byte alhour;
byte alminute;
}clockparams_t;
extern volatile clockparams_t clockparams;
void updateTest();
void writeCommand(byte* command, byte length);
byte writeByteData(byte _send);
byte readByteData();
void updateAll();
void updateAlarm();
void updateDate();
void updateTemperature();
void updateMode();
#define REGET_TH 1000
#define UPD_INTVAL_TIME 1000
#define UPD_INTVAL_DATE 1000
#define UPD_INTVAL_ALARM 1000
#define UPD_INTVAL_TEMP 1000
#define UPD_INTVAL_MODE 200
#define SNOOZE_TIME 5 // in minute
class Clock {
private:
public:
Clock();
void initClockPinSet(void);
void setTime(byte hour, byte minute);
void setDate(byte year, byte month, byte day);
void setTimeTempMode(byte mode);
void setAlarm(byte hour, byte minute);
void setBackLight(boolean on, byte red, byte green, byte blue);
byte getHour();
byte getMinute();
unsigned int getYear();
byte getMonth();
byte getDay();
byte getMode();
byte getTimeMode();
byte getTempMode();
byte getAlarmMode();
byte getPushed();
byte getAlarmHour();
byte getAlarmMinute();
int getTemperature();
boolean isAlarmTime();
void buzzer(boolean on, unsigned int frequency);
void buzzer(unsigned int frequency, unsigned long duration);
};
#endif // __CLOCK_H__