반응형

Arm trainning kit


1. 키와 몸무게를 이력받아 BMI를 계산하는 프로그램을 작성하시오


캐릭터 LCD에 메뉴를 표시한다.

상태1 

[1. INPUT WEIGHT]


상태2

[2. INPUT HEINGT]


상태3

[3. CALC BMI]


0번 버튼 : 상

1번 버튼 : 하

2번 버튼 : 선택

3번 버튼 : 취소

------------------------------------------------------------


1. 상/하 버튼을 누르면 상태가 바뀜. 상태1 > 상태2 > 상태3 


2. 1번 상태에서 버튼을 누르면 

 상태1

 [50] +-

 상/하 버튼을 입력하여 몸무게 증감. 

 [선택]을 누르면 몸무게가 셋팅 되고 1번 상태로 돌아감

 [취소]을 누르면 취소되고 1로 돌아감


 상태2

  상/하 버튼을 입력하여 키 증감. 

 [선택]을 누르면 키가 셋팅 되고 1번 상태로 돌아감

 [취소]을 누르면 취소되고 1로 돌아감


 상태3

 Your BMI is 

 BMI Calc = w/(t^2) (단위, t = m)

 >= 30 비만, 25>= 과체중

 < 18.5 저체중

 Over weight

 Nomal weight

 Under weignt

 [취소]을 누르면 1로 돌아감 // 해당 기능 구현 필요


// LCD.H


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
#include "stm32f4xx.h"
 
void lcd_delay_us(u32 nCount) {
 int i,tmp;
 for(; nCount !=0; nCount--)
    {
       for(i=0; i<10; i++) tmp += i;
    }
}
 
void lcd_delay_ms(u32 nCount)
{
    //delay(nCount);
   for(; nCount !=0; nCount--)
      lcd_delay_us(1000);
}
 
void lcd_command(unsigned char command); // write a command(instruction) to text
void lcd_data(unsigned char data); // display a character on text LCD
void lcd_init(void); // initialize text LCD module
void lcd_string(unsigned char command, char *string);
 
//CLCD Control Port set
#define CLCD_PORT GPIOE //CLCD CONTROL PORT SET
#define Rs(x) CLCD_PORT->ODR=((CLCD_PORT->ODR&~(GPIO_Pin_8))|(x<<8)) //CLCD Rs : PE8
#define E(x) CLCD_PORT->ODR=((CLCD_PORT->ODR&~(GPIO_Pin_10))|(x<<10)) //CLCD E : PE10
#define CLCD_data(x) CLCD_PORT->ODR=((CLCD_PORT->ODR&(~(GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15)))|(x<<12 )) //CLCD Data bus : PE12~PE15
 
void lcd_init(void) { // initialize text LCD module (4BIT)
   int Cont;
 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
 
   GPIO_InitTypeDef GPIO_PORTE; //GPIO 설정관련 구조체 선언
   GPIO_PORTE.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_PORTE.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_PORTE.GPIO_OType = GPIO_OType_PP;
   GPIO_PORTE.GPIO_Pin = GPIO_Pin_All;
   GPIO_Init(CLCD_PORT, &GPIO_PORTE);  //PORTE 설정 메모리번지를 구조체 포인터 지시
   lcd_delay_ms(30); //30ms
   E(0), Rs(0); CLCD_data(0x30); //Functon set
   lcd_delay_ms(6); //4.1ms
   E(1);
   for(Cont=0;Cont<2;Cont++) { //Functon set loop
      E(0);
      lcd_delay_us(150); // 100us
      E(1);
   }
   lcd_delay_us(50); //50
 
   CLCD_data(0x20);
   E(1);
   lcd_delay_us(150); //150
   E(0);
   lcd_delay_us(50); //50
   lcd_command(0x28); // function set(4 bit, 2 line, 5x7 dot)
   lcd_command(0x0C); // display control(display ON, cursor OFF)
   lcd_command(0x06); // entry mode set(increment, not shift)
   lcd_command(0x01); // clear display
   lcd_delay_ms(10); //4
}
 
