2012年8月16日木曜日

年月日時分秒からUNIXtimeに

年月日時分秒をUNIXtime(秒)に変換する関数です



 int YMDhms2s(int Y, int M, int D, int h, int m, int s) {
    int y = Y - 1970;
    int res = 0;
    while(y > 0) {
        if ((y % 4) == 0 && (y % 100) != 0 || (y % 400) == 0) {
            res += 31622400;
        } else {
            res += 31536000;
        }
        y--;
    }
   
    switch(M - 1)
    {
    case(12): { res += 2678400; }
    case(11): { res += 2592000; }
    case(10): { res += 2678400; }
    case( 9): { res += 2592000; }
    case( 8): { res += 2678400; }
    case( 7): { res += 2678400; }
    case( 6): { res += 2592000; }
    case( 5): { res += 2678400; }
    case( 4): { res += 2592000; }
    case( 3): { res += 2678400; }
    case( 2): {
        if ((Y % 4) == 0 && (Y % 100) != 0 || (Y % 400) == 0) {
            res += 2505600;
        } else {
            res += 2419200; }
              }
    case( 1): { res += 2678400; }
    default : { break; }
    }

    res += (D - 1) * 86400;

    res += h * 3600;
    res += m * 60;
    res += s;
   
    return(res);
}

まずは年を秒に変換します
めんどくさいのでwhileを使いましたが
すっげー遅くなるので本来は使うべきではない

次に月を秒に変換しますが
ここは
1. 1ヶ月の長さがまちまち
2. 2月は閏年を考慮する必要がある
という理由により
switchを使っています

そして日 時 分 秒をそれぞれ計算していきます
流れとしては非常に簡単
一応正常に動いてるっぽいので 大丈夫なはずです

なお閏年判定のコードはwikipediaから拝借しました

このコードはUNIXtimeに変換するものですが
定数の変更でNTPtimeも対応可能なはずです

前にUNIXtimeを文字列に変換する関数もおいてるので
それと組み合わせれば色々と遊べます
まぁ組み込みとかの内の一部用途でしか使い道無いんですが

一応32bitだと2100年くらいまで処理できるので
しばらくの間は大丈夫だと思います

2012年8月15日水曜日

年月日から曜日を計算する

年月日から曜日を取り出す関数です


#include <stdio.h>

int ymd2w(int _y, int m, int q) {
    int J = _y / 100,
        K = _y % 100;
    return((q + (((m + 1)*26) / 10) + K + (K / 4) + (J / 4) - (2 * J)) % 7);
}

int main(void) {

    printf("%d\n", ymd2w(2012, 8, 15));

    return(0);
}
  
楽っすねー
関数じゃなくて マクロで実装したほうが便利かもしれないけど

今回は
を参考にしました

ちなみに
この関数からの戻り値は
日曜=1
月曜=2
...
金曜=6
土曜=7
になるので
コードによっては というか かなりの場合 デクリメントしないと正常な値として扱えません

つーことで
年月日から曜日を計算するコードでした

2012年8月14日火曜日

strstr 関数

strstr関数です
文字列の中から文字列を検索しポインタを返却
という感じの関数です
GCCでコンパイルしたら警告出ます
const charをcharとして戻り値に入れてるからだと思いますが


標準ライブラリ

自分でちょこちょこ作ってる標準ライブラリの関数を
ここに貼り付けることにします
理由:あとで探すのめんどくさくなってきた

最低限の動作確認はしていますが
ホンモノとまったく同じ動きをするという保証はどこにもないので
あまり使わないほうが懸命です

string.h周りが多くなると思いますが

2012年8月11日土曜日

自作strtok関数

GPSのデータのデコードにstrtokを使ったら楽なんじゃないかな
とか思って 自分で作ってみました

本来のstrtokは
char *strtok(char *s1, const char *s2);
ですが
今回はそんなに高性能じゃなくてもいいので
uint8_t *StrtokB(uint8_t *s1, const char s2);
として
複数の文字を指定する機能は付けていません

以下コード

2012年8月8日水曜日

キャラ液晶とスイッチの共存

トライステートの電波時計(秋月)の回路図を見ていると面白い回路が含まれています


PICと液晶の間になにやらスイッチが入っています


通常キャラ液晶には6本のIOが専有されます
(最大で11本が専有されるモードがありますが まぁ 普通は使いません)

で そのうち5本は基本的に他の用途にも使うことが可能です
そのうちキリのいい4本をスイッチに使っているわけです
(LCDのE端子は他の用途に使うことができません)


どのマイコンでもIO不足は深刻なので
これをSTBeeMiniで試してみます

回路は↓こんな感じ

今回はスイッチを8個使います
また抵抗とかめんどくさいのと スイッチ数を増やしたかったので
ポートでGNDに落とします
これはオープンドレイン動作が有るARMならではといったところです
PICだとめんどくさいですねー

この回路であれば大量のスイッチを使用することや
スイッチが押されているときにLCDの操作が有っても問題なく使用可能です


御存知の通りLCDの中にはプルアップ抵抗がありますが
どーもこの回路ではそのプルアップ抵抗を期待できないらしいです
ということで 今回は4本のポートにGPIO_Mode_IPUを指定することで正常に動作するようにしています


とりあえず今回はこんなところで
追ってソースコードをサブページにおいておくと思います