My_Arduino_FND_Lib_V2_7.h 파일의 299 번째 줄을 아래와 같이 수정해주세요.
수정 전
(Seg_V -> Dp_595_Digit == scan_f) ? (data &= 0x7f) : (data |= 0x80);
수정 후
(Seg_V -> Dp_595_Digit & scan_f) ? (data &= 0x7f) : (data |= 0x80);
수정 전에는 0x03 ( 0000 0011 ) 같은 값을 거짓으로 판단해 동시에 여러개의 비트(Dp)를 킬수 없었습니다. And 비트연산은 비트마다 참인지를 확인하기 때문에 수정 후에는 해결되었습니다.
사용되지 않는 소스( 예: m_led1 )는 잘라냈고, Run 입력시 카운트 증감 속도를 tm2_irq() 함수로 1초 간격으로 제어했습니다.
run_func() 안에는 반복문을 넣으면 반복문이 끝나기 전까진 key_chk() 함수로 진입이 불가능해서 키입력을 해도 인식하지 못했습니다.
따라서 run_func() 는 시리얼 출력만 담당하고, 인터럽트인 tm2_irq() 에서만 실제 값의 증감을 관리하도록 수정했습니다.
시리얼 모니터에서 너무 빠르게 프린트 되는 것을 막기 위해 loop() 함수에서 호출되는 run_func() 의 조건에 ct->t_loop 를 체크하도록 변경했습니다. ct->t_loop 는 tm2_irq() 인터럽트가 돌때마다 1 로 변경되는, flag 와 같은 용도로 사용했습니다.
추신) 페이지의 맨밑을 절대 확인하지 마
// Sys Lib
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Arduino API
#include <MsTimer2.h>
#include <TimerOne.h>
// My Lib
#include <value.h>
#include <My_Mult_Func_BD_Pin_define_Lib.h>
#include <My_Arduino_GPIO_Lib_V1_8.h>
// #include <My_Arduino_FND_Lib_V2_7.h>
// 직렬타입 FND
#define FND_595_IF 1
// #define En_Font 2
#include <My_Arduino_FND_Lib_V2_7.h>
#include <My_LCD_User_Font_Lib_V1_4.h>
#define I2C_IF 1
#include <My_Arduino_LiqCry_LCD_Lib_V1_5.h>
#include <My_Arduino_SSD1306_LIB_V1_2.h>
#define Arduino_Mode 1
#define HW_Uart_mode 2
#define Arduino_i2c_Char_LCD 3
#define SSD1306_I2C_OLED 4
extern int out_dev_set_mode;
#include <My_MCU_Printf_Lib_V2_6.h>
extern uint8_t key;
uint8_t mode_cnt = 1;
String rxd;
uint8_t dan = 1;
uint8_t gu = 1;
uint8_t mul = 1;
void tm1_irq()
{
//1ms
switch(mode_cnt)
{
case 1:
case 2:
case 3:
case 4:
case 7:
case 8:
fnd_595_out(ct->cnt16);
break;
case 5:
Seg_V->Dp_595_Digit = 0x03;
fnd_595_out(dan * 1000 + gu * 100 + mul);
break;
case 6:
Seg_V->Dp_595_Digit = 0x0a;
fnd_595_out(ct->min * 100 + ct->sec);
break;
}
}
void tm2_irq()
{
ct->t_loop = 1;
if(fg->run_flag == 1)
{
switch(mode_cnt)
{
case 1: ct->cnt16++; break;
case 2: ct->cnt16--; break;
case 3:
ct->cnt16 = (ct->cnt16%2 == 0) ? ct->cnt16 + 2 : ct->cnt16 + 1;
break;
case 4:
ct->cnt16 = (ct->cnt16%2 == 0) ? ct->cnt16 + 1 : ct->cnt16 + 2;
break;
case 5:
gu++;
if(gu > 9)
{
dan++;
gu = 1;
if(dan > 9)
{
dan = 1;
}
}
mul = dan * gu;
break;
case 6:
ct->sec++;
if(ct->sec >= 60)
{
ct->sec = 0;
ct->min++;
if(ct->min >= 60) ct->min = 0;
}
break;
}
(ct->cnt16 >= 10000) ? ct->cnt16 = 0 : 0;
}
}
char bit_key_rd()
{ // d_in() == digitalRead() 매크로함수
uint8_t buf = 0;
if(d_in(SW1) == 0) // Up
{
while(d_in(SW1) == 0) {}
buf = 1;
}
else if(d_in(SW2) == 0) // Mode
{
while(d_in(SW2) == 0) {}
buf = 2;
}
else if(d_in(SW3) == 0) // Preset UP
{
while(d_in(SW3) == 0) {}
buf = 3;
}
fg->key_flag = (buf != 0) ? 1 : 0;
return buf;
}
void key_chk()
{
fg->key_flag = 0;
if(fg->rx_end_flag == 1)
{
fg->rx_end_flag = 0;
rxd.toCharArray(d_buf, sizeof(d_buf));
Serial.println(d_buf);
if(strcmp("Run", d_buf) == 0) fg->run_flag = 1;
else if(strcmp("Stop", d_buf) == 0) fg->run_flag = 0;
else if(strcmp("M1Up", d_buf) == 0) mode_cnt = 1;
else if(strcmp("M2Dn", d_buf) == 0) mode_cnt = 2;
else if(strcmp("M3Env", d_buf) == 0) mode_cnt = 3;
else if(strcmp("M4Odd", d_buf) == 0) mode_cnt = 4;
else if(strcmp("M5GuDan", d_buf) == 0) mode_cnt = 5;
else if(strcmp("Time", d_buf) == 0) mode_cnt = 6;
else if(strcmp("P-UP", d_buf) == 0) {mode_cnt = 7; if(fg->run_flag == 0) ct->cnt16++;}
else if(strcmp("P-DN", d_buf) == 0) {mode_cnt = 8; if(fg->run_flag == 0) ct->cnt16--;}
}
// fnd dp clr
Seg_V->Dp_595_Digit = 0;
switch(key)
{
case 1:
// run/stop key
fg -> run_flag = !fg -> run_flag;
break;
case 2:
// mode cnt
mode_cnt = (mode_cnt >= 8) ? 1 : mode_cnt + 1;
break;
case 3:
// Preset Mode UP Cnt
if(fg->run_flag == 0) ct->cnt16++;
break;
}
key = 0;
}
void serialEvent()
{
if(Serial.available() > 0)
{
rxd = Serial.readString();
Serial.println(rxd); // 디버깅 용
fg->rx_end_flag = 1;
}
}
void run_func()
{
switch(mode_cnt)
{
case 1:
dev_printf("Mode 1 Up Cnt = %d\r\n", ct->cnt16);
break;
case 2:
dev_printf("Mode 2 Dn Cnt = %d\r\n", ct->cnt16);
break;
case 3:
dev_printf("Mode 3 Env Cnt = %d\r\n", ct->cnt16);
break;
case 4:
dev_printf("Mode 4 Odd Cnt = %d\r\n", ct->cnt16);
break;
case 5:
dev_printf("Mode 5 GuGuDan = %d X %d = %d\r\n", dan, gu, mul);
break;
case 6:
dev_printf("Mode 6 Time = %d : %d\r\n", ct->min, ct->sec);
break;
case 7:
dev_printf("Mode 7 Preset Up Cnt = %d\r\n", ct->cnt16);
break;
case 8:
dev_printf("Mode 8 Preset Dn Cnt = %d\r\n", ct->cnt16);
break;
}
}
void setup() {
asm("nop");
asm("nop");
// 1. GPIO init
for(int i = 0; i < 8; i++)
{ // LED + FND DIR Set
pinMode(LED_pin[i], OUTPUT);
}
Led_Byte_Out(0xff); // init
// 1-2 FND Pin
pinMode(DATA, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LATCH, OUTPUT);
//--------------------------------------------
// 1-3 LED
// pinMode(m_led1, OUTPUT);
// pinMode(m_led2, OUTPUT);
// pinMode(m_led3, OUTPUT);
// pinMode(m_led4, OUTPUT);
//-----------------------------------------------
// 2. UART init
Serial.begin(115200);
out_dev_set_mode = HW_Uart_IF_Mode;
//-------------------------------------------------
// 3. I2C LCD Init
//lcd_init();
// i2c_scan_id();
//Lcd_Test();
// LCD_All_CLr;
// LCD_Home;
// print_xy_str(2,0,"Up Cnt: ");
// print_xy_str(2,1,"Dn Cnt: ");
//------------------------------------------------
// 4. Timer 1, 2 Init
// Timer2 Interrupt
MsTimer2::set(1000, tm2_irq); //1sec
MsTimer2::start();
// Timer1 Interrupt = IRQ
Timer1.initialize(1000); // 1ms ==fnd display
Timer1.attachInterrupt(tm1_irq);
//----------------------------------------------------
// 5. KEy init
pinMode(SW1, INPUT_PULLUP); //d2
pinMode(SW2, INPUT_PULLUP); //d3
pinMode(SW3, INPUT_PULLUP); //d17
asm("nop");
asm("nop");
}
void loop() {
key = bit_key_rd();
if((fg->key_flag == 1) || (fg->rx_end_flag == 1)) key_chk();
if((fg->run_flag == 1) && (ct->t_loop == 1)) {ct->t_loop = 0; run_func();}
}