void lcd_command(unsigned char command) { // write a command(instruction) to text
//상위 4BIT 전송
   Rs(0),E(0);
   lcd_delay_us(1); //tas : Min 40ns
   CLCD_data(command>>4);
   E(1);
   lcd_delay_us(1);   //PW_eh min 230ns
   E(0);
   lcd_delay_us(50);   //100
//  하위 4BIT 전송
   CLCD_data((command&0x0F)); // output command
   E(1); lcd_delay_us(1); //1
   E(0); lcd_delay_us(50); //50
}
void lcd_data(unsigned char data) { // display a character on text LCD //상위 4BIT 전송
   E(0), Rs(1); CLCD_data(data>>4); // output data
   E(1); lcd_delay_us(1); // 1
   E(0); lcd_delay_us(50); //50
//하위 4BIT 전송
   CLCD_data((data&0x0F));
   E(1); lcd_delay_us(1);  //   1
   E(0); lcd_delay_us(50); //50
}
 
void lcd_string(unsigned char command, char *string)  { // display a string on LCD
   lcd_command(command); // start position of string
   while(*string != '\0') { // display string
      lcd_data(*string); string++;
   }
}
 
void lcd_gotoxy(int x, int y)
{
   lcd_command(0x80 | (0x40 * y) | x);
}
 
void lcd_clear()
{
    lcd_command(0x01); // clear display
    lcd_delay_ms(10); //4
 
}
 
void lcd_printxy(int x, int y, char *string)  { // display a string on LCD
   lcd_gotoxy(x, y);
   while(*string != '\0') { // display string
      lcd_data(*string);
      string++;
   }
}
 
cs



// Main Code


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
 
 #include "stm32f4xx.h"
#include "lcd.h"
#include "stdio.h"
 
 
int msTime = 0;
void SysTick_Handler() {
    msTime++;
}
void delay(int ms) {
    int future = ms + msTime;
    while (future > msTime)
        ;
}
void init() {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
            | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
}
 
int prev_pin_0 = 1;
int pin_0 = 1;
int prev_pin_1 = 1;
int pin_1 = 1;
int prev_pin_2 = 1;
int pin_2 = 1;
int prev_pin_3 = 1;
int pin_3 = 1;
char buf[255];
 
void getBtn() {
    prev_pin_0 = pin_0;
    pin_0 = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_0);
    prev_pin_1 = pin_1;
    pin_1 = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_1);
    prev_pin_2 = pin_2;
    pin_2 = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_2);
    prev_pin_3 = pin_3;
    pin_3 = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3);
}
 
int InputWeightMenu(int CurrentWeight) {
    int iWeight = CurrentWeight;
    while (1) {
        lcd_clear();
        lcd_printxy(00"[In Your Weight]");
        while (1) {
            sprintf(buf, "[Weight:%d kg]+-", iWeight);
            lcd_printxy(01, buf);
 
            getBtn();
            // 키 입력시 몸무게 증가
            if (pin_0 == 0 && prev_pin_0 == 1) {
                iWeight++;
                if (iWeight > 300)
                    iWeight = 0;
                break;
            }
            // 키 입력시 몸무게 감소
            if (pin_1 == 0 && prev_pin_1 == 1) {
                iWeight--;
                if (iWeight < 0)
                    iWeight = 0;
                break;
            }
            if (pin_2 == 0 && prev_pin_2 == 1) {
                lcd_clear();
                lcd_printxy(00"[Input Weight]");
                sprintf(buf, "[Weight:%d kg]+-", iWeight);
                lcd_printxy(01, buf);
                return iWeight;
            }
            if (pin_3 == 0 && prev_pin_3 == 1) {
                lcd_clear();
                lcd_printxy(00"[Input Weight]");
                sprintf(buf, "[Weight:%d kg]+-", CurrentWeight);
                lcd_printxy(01, buf);
                return CurrentWeight;
            }
        }
    }
}
double InputHeightMenu(volatile double CurrentHeight) {
    double iHeight = CurrentHeight;
    while (1) {
        lcd_clear();
        lcd_printxy(00"[In Your Height]");
        while (1) {
 
            sprintf(buf, "[Height:%.2f m]+-", iHeight);
            lcd_printxy(01, buf);
 
            getBtn();
            // 키 입력시 키 증가
            if (pin_0 == 0 && prev_pin_0 == 1) {
                iHeight += 0.01;
                break;
            }
            // 키 입력시 키 감소
            if (pin_1 == 0 && prev_pin_1 == 1) {
                iHeight -= 0.01;
                break;
            }
            if (pin_2 == 0 && prev_pin_2 == 1) {
                lcd_clear();
                lcd_printxy(00"[Input Height]");
                sprintf(buf, "[Height:%.2f m]+-", iHeight);
                lcd_printxy(01, buf);
                return iHeight;
            }
            if (pin_3 == 0 && prev_pin_3 == 1) {
                lcd_clear();
                lcd_printxy(00"[Input Height]");
                sprintf(buf, "[Height:%.2f m]+-", CurrentHeight);
                lcd_printxy(01, buf);
                return CurrentHeight;
            }
        }
    }
}
 
