CListery
发表于 2024-8-2 16:20:15
本帖最后由 CListery 于 2024-8-2 16:22 编辑
记一个在 STC32G12K128 大学计划实验箱 V9.62 上遇到的问题:
在同时对 P32、P33、P34、P35 和 矩阵按键扫描时,P34会出现意外拉低的情况,设置了上拉电阻也无效,导致按键扫描程序一直扫描到 P34 为低电平
引发该问题的具体原因暂时未知,有可能是在拉低P0口时其他的电路影响到了P3口
解决方案,在扫描 P3 口的按键时将 P0 口拉高,扫描 P0 口矩阵按键时将 P3 拉高(最好排除 P30、P31 口)
CListery
发表于 2024-8-2 23:23:13
第二十九集:
做一个带闹钟、时间设置、30秒提醒功能的时钟
#include <stc32g.h>
#define PRINTF_HID
#include <stc32_stc8_usb.h>
#include "adc.h"
#include "extint.h"
#include "key.h"
#include "led.h"
#include "timer.h"
#define FOSC 24000000UL // ISP 下载时需将工作频率设置为 24MHz
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; // 设置自动复位到ISP区的用户接口命令
bit FLAG_100ms = 1, FLAG_500ms = 0;
// 秒,分,时
u8 time = {0, 0, 0};
#define T_HOUR time
#define T_MINUTE time
#define T_SECOUND time
u8 preSetTime = {255, 255, 255};
#define PRE_T_HOUR preSetTime
#define PRE_T_MINUTE preSetTime
#define PRE_T_SECOUND preSetTime
bit pauseRefreshLight = 0;
u8 twinkle = 0;
bit TIME_SETTING = 0;
bit PRE_TIME_SETTING = 0;
u8 twinklePos = 0;
bit PRE_TIMEUP = 0;
void sys_init();
void refreshTIME();
void setTime(u8 tVal);
void preTimeup();
void Delay1ms(void) //@24.000MHz
{
unsigned char data i, j;
i = 24;
j = 85;
do
{
while (--j)
;
} while (--i);
}
void Delay100ms()
{
u8 i = 100;
while (--i)
{
Delay1ms();
}
}
void main()
{
char key;
// u8 keyStatus;
u8 tVal;
sys_init();
// initTimer0(0x30, 0xF8);
initTimer1(0x40, 0xA2);
initADC(0);
EA = 1;
P0M0 = 0;
P0M1 = 0;
// P3M0 = 0;
// P3M1 = 0;
P4M0 = 0;
P4M1 = 0;
P6M0 = 0;
P6M1 = 0;
P7M0 = 0;
P7M1 = 0;
// SSD0 = 0;
// SSD1 = 1;
// SSD2 = 2;
// SSD3 = 3;
// SSD4 = 4;
// SSD5 = 5;
// SSD6 = 6;
// SSD7 = 7;
// 等待 USB 完成配置
while (DeviceState != DEVSTATE_CONFIGURED)
;
while (1)
{
if (bUsbOutReady) // 当硬件接收完成上位机通过串口助手发送数据后
// 会自动将 bUsbOutReady 置 1
// 接收的数据字节保存在 OutNumber 变量总
// 接收的数据保存在 UsbOutBuffer 缓冲区
{
USB_SendData(UsbOutBuffer, OutNumber); // 使用 Usb_SendData 库函数可向上位机发送数据
// 这里的测试代码为将接收数据原样返回
usb_OUT_done(); // 处理完成接收的数据后
// 调用 usb_OUT_done 准备接收下一笔数据
}
if (FLAG_100ms)
{
FLAG_100ms = 0;
key = adcKeyRead(0);
if (key != -1)
{
tVal = -1;
printf("%d\r\n", key);
switch (key)
{
case ADC_K_0_CLICK:
case ADC_K_1_CLICK:
case ADC_K_2_CLICK:
case ADC_K_3_CLICK:
case ADC_K_4_CLICK:
case ADC_K_5_CLICK:
case ADC_K_6_CLICK:
case ADC_K_7_CLICK:
case ADC_K_8_CLICK:
case ADC_K_9_CLICK:
if (TIME_SETTING || PRE_TIME_SETTING)
{
while (queryADC(0))
{
Delay100ms();
}
tVal = key - 1;
}
break;
case ADC_K_B_CLICK:
case ADC_K_B_LONG_CLICK:
if (TIME_SETTING)
{
T_SECOUND++;
pauseRefreshLight = 0;
}
break;
case ADC_K_D_CLICK:
if (TIME_SETTING)
{
// 退出设置时间
TIME_SETTING = 0;
pauseRefreshLight = 0;
}
else if (PRE_TIME_SETTING)
{
// 退出设置闹钟
PRE_TIME_SETTING = 0;
pauseRefreshLight = 0;
}
break;
case ADC_K_A_LONG_CLICK:
// 设置时间
if (!TIME_SETTING)
{
twinklePos = 0;
TIME_SETTING = 1;
}
break;
case ADC_K_F_LONG_CLICK:
// 设置闹钟
if (!PRE_TIME_SETTING)
{
twinklePos = 0;
PRE_TIME_SETTING = 1;
}
break;
}
if (tVal != -1)
{
setTime(tVal);
}
}
// key = queryUnNormalKey();
// if (key != -1)
// {
// keyStatus = readKeyStatus(key);
// printf("%d -> %d\r\n", key, keyStatus);
// switch (key)
// {
// case KEY1:
// // A 键
// if (keyStatus == KEY_LONG_CLICK)
// {
// if (!TIME_SETTING)
// {
// twinklePos = 0;
// TIME_SETTING = 1;
// }
// }
// break;
// case KEY4:
// // D键
// if (keyStatus == KEY_CLICK)
// {
// TIME_SETTING = 0;
// pauseRefreshLight = 0;
// }
// break;
// }
// }
refreshTIME();
}
}
}
void setTime(u8 tVal)
{
if (TIME_SETTING)
{
switch (twinklePos)
{
case 0:
T_SECOUND = (T_SECOUND / 10 * 10) + tVal;
break;
case 1:
T_SECOUND = tVal * 10 + T_SECOUND % 10;
break;
case 3:
T_MINUTE = (T_MINUTE / 10 * 10) + tVal;
break;
case 4:
T_MINUTE = tVal * 10 + T_MINUTE % 10;
break;
case 6:
T_HOUR = (T_HOUR / 10 * 10) + tVal;
break;
case 7:
T_HOUR = tVal * 10 + T_HOUR % 10;
break;
}
twinklePos++;
if (twinklePos == 2 || twinklePos == 5)
{
twinklePos++;
}
else if (twinklePos == 8)
{
twinklePos = 0;
}
}
else if (PRE_TIME_SETTING)
{
switch (twinklePos)
{
case 0:
PRE_T_SECOUND = (PRE_T_SECOUND / 10 * 10) + tVal;
break;
case 1:
PRE_T_SECOUND = tVal * 10 + PRE_T_SECOUND % 10;
break;
case 3:
PRE_T_MINUTE = (PRE_T_MINUTE / 10 * 10) + tVal;
break;
case 4:
PRE_T_MINUTE = tVal * 10 + PRE_T_MINUTE % 10;
break;
case 6:
PRE_T_HOUR = (PRE_T_HOUR / 10 * 10) + tVal;
break;
case 7:
PRE_T_HOUR = tVal * 10 + PRE_T_HOUR % 10;
break;
}
twinklePos++;
if (twinklePos == 2 || twinklePos == 5)
{
twinklePos++;
}
else if (twinklePos == 8)
{
twinklePos = 0;
}
}
}
void refreshTIME()
{
if (PRE_TIME_SETTING)
{
if (PRE_T_SECOUND >= 60)
{
PRE_T_SECOUND = 0;
PRE_T_MINUTE++;
}
if (PRE_T_MINUTE >= 60)
{
PRE_T_MINUTE = 0;
PRE_T_HOUR++;
}
if (PRE_T_HOUR >= 24)
{
PRE_T_HOUR = 0;
}
// if (!pauseRefreshLight)
// {
// printf("%d - %d - %d \r\n", T_HOUR, T_MINUTE, T_SECOUND);
// }
// else
// {
// printf(" - -\r\n");
// }
SSD0 = PRE_T_SECOUND > 0 ? PRE_T_SECOUND % 10 : 0;
SSD1 = PRE_T_SECOUND > 0 ? PRE_T_SECOUND / 10 : 0;
SSD2 = SEG_DISPLAY_STAFF;
SSD3 = PRE_T_MINUTE > 0 ? PRE_T_MINUTE % 10 : 0;
SSD4 = PRE_T_MINUTE > 0 ? PRE_T_MINUTE / 10 : 0;
SSD5 = SEG_DISPLAY_STAFF;
SSD6 = PRE_T_HOUR > 0 ? PRE_T_HOUR % 10 : 0;
SSD7 = PRE_T_HOUR > 0 ? PRE_T_HOUR / 10 : 0;
}
else
{
if (T_SECOUND >= 60)
{
T_SECOUND = 0;
T_MINUTE++;
}
if (T_MINUTE >= 60)
{
T_MINUTE = 0;
T_HOUR++;
}
if (T_HOUR >= 24)
{
T_HOUR = 0;
}
// if (!pauseRefreshLight)
// {
// printf("%d - %d - %d \r\n", T_HOUR, T_MINUTE, T_SECOUND);
// }
// else
// {
// printf(" - -\r\n");
// }
SSD0 = T_SECOUND > 0 ? T_SECOUND % 10 : 0;
SSD1 = T_SECOUND > 0 ? T_SECOUND / 10 : 0;
SSD2 = SEG_DISPLAY_STAFF;
SSD3 = T_MINUTE > 0 ? T_MINUTE % 10 : 0;
SSD4 = T_MINUTE > 0 ? T_MINUTE / 10 : 0;
SSD5 = SEG_DISPLAY_STAFF;
SSD6 = T_HOUR > 0 ? T_HOUR % 10 : 0;
SSD7 = T_HOUR > 0 ? T_HOUR / 10 : 0;
if (T_SECOUND == PRE_T_SECOUND && T_MINUTE == PRE_T_MINUTE && T_HOUR == PRE_T_HOUR)
{
preTimeup();
}
}
}
void preTimeup()
{
u8 key;
PRE_TIMEUP = 1;
twinklePos = 0;
while (1)
{
if (FLAG_100ms)
{
FLAG_100ms = 0;
key = adcKeyRead(0);
if (key != -1)
{
printf("%d\r\n", key);
if (key == ADC_K_0_CLICK)
{
PRE_TIMEUP = 0;
break;
}
}
}
}
}
void t1_run(void) interrupt 3
// void t0_run() interrupt 1
{
static u8 n = 0, n100 = 0, n500 = 0;
if (TIME_SETTING || PRE_TIME_SETTING || PRE_TIMEUP)
{
refreshLight(pauseRefreshLight ? twinklePos : -1);
}
else
{
if (pauseRefreshLight)
{
SEG_ENABLE = 0xFF;
}
else
{
refreshLight(-1);
}
}
n++;
if (n % 10 == 0)
{
refreshKeyStatus();
}
if (n == 100)
{
FLAG_100ms = 1;
n100++;
n500++;
n = 0;
}
if (n100 > 0)
{
if (n100 % 10 == 0)
{
if (!TIME_SETTING)
{
T_SECOUND++;
if (T_SECOUND == 30)
{
twinkle = 6;
}
}
n100 = 0;
}
if (n500 == 5)
{
n500 = 0;
}
}
if (n500)
{
n500 = 0;
if (TIME_SETTING || PRE_TIME_SETTING)
{
pauseRefreshLight = !pauseRefreshLight;
}
else if (PRE_TIMEUP)
{
pauseRefreshLight = 1;
twinklePos++;
if (twinklePos == 8)
{
twinklePos = 0;
}
}
else
{
if (twinkle > 0)
{
pauseRefreshLight = !pauseRefreshLight;
twinkle--;
}
else
{
pauseRefreshLight = 0;
}
}
}
}
void sys_init()
{
WTST = 0;
CKCON = 0;
EAXFR = 1;
P3M0 = 0x00;
P3M1 = 0x00;
P3M0 &= ~0x03; // P30,P31 和 USB 的 D-,D+ 共用 PIN 脚
P3M1 |= 0x03;// 需要将 P30,P31 设置为高阻输入模式
IRC48MCR = 0x80; // 使能内部 48M 的 USB 专用 IRC
while (!(IRC48MCR & 0x01))
; // 等待震荡源稳定
USBCLK = 0x00; // 设置 USB 时钟源为内部 48M 的 USB 专用 IRC
USBCON = 0x09; // 使能 USB 功能
usb_init(); // 调用 USB CDC 初始化库函数
EUSB = 1; // 使能 USB 中断
}
llyymm
发表于 2024-8-3 08:14:10
进来看看
CListery
发表于 2024-8-7 15:46:11
本帖最后由 CListery 于 2024-8-7 15:58 编辑
第三十集:
ADC采集NTC温度并显示
#include <stc32g.h>
#define PRINTF_HID
#include <stc32_stc8_usb.h>
#include "adc.h"
#include "extint.h"
#include "key.h"
#include "led.h"
#include "timer.h"
#define FOSC 24000000UL // ISP 下载时需将工作频率设置为 24MHz
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; // 设置自动复位到ISP区的用户接口命令
bit FLAG_100ms = 1, FLAG_500ms = 0;
u16 NTC_ADC_DATA = {
3980, // -40 0
3972, // -39 1
3964, // -38 2
3955, // -37 3
3946, // -36 4
3936, // -35 5
3926, // -34 6
3915, // -33 7
3904, // -32 8
3892, // -31 9
3880, // -30 10
3867, // -29 11
3853, // -28 12
3838, // -27 13
3823, // -26 14
3807, // -25 15
3791, // -24 16
3774, // -23 17
3756, // -22 18
3737, // -21 19
3717, // -20 20
3697, // -19 21
3675, // -18 22
3653, // -17 23
3630, // -16 24
3606, // -15 25
3581, // -14 26
3556, // -13 27
3529, // -12 28
3501, // -11 29
3473, // -10 30
3444, // -9 31
3413, // -8 32
3382, // -7 33
3350, // -6 34
3317, // -5 35
3283, // -4 36
3249, // -3 37
3213, // -2 38
3177, // -1 39
3139, // 0 40
3101, // 1 41
3063, // 2 42
3023, // 3 43
2983, // 4 44
2942, // 5 45
2901, // 6 46
2858, // 7 47
2816, // 8 48
2773, // 9 49
2729, // 10 50
2685, // 11 51
2640, // 12 52
2595, // 13 53
2550, // 14 54
2505, // 15 55
2459, // 16 56
2414, // 17 57
2368, // 18 58
2322, // 19 59
2276, // 20 60
2230, // 21 61
2184, // 22 62
2139, // 23 63
2093, // 24 64
2048, // 25 65
2003, // 26 66
1958, // 27 67
1914, // 28 68
1870, // 29 69
1827, // 30 70
1784, // 31 71
1741, // 32 72
1699, // 33 73
1657, // 34 74
1617, // 35 75
1576, // 36 76
1536, // 37 77
1497, // 38 78
1459, // 39 79
1421, // 40 80
1384, // 41 81
1348, // 42 82
1312, // 43 83
1277, // 44 84
1242, // 45 85
1209, // 46 86
1176, // 47 87
1144, // 48 88
1112, // 49 89
1082, // 50 90
1052, // 51 91
1022, // 52 92
994,// 53 93
966,// 54 94
939,// 55 95
912,// 56 96
886,// 57 97
861,// 58 98
837,// 59 99
813,// 60 100
790,// 61 101
767,// 62 102
745,// 63 103
724,// 64 104
703,// 65 105
683,// 66 106
663,// 67 107
644,// 68 108
626,// 69 109
608,// 70 110
590,// 71 111
573,// 72 112
557,// 73 113
541,// 74 114
525,// 75 115
510,// 76 116
496,// 77 117
481,// 78 118
468,// 79 119
454,// 80 120
441,// 81 121
429,// 82 122
417,// 83 123
405,// 84 124
394,// 85 125
382,// 86 126
372,// 87 127
361,// 88 128
351,// 89 129
341,// 90 130
332,// 91 131
323,// 92 132
314,// 93 133
305,// 94 134
297,// 95 135
289,// 96 136
281,// 97 137
273,// 98 138
265,// 99 139
258,// 100 140
251,// 101 141
245,// 102 142
238,// 103 143
232,// 104 144
225,// 105 145
219,// 106 146
214,// 107 147
208,// 108 148
202,// 109 149
197,// 110 150
192,// 111 151
187,// 112 152
182,// 113 153
177,// 114 154
173,// 115 155
168,// 116 156
164,// 117 157
160,// 118 158
156,// 119 159
152,// 120 160
148,// 121 161
144,// 122 162
141,// 123 163
137,// 124 164
134,// 125 165
130,// 126 166
127,// 127 167
124,// 128 168
121,// 129 169
118,// 130 170
115,// 131 171
112,// 132 172
110,// 133 173
107,// 134 174
104,// 135 175
102,// 136 176
100,// 137 177
97, // 138 178
95, // 139 179
93, // 140 180
91, // 141 181
88, // 142 182
86, // 143 183
84, // 144 184
82, // 145 185
81, // 146 186
79, // 147 187
77, // 148 188
75, // 149 189
73, // 150 190
};
void sys_init();
void Delay1ms(void) //@24.000MHz
{
unsigned char data i, j;
i = 24;
j = 85;
do
{
while (--j)
;
} while (--i);
}
void Delay100ms()
{
u8 i = 100;
while (--i)
{
Delay1ms();
}
}
u16 cal_temperature(u16 adcVal);
void main()
{
u16 ntcVal;
u16 temp;
sys_init();
// initTimer0(0x30, 0xF8);
initTimer1(0x40, 0xA2);
initADC(0);
EA = 1;
P0M0 = 0;
P0M1 = 0;
P4M0 = 0;
P4M1 = 0;
P6M0 = 0;
P6M1 = 0;
P7M0 = 0;
P7M1 = 0;
P1M1 = 0x38;
P1M0 = 0x30; // 设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.3 为 ADC 高阻输入口
// SSD0 = 0;
// SSD1 = 1;
// SSD2 = 2;
// SSD3 = 3;
// SSD4 = 4;
// SSD5 = 5;
// SSD6 = 6;
// SSD7 = 7;
// 等待 USB 完成配置
while (DeviceState != DEVSTATE_CONFIGURED)
;
while (1)
{
if (bUsbOutReady) // 当硬件接收完成上位机通过串口助手发送数据后
// 会自动将 bUsbOutReady 置 1
// 接收的数据字节保存在 OutNumber 变量总
// 接收的数据保存在 UsbOutBuffer 缓冲区
{
USB_SendData(UsbOutBuffer, OutNumber); // 使用 Usb_SendData 库函数可向上位机发送数据
// 这里的测试代码为将接收数据原样返回
usb_OUT_done(); // 处理完成接收的数据后
// 调用 usb_OUT_done 准备接收下一笔数据
}
if (FLAG_100ms)
{
FLAG_100ms = 0;
ntcVal = queryADC(3);
if (ntcVal < 4096)
{
temp = cal_temperature(ntcVal);
SSD0 = temp % 10;
SSD1 = temp / 10 % 10 + 11;
SSD2 = temp / 100;
}
printf("ntc: %d -> %d\r\n", ntcVal, temp);
}
}
}
u16 cal_temperature(u16 adcVal)
{
u8 i;
float temp;
if (adcVal < NTC_ADC_DATA)
{
i = 191 / 2;
}
else
{
i = 0;
}
for (; i < 191; i++)
{
if (NTC_ADC_DATA == adcVal)
{
temp = (i - 40) * 10;
break;
}
else if (NTC_ADC_DATA < adcVal)
{
temp = ((float)(NTC_ADC_DATA - adcVal) / (float)(NTC_ADC_DATA - NTC_ADC_DATA) + (i - 40)) * 10;
break;
}
}
return (u16)temp;
}
void t1_run(void) interrupt 3
// void t0_run() interrupt 1
{
static u8 n = 0, n100 = 0, n500 = 0;
refreshLight(-1);
n++;
if (n % 10 == 0)
{
refreshKeyStatus();
}
if (n == 100)
{
FLAG_100ms = 1;
n100++;
n500++;
n = 0;
}
if (n100 > 0)
{
if (n500 == 5)
{
n500 = 0;
}
if (n100 % 10 == 0)
{
n100 = 0;
}
}
if (n500)
{
n500 = 0;
}
}
void sys_init()
{
WTST = 0;
CKCON = 0;
EAXFR = 1;
P3M0 = 0x00;
P3M1 = 0x00;
P3M0 &= ~0x03; // P30,P31 和 USB 的 D-,D+ 共用 PIN 脚
P3M1 |= 0x03;// 需要将 P30,P31 设置为高阻输入模式
IRC48MCR = 0x80; // 使能内部 48M 的 USB 专用 IRC
while (!(IRC48MCR & 0x01))
; // 等待震荡源稳定
USBCLK = 0x00; // 设置 USB 时钟源为内部 48M 的 USB 专用 IRC
USBCON = 0x09; // 使能 USB 功能
usb_init(); // 调用 USB CDC 初始化库函数
EUSB = 1; // 使能 USB 中断
}