lezjin 发表于 2024-6-28 21:04:33

七ADC按键    时间片调用4个函数,点两个灯,串口2测试,ADC按键扫描,ADC按键检测后简单点灯测试。 参考例程代码采用if判断ADC值误差返回
健码,设置3次状态读取判断,可以正常运行,论坛里有一种采用移位然后switch的方法据说更快,后续再实验。




/*-------------------------------------------------------------------------------
@brief:ADC初始化
@param:
@retval:
------------------------------------------------------------------------------*/
void AdcInit(void)
{
        ADCTIM = 0X3F;//00111111   通道选择时间 CSSETUP : 0, 通道选择保持时间CSHOLD 01 , 采样时间SMPDUTY :11111;   
        ADCCFG = 0x2f;//00101111    转换结果格式 RESFMT: 1,ADC工作工作时钟频率 SPEED : 1111sysclkk/2/speed;
        ADC_CONTR = 0x80; // adcpower = 1;       
}


/*-------------------------------------------------------------------------------
@brief:查询ADC转换完成标志位获取转换结果
@param:channel 要转换的通道 有效值0-15
@retval:12位的ADC转换结果
------------------------------------------------------------------------------*/
uint16_t GetAdcResult(uint8_t channel)
{
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = (ADC_CONTR & 0XF0) | 0x40 | channel; //adcstart
       
        _nop_();       
        _nop_();       
        _nop_();       
        _nop_();       
       
        while((ADC_CONTR & 0x20) == 0);
        ADC_CONTR &= ~0x20;
        return (((uint16_t) ADC_RES << 8) | ADC_RESL);
}


static uint8_tAdcKeystate;
static uint8_tAdcKeystateOne;
static uint8_tAdcKeystateSec;
static uint8_tAdcKeystateThr;
static uint8_tAdcKeyHoldCnt;


/*-------------------------------------------------------------------------------
@brief:获取ADC键码值
@param:adcval:按键按下是获取的ADC值
@retva:KeyValue:根据ADC值计算出来对应到具体哪个按键,返回键码值
------------------------------------------------------------------------------*/
uint8_t CalcAdcKey(uint16_t adcval)
{
        uint8_t i;
        uint16_t j;
        uint8_tKeyValue = 0;

        if ( adcval < (256 - ADC_OFFSET) )
        {
                AdcKeystate = 0;
                AdcKeyHoldCnt = 0;
        }
        j = 256;
        for (i = 1; i <= 16; i++)
        {
                if ((adcval >= (j - ADC_OFFSET)) && (adcval <= (j + ADC_OFFSET))) //找出在偏差上下限范围内的I值
                        break;
                j +=256;
        }

        AdcKeystateThr = AdcKeystateSec;
        AdcKeystateSec = AdcKeystateOne;

        if (i > 16)
        {
                AdcKeystateOne = 0;
        }
        else
        {
                AdcKeystateOne = i;
                if ((AdcKeystateThr == AdcKeystateSec) && (AdcKeystateSec == AdcKeystateOne) &&
                                (AdcKeystateThr > 0) && (AdcKeystateSec > 0) && (AdcKeystateOne > 0))
                {
                        if (AdcKeystate == 0)
                        {
                                KeyValue = i;
                                AdcKeystate = i;
                                AdcKeyHoldCnt = 0;
                        }
                        if (AdcKeystate == i)
                        {
                                if ( ++AdcKeyHoldCnt >= 100)
                                {
                                        AdcKeyHoldCnt = 90;
                                        KeyValue = i;
                                }
                        }
                        else
                        {
                                AdcKeyHoldCnt = 0;
                        }
                }
        }
        return KeyValue;
}




/*-------------------------------------------------------------------------------
@brief: ADC按键测试函数
@param:   
@retva:
------------------------------------------------------------------------------*/

voidAdcKeyTest(void)
{
    uint8_t keyresult = 0;
    uint16_t adcresult = 0;
    adcresult = GetAdcResult(0);
    if (adcresult < 4096)
    {
      keyresult = CalcAdcKey(adcresult);
    }

    if (keyresult > 0)
    {
      switch (keyresult)
      {
            case 1:
                P66 = ~P66;
                break;
             case 5:
                P67 = ~P67;
                break;
            case 8:
                P65 = ~P65;
                break;
            default:
                P64 = ~P64;
                break;
      }
    }

}



static Task_t g_task[] =
{
//状态计数周期函数

        {0,   500,   500,        LedCtrlone},
        {0,   10,   10,        AdcKeyTest},
        {0,   5000,   5000,testuart2},
        {0,   2000,   2000,        LedCtrltwo},
        /* Add new task here */

};



soma 发表于 2024-6-28 21:36:19

实验箱蛮强大的

lezjin 发表于 2024-6-29 17:07:55

soma 发表于 2024-6-28 21:36
实验箱蛮强大的

试验箱功能很多,可以学习到很多常用的外设。
页: 1 [2]
查看完整版本: STC8H试验箱学习记录