int main(void) {
    init();
    lcd_init();
    SysTick_Config(SystemCoreClock / 1000 / 3.125);
    int iCurrentMenu = 0;
    int iWeight = 50;
    double iHeight = 1.60;
    for (;;) {
        lcd_clear();
        if (iCurrentMenu == 0) {
            lcd_printxy(00"[Input Weight]");
            sprintf(buf, "[Weight:%d kg]", iWeight);
            lcd_printxy(01, buf);
        }
        if (iCurrentMenu == 1) {
            lcd_printxy(00"[Input Height]");
            sprintf(buf, "[Height:%.2f m]", iHeight);
            lcd_printxy(01, buf);
        }
        if (iCurrentMenu == 2) {
            lcd_printxy(00"[Calc BMI]");
            double bmi = iWeight/(iHeight*iHeight);
            sprintf(buf, "[BMI:%.2f]", bmi);
            lcd_printxy(0,1,buf);
        }
 
        while (1) {
            getBtn();
 
            if (pin_0 == 0 && prev_pin_0 == 1) {
                iCurrentMenu = (iCurrentMenu + 1) % 3// 다음 메뉴
                break;
            }
            if (pin_2 == 0 && prev_pin_2 == 1) {
                if (iCurrentMenu == 0)
                    iWeight = InputWeightMenu(iWeight);
                if (iCurrentMenu == 1)
                    iHeight = InputHeightMenu(iHeight);
                if (iCurrentMenu == 2){
                    lcd_clear();
                    double bmi = iWeight/(iHeight*iHeight);
                    sprintf(buf, "[BMI : %.2f]", bmi);
                    lcd_printxy(00, buf);
                    if(bmi>= 30)
                    lcd_printxy(0,1,"Obesity");
                    else if(bmi>=25)
                        lcd_printxy(0,1,"OVER Weight");
                    else if(bmi>=18.5)
                        lcd_printxy(0,1,"Nomal Weight");
                    else if(bmi <18.5)
                        lcd_printxy(0,1,"Under Weight");
                }
            }
        }
    }
}
 
 
// Sprintf(buf,"%f", 15.5);
//소숫점 표기를 위해 프로젝트
//properties -> C/C++ build -> setting -> MCU GCC Linker -> miscellaneous -> -u _printf_float 추가
 
cs


반응형

'Study > 32-bit MCUs' 카테고리의 다른 글

[Elevator(ARM)] DoorLock  (0) 2018.10.25
[Elevator(ARM)] Calculator  (0) 2018.10.25
[Elevator(ARM)] Coretex-M4 Elevator  (0) 2018.10.18
[MTX32F407-M4] Coretex-M4 Stop_Watch  (0) 2018.10.18
[MTX32F407-M4] Cortex-M4 LED제어, SW제어, FND 제어  (0) 2018.10.15

+ Recent posts