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 中断
}





页: 1 2 3 [4]
查看完整版本: 跟着冲哥学习单片机