ソースコードはこちらからダウンロードすることもできます。
データ変換ツールはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
#pragma config FEXTOSC = OFF // FEXTOSC External Oscillator mode Selection bits (Oscillator not enabled) #pragma config RSTOSC = HFINT1 // Power-up default value for COSC bits (HFINTOSC (1MHz)) #pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2) #pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) #pragma config MCLRE = ON // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config WDTE = OFF // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored) #pragma config LPBOREN = OFF // Low-power BOR enable bit (ULPBOR disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled) #pragma config BORV = LOW // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V) #pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle) #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will not cause a Reset) #pragma config DEBUG = OFF // Debugger enable bit (Background debugger disabled) #pragma config WRT = OFF // User NVM self-write protection bits (Write protection off) #pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/VPP must be used for programming.) #pragma config CP = OFF // User NVM Program Memory Code Protection bit (User NVM code protection disabled) #pragma config CPD = OFF // Data NVM Memory Code Protection bit (Data NVM code protection disabled) #include <xc.h> #include "sed1520.h" #include "i2c.h" #include "bme280.h" #define _XTAL_FREQ 125000 //クロックダウン後の周波数 #define DS 0b1101000 enum Mode { SEC = 0, MIN, HOUR, DAY, DATE, MONTH, YEAR, IDLE = 255} mode; //主に時刻設定時に使用 const char background[488] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x30,0x0C,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x04,0x04,0x78,0x00,0x7F,0x11,0x11,0x0E,0x00,0x20,0x54,0x54,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; const char largeNum[36*11] = {0x00,0xE0,0xFC,0x7E,0x0F,0x07,0x07,0x07,0x0F,0x7E,0xFC,0xE0,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x01,0x07,0x07,0x0E,0x0E,0x0E,0x07,0x07,0x01,0x00,0x00,0x00,0x00,0x18,0x18,0x1C,0xFE,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0xF8,0xFE,0x0E,0x07,0x03,0x07,0x0F,0xFE,0xFC,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF8,0x3C,0x1F,0x07,0x03,0x00,0x00,0x0E,0x0F,0x0F,0x0D,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x38,0x3E,0x0E,0x07,0x03,0x03,0x0F,0xFE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x1F,0xFB,0xF1,0xC0,0x00,0x00,0x03,0x07,0x0E,0x0E,0x0E,0x0E,0x07,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x7C,0x1F,0xFF,0xFF,0x00,0x00,0x00,0xF0,0xFC,0xDF,0xC7,0xC1,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0x07,0x87,0x87,0x87,0x87,0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x03,0x01,0x01,0x01,0x03,0xFF,0xFE,0xF8,0x00,0x00,0x03,0x07,0x06,0x0E,0x0E,0x0E,0x07,0x07,0x01,0x00,0x00,0x00,0xF0,0xFC,0x1E,0x87,0x83,0x83,0x87,0x3E,0x3C,0x00,0x00,0x7E,0xFF,0xFF,0x07,0x03,0x03,0x03,0x07,0xFF,0xFC,0xF0,0x00,0x00,0x01,0x03,0x07,0x0E,0x0E,0x0E,0x0F,0x07,0x03,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0xC7,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF0,0xFE,0x3F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFE,0x0F,0x03,0x03,0x03,0x0F,0xFE,0xFC,0x00,0x00,0xC0,0xF1,0xFB,0x1F,0x0E,0x0E,0x0E,0x1F,0xFB,0xF1,0xC0,0x00,0x00,0x03,0x07,0x0E,0x0E,0x0E,0x0E,0x0E,0x07,0x03,0x00,0x00,0xE0,0xFC,0xFE,0x0F,0x03,0x03,0x07,0x0E,0xFC,0xF8,0xC0,0x00,0x01,0x0F,0x1F,0x38,0x30,0x30,0x18,0x0C,0xFF,0xFF,0xFF,0x00,0x00,0x03,0x07,0x0E,0x0E,0x0E,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; const char smallNum[5*11] = {0x00,0x3E,0x41,0x41,0x3E,0x00,0x00,0x02,0x7F,0x00,0x00,0x62,0x51,0x49,0x46,0x00,0x22,0x41,0x49,0x36,0x00,0x1E,0x11,0x7F,0x10,0x00,0x2F,0x49,0x49,0x31,0x00,0x3E,0x49,0x49,0x32,0x00,0x01,0x71,0x0D,0x03,0x00,0x36,0x49,0x49,0x36,0x00,0x26,0x49,0x49,0x3E,0x00,0x00,0x00,0x00,0x00}; const char dayData[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x11,0x11,0x11,0x11,0x11,0x11,0xFF,0xFF,0x00,0x00,0x00,0x40,0x60,0x38,0x1F,0x07,0x01,0x01,0x01,0x01,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x80,0xFF,0xFF,0x80,0x00,0x40,0x60,0x30,0x10,0x00,0x40,0x40,0x60,0x30,0x18,0x0E,0x07,0x01,0x01,0x07,0x0E,0x18,0x30,0x60,0x40,0x40,0x10,0x10,0x10,0x10,0xD0,0xF0,0x30,0xFF,0xFF,0xF8,0xC0,0xC0,0x60,0x30,0x18,0x08,0x10,0x18,0x0C,0x07,0x03,0x40,0x40,0x7F,0x7F,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x08,0x08,0x08,0x08,0x08,0xC8,0xE8,0xFF,0xFF,0xE8,0xC8,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x0C,0x06,0x03,0x01,0x00,0x7F,0x7F,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x40,0x40,0x60,0x30,0x58,0x4C,0x46,0xC3,0xC3,0x46,0x4C,0x58,0x30,0x60,0x40,0x40,0x40,0x42,0x42,0x4A,0x7A,0x72,0x42,0x7F,0x7F,0x42,0x62,0x7A,0x5A,0x42,0x42,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0xFE,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x7F,0x00,0x00,0x00}; //0: ' ', 1: 月, ... 7: 日 const char maxList[] = {0x60, 0x60, 0x24, 0x08, 0x32, 0x13, 0xA0}; //BCDフォーマット char dateTime[7]; int temp, hum, pres; char measureFlag = 0; void PrintLargeNum(char add, char num, char mask){ int offset = 36*num; //1文字36byte for(char i=0; i<3; i++){ Sed_SetAddress(i, 12*add); //1文字12列 for(char j=0; j<12; j++){ Sed_Dat(largeNum[offset] ^ mask); offset++; } } } void PrintSmallNum(char num, char mask){ int offset = 5*num; //1文字5byte for(char i=0; i<5; i++){ //1文字5列 Sed_Dat(smallNum[offset + i] ^ mask); } } void PrintDay(char mask){ int offset = 32*dateTime[DAY]; //1文字32byte for(char i=0; i<2; i++){ Sed_SetAddress(2+i, 104); for(char j=0; j<16; j++){ Sed_Dat(dayData[offset] ^ mask); offset++; } } } void Prints(char target, char mask){ //時刻、日時を表示 char buf; switch(target){ case SEC: PrintLargeNum(6, (dateTime[SEC] >> 4) & 0x0F, mask); //10の位 PrintLargeNum(7, dateTime[SEC] & 0x0F, mask); // 1の位 break; case MIN: PrintLargeNum(3, (dateTime[MIN] >> 4) & 0x0F, mask); //10の位 PrintLargeNum(4, dateTime[MIN] & 0x0F, mask); // 1の位 break; case HOUR: buf = (dateTime[HOUR] >> 4) & 0x0F; //10の位 if(buf == 0) buf = 10; // 0消し PrintLargeNum(0, buf, mask); PrintLargeNum(1, dateTime[HOUR] & 0x0F, mask); // 1の位 break; case DAY: PrintDay(mask); break; case DATE: Sed_SetAddress(1, 112); buf = (dateTime[DATE] >> 4) & 0x0F; if(buf == 0) buf = 10; PrintSmallNum(buf, mask); PrintSmallNum(dateTime[DATE] & 0x0F, mask); break; case MONTH: Sed_SetAddress(1, 97); buf = (dateTime[MONTH] >> 4) & 0x0F; if(buf == 0) buf = 10; PrintSmallNum(buf, mask); PrintSmallNum(dateTime[MONTH] & 0x0F, mask); break; case YEAR: Sed_SetAddress(0, 102); PrintSmallNum(2, mask); PrintSmallNum(0, mask); PrintSmallNum((dateTime[YEAR] >> 4) & 0x0F, mask); PrintSmallNum(dateTime[YEAR] & 0x0F, mask); break; } } void GetDateTime(){ //DS1307のアドレス0-6を取得しdataTime[]に格納 SendI2C(DS, 0); GetDataI2C(DS, dateTime, 7); } void SetDateTime(){ for(char i=0; i<7; i++){ CmdI2C(DS, i, dateTime[i]); } CmdI2C(DS, 7, 0x10); // 1Hz output } void BCDincrement(char* c){ (*c)++; if((*c & 0x0F) == 10) *c += 6; //繰り上がり -10 + 16 } void PrintWeather(){ char buf[4]; //気温 buf[0] = temp / 100; //100の位 if(buf[0] == 0) buf[0] = 10; // 0消し buf[1] = (temp / 10) % 10; // 10の位 buf[2] = temp % 10; // 1の位 Sed_SetAddress(3, 6); PrintSmallNum(buf[0], 0); PrintSmallNum(buf[1], 0); Sed_SetAddress(3, 18); PrintSmallNum(buf[2], 0); //湿度 buf[0] = hum / 100; if(buf[0] == 0) buf[0] = 10; buf[1] = (hum / 10) % 10; if((buf[0] == 10) && (buf[1] == 0)) buf[1] = 10; buf[2] = hum % 10; Sed_SetAddress(3, 33); for(char i=0; i<3; i++){ PrintSmallNum(buf[i], 0); } //気圧 buf[0] = pres / 1000; if(buf[0] == 0) buf[0] = 10; buf[1] = (pres / 100) % 10; buf[2] = (pres / 10) % 10; buf[3] = pres % 10; Sed_SetAddress(3, 61); for(char i=0; i<4; i++){ PrintSmallNum(buf[i], 0); } } void Init(){ TRISA = 0b00001011; ANSELA = 0; WPUA = 0b00001011; PORTA = 0; TRISB = 0b11110000; ANSELB = 0; WPUB = 0b10100000; PORTB = 0; TRISC = 0; ANSELC = 0; WPUC = 0; PORTC = 0; PMD0 = 0b01111110; //Enabled Periferals: PMD1 = 0xFF; // SystemClock PMD2 = 0xFF; // IOC PMD3 = 0xFF; // MSSP1 PMD4 = 0b11111101; PMD5 = 0xFF; IOCAN = 0b00000011; IOCAP = 0b00000011; IOCBN = 0b10000000; IOCIE = 1; PEIE = 1; } void main(void) { Init(); Sed_Init(); for(int i=0; i<488; i++){ Sed_Dat(background[i]); } I2C_Master_Init(10000); bme_Init(); measureFlag = 1; GetDateTime(); for(char i = SEC; i<= YEAR; i++){ Prints(i, 0); } //クロックダウン、割込み開始 GIE = 1; OSCFRQbits.HFFRQ = 0b0000; // 1 MHz OSCCON1bits.NDIV = 0b0011; // 1/8 = 125 kHz while(1){ if(measureFlag){ measureFlag = 0; bme_ForceMeasurement(&temp, &hum, &pres); PrintWeather(); } SLEEP(); //消費電力低減(効果あるのかは不明) } } void __interrupt isr(){ GIE = 0; if(IOCAFbits.IOCAF0){ //START IOCAFbits.IOCAF0 = 0; static char sw0 = 1; __delay_ms(1); //チャタリング回避 if((RA0 == 0) && (sw0 == 1)){ // if(mode == IDLE){ //時刻設定開始 mode = SEC; Prints(mode, 0xFF); //マスク IOCBNbits.IOCBN7 = 0; //クロック入力停止 } else if(mode == YEAR){ //時刻設定完了 Prints(mode, 0); //マスク解除 SetDateTime(); mode = IDLE; IOCBNbits.IOCBN7 = 1; //クロック入力再開 } else{ Prints(mode, 0); //マスク解除 mode++; //設定項目移動 Prints(mode, 0xFF); //マスク } sw0 = 0; } else if((RA0 == 1) && (sw0 == 0)){ sw0 = 1; } } if(IOCAFbits.IOCAF1){ //SELECT IOCAFbits.IOCAF1 = 0; static char sw1 = 1; __delay_ms(1); if((RA1 == 0) && (sw1 == 1)){ if(mode != IDLE){ BCDincrement(&dateTime[mode]); if(dateTime[mode] >= maxList[mode]) dateTime[mode] = 0; Prints(mode, 0xFF); } sw1 = 0; } else if((RA1 == 1) && (sw1 == 0)){ sw1 = 1; } } if(IOCBFbits.IOCBF7){ //1Hzクロック入力 IOCBFbits.IOCBF7 = 0; BCDincrement(&dateTime[SEC]); if(dateTime[SEC] == 0x60){ dateTime[SEC] = 0; BCDincrement(&dateTime[MIN]); if(dateTime[MIN] == 0x60){ dateTime[MIN] = 0; BCDincrement(&dateTime[HOUR]); if(dateTime[HOUR] == 0x24){ dateTime[HOUR] = 0; GetDateTime(); for(char i=DAY; i<= YEAR; i++) Prints(i, 0); } Prints(HOUR, 0); } Prints(MIN, 0); measureFlag = 1; //1分ごとに気象データ測定 } Prints(SEC, 0); } GIE = 1; } |
▼グラフィックLCDライブラリ
1 2 3 4 |
void Sed_Cmd(char c); void Sed_Dat(char c); void Sed_SetAddress(char page, char column); void Sed_Init(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#include <xc.h> #include "sed1520.h" #define _XTAL_FREQ 125000 #define A0 RA2 #define E1 RA5 #define E2 RA4 #define DATAPORT PORTC char currentPage = 0; // データ送信先の判断とページインクリメントの char currentColumn = 0; // ために現在のアドレスを保持 void Sed_Cmd(char c){ // コマンドは両方の制御ICに送信 A0 = 0; DATAPORT = c; E1 = 1; E2 = 1; E1 = 0; E2 = 0; __delay_us(40); } void Sed_Dat(char c){ A0 = 1; DATAPORT = c; if(currentColumn < 61){ // 送信先判断 E1 = 1; E1 = 0; } else{ E2 = 1; E2 = 0; } currentColumn++; // コラム自動インクリメント if(currentColumn == 122){ // ページ手動インクリメント currentColumn = 0; currentPage = (currentPage + 1) % 4; Sed_SetAddress(currentPage, currentColumn); } __delay_us(40); } void Sed_SetAddress(char page, char column){ currentPage = page; currentColumn = column; Sed_Cmd(0b10111000 + page); // 両方ともページセット if(column < 61){ // 前半の場合は後半のコラムを0にするのも DATAPORT = column; E1 = 1; E1 = 0; DATAPORT = 0; E2 = 1; E2 = 0; } else{ DATAPORT = column-61; E2 = 1; E2 = 0; } } void Sed_Init(){ Sed_Cmd(0b10101111); //Display ON Sed_SetAddress(0,0); //page 0, column 0 } |
▼I2Cライブラリ
1 2 3 4 5 6 7 8 9 10 |
void I2C_Master_Init(const unsigned long c); void I2C_Master_Wait(); void I2C_Master_Start(); void I2C_Master_RepeatedStart(); void I2C_Master_Stop(); void I2C_Master_Write(unsigned d); unsigned short I2C_Master_Read(unsigned short a); void SendI2C(char adrs, char data); void CmdI2C(char adrs, char reg, char data); void GetDataI2C(char adrs, char* buf, char cnt); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include<xc.h> #define _XTAL_FREQ 125000 void I2C_Master_Init(const unsigned long c){ SSP1CON1 = 0x28; //SSP1 Module as Master SSP1CON2 = 0x00; SSP1CON3 = 0x00; SSP1ADD = (_XTAL_FREQ/(4*c))-1; //Setting Clock Speed SSP1STAT = 0x80; SSP1CLKPPS = 0x0E; //PPS Settings SSP1DATPPS = 0x0C; // SCL : RB6 RB6PPS = 0x18; // SDA : RB4 RB4PPS = 0x19; } void I2C_Master_Wait(){ while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F)); //Transmit is in progress } void I2C_Master_Start(){ I2C_Master_Wait(); SSP1CON2bits.SEN = 1; //Initiate start condition } void I2C_Master_RepeatedStart(){ I2C_Master_Wait(); SSP1CON2bits.RSEN = 1; //Initiate repeated start condition } void I2C_Master_Stop(){ I2C_Master_Wait(); SSP1CON2bits.PEN = 1; //Initiate stop condition } void I2C_Master_Write(unsigned d){ I2C_Master_Wait(); SSP1BUF = d; //Write data to SSP1BUF } unsigned short I2C_Master_Read(unsigned short a){ unsigned short temp; I2C_Master_Wait(); SSP1CON2bits.RCEN = 1; I2C_Master_Wait(); temp = SSP1BUF; //Read data from SSP1BUF I2C_Master_Wait(); SSP1CON2bits.ACKDT = a; //Acknowledge bit 1:Not Ack 0:Ack SSP1CON2bits.ACKEN = 1; //Acknowledge sequence return temp; } void SendI2C(char adrs, char data){ I2C_Master_Start(); I2C_Master_Write(adrs<<1); //SlaveAdress + Write I2C_Master_Write(data); //mainly RegisterAdress I2C_Master_Stop(); } void CmdI2C(char adrs, char reg, char data){ I2C_Master_Start(); I2C_Master_Write(adrs<<1); //SlaveAdress + Write I2C_Master_Write(reg); //RegisterAdress I2C_Master_Write(data); I2C_Master_Stop(); } void GetDataI2C(char adrs, char* buf, char cnt){ I2C_Master_Start(); I2C_Master_Write((adrs<<1)+1); //SlaveAdress + Read for(char i=0; i<cnt-1; i++) buf[i] = I2C_Master_Read(0); //ACK buf[cnt-1] = I2C_Master_Read(1); //NACK I2C_Master_Stop(); } |
▼BME280ライブラリ
1 2 |
void bme_Init(void); void bme_ForceMeasurement(int* temp, char* hum, int* pres); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <xc.h> #include "i2c.h" #define _XTAL_FREQ 125000 const int TMAX = 2251, TMIN = 1755, HMAX = 353, HMIN = 193, PMAX = 567, PMIN = 519; //インデックスの範囲 const int TEMPTABLE[] = {0,0,0,1,2,3,4,4,5,6,7,8,8,9,10,11,12,12,13,14,15,16,16,17,18,19,20,21,21,22,23,24,25,25,26,27,28,29,29,30,31,32,33,33,34,35,36,37,38,38,39,40,41,42,42,43,44,45,46,46,47,48,49,50,50,51,52,53,54,55,55,56,57,58,59,59,60,61,62,63,63,64,65,66,67,67,68,69,70,71,72,72,73,74,75,76,76,77,78,79,80,80,81,82,83,84,84,85,86,87,88,88,89,90,91,92,93,93,94,95,96,97,97,98,99,100,101,101,102,103,104,105,105,106,107,108,109,110,110,111,112,113,114,114,115,116,117,118,118,119,120,121,122,122,123,124,125,126,127,127,128,129,130,131,131,132,133,134,135,135,136,137,138,139,139,140,141,142,143,144,144,145,146,147,148,148,149,150,151,152,152,153,154,155,156,156,157,158,159,160,161,161,162,163,164,165,165,166,167,168,169,169,170,171,172,173,173,174,175,176,177,178,178,179,180,181,182,182,183,184,185,186,186,187,188,189,190,190,191,192,193,194,194,195,196,197,198,199,199,200,201,202,203,203,204,205,206,207,207,208,209,210,211,211,212,213,214,215,216,216,217,218,219,220,220,221,222,223,224,224,225,226,227,228,228,229,230,231,232,233,233,234,235,236,237,237,238,239,240,241,241,242,243,244,245,245,246,247,248,249,250,250,251,252,253,254,254,255,256,257,258,258,259,260,261,262,262,263,264,265,266,267,267,268,269,270,271,271,272,273,274,275,275,276,277,278,279,279,280,281,282,283,284,284,285,286,287,288,288,289,290,291,292,292,293,294,295,296,296,297,298,299,300,301,301,302,303,304,305,305,306,307,308,309,309,310,311,312,313,313,314,315,316,317,318,318,319,320,321,322,322,323,324,325,326,326,327,328,329,330,330,331,332,333,334,335,335,336,337,338,339,339,340,341,342,343,343,344,345,346,347,347,348,349,350,351,351,352,353,354,355,356,356,357,358,359,360,360,361,362,363,364,364,365,366,367,368,368,369,370,371,372,373,373,374,375,376,377,377,378,379,380,381,381,382,383,384,385,385,386,387,388,389,390,390,391,392,393,394,394,395,396,397,398,398,399,400}; const int HUMTABLE[] = {0,1,1,2,3,3,4,5,5,6,7,7,8,8,9,10,10,11,12,12,13,13,14,15,15,16,17,17,18,18,19,20,20,21,22,22,23,24,24,25,25,26,27,27,28,29,29,30,30,31,32,32,33,34,34,35,35,36,37,37,38,39,39,40,40,41,42,42,43,44,44,45,45,46,47,47,48,49,49,50,50,51,52,52,53,53,54,55,55,56,57,57,58,58,59,60,60,61,62,62,63,63,64,65,65,66,67,67,68,68,69,70,70,71,71,72,73,73,74,75,75,76,76,77,78,78,79,80,80,81,81,82,83,83,84,84,85,86,86,87,88,88,89,89,90,91,91,92,92,93,94,94,95,96,96,97,97,98,99,99,100}; const signed char PRESTABLE[] = {20,19,18,17,16,16,15,14,13,12,12,11,10,9,8,7,7,6,5,4,3,2,2,1,0,-1,-2,-3,-3,-4,-5,-6,-7,-7,-8,-9,-10,-11,-12,-12,-13,-14,-15,-16,-17,-17,-18,-19,-20}; void bme_Init(void){ CmdI2C(0x76, 0xE0, 0xB6); // reset CmdI2C(0x76, 0xF2, 0x01); // Ctrl_hum_reg CmdI2C(0x76, 0xF4, 0x25); // Ctrl_meas_reg /Forced mode CmdI2C(0x76, 0xF5, 0xA0); // config/reg } void bme_ForceMeasurement(int* temp, int* hum, int* pres){ CmdI2C(0x76, 0xF4, 0x25); // Ctrl_meas_reg /Forced mode __delay_ms(30); char buf[8]; SendI2C(0x76, 0xF7); GetDataI2C(0x76, buf, 8); // Get from 0xF7 to 0xFE int temp12 = ((buf[3] << 4) | ((buf[4] >> 4) & 0x0F)); // 各ビット数のインデックスに変換 int hum9 = ((buf[6] << 1) | ((buf[7] >> 7) & 0x01)); int pres11 = ((buf[0] << 3) | ((buf[1] >> 5) & 0x07)); if (temp12 > TMAX) temp12 = TMAX; //インデックスが範囲外なら修正 else if(temp12 < TMIN) temp12 = TMIN; // else temp12 -= TMIN; //範囲内 if (hum9 > HMAX) hum9 = HMAX; else if(hum9 < HMIN) hum9 = HMIN; else hum9 -= HMIN; if (pres11 > PMAX) pres11 = PMAX; else if(pres11 < PMIN) pres11 = PMIN; else pres11 -= PMIN; *temp = TEMPTABLE[temp12]; // 温度結果 *hum = HUMTABLE[hum9]; // 湿度結果 *pres = PRESTABLE[pres11] + 1013; // 気圧結果 return; } |