标题: STC8G单片机单个io口连接6个按键,引脚的电压会影响采集电压怎么办 [打印本页]

作者: Dokkis    时间: 2024-12-5 16:47
标题: STC8G单片机单个io口连接6个按键,引脚的电压会影响采集电压怎么办
想通过adc采集电压,让一个引脚接6个按键进行不同的功能,经过计算后接入不同的电阻如原理图,但是s1和s2处实际电压跟算出来的不一样,后面我把单片机1脚的电路断开,单独测了1脚的电压有2.8v,s1和s2的电压也跟计算的一样了。有什么办法能够让1脚的电压不影响到s1和2呀,还是只能重新计算阻值了,但是那个实际的电压我也想不通是怎么算出来的,有没有大神救救我理论电压:s1:0.41v s2:1.24v s3:2.07v s4:2.91v s5:3.73v s6:4.57v
实际电压:s1:1.89v s2:1.89v s3:2.23v s4:2.94v s5:3.5v  s6:4.6v
按键电压范围:s1:0-0.83v s2:0.83-1.66v s3:1.66-2.49v s4:2.49-3.32v s5:3.32-4.15v s6:4.15-4.9v




还有一个就是我s3 s4 s5 s6的电压跟计算的差不多,但是按键的功能也实现不了,调光程序是之前写好的可以用的,我就在里面加了adc和check_keys函数,不知道为什么用不了
s1:控制灯开关和闭合 s2:将灯调为0% s3:25% s4:50% s5:75% s6:100%
程序:
#include        "config.h"
#include        "gpio.h"
#include        "UART.h"
#include        "delay.h"
#include         "stdio.h"
#include        "STC8xxxx.H"
#include        "string.h"
#include         "light.h"
#include        "my_uart.h"
#include        "timer.h"

unsigned long timer0_count = 0;
unsigned char PWM_T = 0;   //0-250占空比控制变
unsigned char current_brightness = 0;        //当前亮度
unsigned char light_switch_state = 0;        //灯开关状态
signed int    brightness = 0;
unsigned char key_open = 1;
#define IT_HZ        100000        //中断频率
#define TIM0_VALUE        65536UL - (MAIN_Fosc / IT_HZ)

void        light_init(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义
        TIM_InitTypeDef                TIM_InitStructure;                                                //结构定义
/************************ P33 IO口配置 ****************************/
        GPIO_InitStructure.Pin  = LIGHT_PIN;                                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
        GPIO_InitStructure.Mode = GPIO_PullUp;                        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(LIGHT_PORT,&GPIO_InitStructure);        //初始化

/************************ 定时器配置 ****************************/
        TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;        //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
        TIM_InitStructure.TIM_Priority    = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
        TIM_InitStructure.TIM_Interrupt = ENABLE;                                        //中断是否允许,   ENABLE或DISABLE
        TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T;                //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
        TIM_InitStructure.TIM_ClkOut    = DISABLE;                                //是否输出高速脉冲, ENABLE或DISABLE
        // TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / 100000UL);                //初值,
        TIM_InitStructure.TIM_Value     = TIM0_VALUE;                //初值,
        TIM_InitStructure.TIM_Run       = ENABLE;                                        //是否初始化后启动定时器, ENABLE或DISABLE
        Timer_Inilize(Timer0,&TIM_InitStructure);                                        //初始化Timer0          Timer0,Timer1,Timer2,Timer3,Timer4

}


//设置高电平占空比
//num: 0-100%
void set_duty_cycle(unsigned char num)
{
        current_brightness = num;
        if(num > 0)
        {
                light_switch_state = 1;
        }
        else
        {
                light_switch_state = 0;
        }
        PWM_T = (float)(num / 100.0)*250;
}

/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
         timer0_count++;    //每次定时器溢出加1
         
         if(timer0_count==250)   //PWM周期 100个单位
                 {
                        timer0_count=0;  //使t=0,开始新的PWM周期
                        LIGHT = 1;        //开灯
                 }
         
         if(PWM_T==timer0_count)  //按照当前占空比切换输出为高电平
                 {  
                        LIGHT = 0;        //关灯
                 }

}

//获取灯光占空比
//返回值: 0-100
int get_light_pwm(void)
{
        return PWM_T*100/250;
        // return 0;
}

void light_open(void)  //通电时亮灯为25%
{
          EA = 1;
                light_switch_state = 1;
                set_duty_cycle(25);                //设置占空比
          brightness = 25;
}


#define ADC_CHANNEL 4 // 使用P5.4作为ADC输入,对应ADC通道4
#define VCC 5000      // 供电电压,单位mV

// 初始化系统
void System_Init(void)
        {
    P5M1 = 0x00; // 设置P5.4为模拟输入 引脚1
    P5M0 = 0x10;

    // 设置ADC
    ADC_CONTR = 0x80 + (ADC_CHANNEL << 3); // 选择ADC通道4
    ADC_RES = 0x00;
    ADC_RESL = 0x00;
        }

// 读取ADC值
int Read_ADC(void)
{
    ADC_CONTR |= 0x80; // 开始ADC转换
    while(ADC_CONTR & 0x80); // 等待转换完成
    return (ADC_RES << 8) | ADC_RESL; // 返回10位ADC结果
}

// 判断按键
void Check_Keys(int adc_value)
        {
    if (adc_value > 0 && adc_value < 170)  //按键s1
                        {
                                        if(light_switch_state==1)  //如果灯是开的就关闭
                                        {
                                                light_switch_state=0;
                                                EA = 0;
                                                set_duty_cycle(0);
                                                LIGHT = 0;                        
                                        }
                                        else     //灯是灭的就打开并设置为50%
                                        {
                                                EA = 1;
                                                light_switch_state=1;
                                                brightness = 50;
                                                set_duty_cycle(brightness);                //设置占空比
                                        }
      }
                else if (adc_value >= 171 && adc_value < 340)   //按键s2 设置为0
                        {
                                brightness = 0;
                                set_duty_cycle(brightness);
        // 按键2
      }
                else if (adc_value >= 341 && adc_value < 510)  //按键s3 设置为25%
                        {
                                brightness = 25;
                                set_duty_cycle(brightness);
        // 按键3
      }
                else if (adc_value >= 511 && adc_value < 680)  //按键s4 设置为50%
                        {
                                brightness = 50;
                                set_duty_cycle(brightness);
        // 按键4
      }
                else if (adc_value >= 681 && adc_value < 850)   //按键s5 设置为75%
                        {
                                brightness = 75;
                                set_duty_cycle(brightness);
        // 按键5
      }
                else if(adc_value >=851 && adc_value <1005)  //按键s6 设置为100%
                {
                        brightness = 100;
                        set_duty_cycle(brightness);
                }
        }

// 主函数
void main(void)
        {
            System_Init();
            light_init();                //使用定时器0作pwm功能
            EA = 0;
               
            delay_ms(5000);
            light_open();
               
    while (1)
                        {
        int adc_value = Read_ADC(); // 读取ADC值
                                delay_ms(1);
        Check_Keys(adc_value);           // 检查按键
      }
        }





作者: WL0123    时间: 2024-12-6 07:07
P5.4设置高阻模式   P5M0 = 0x00; P5M1 = 0x10;

作者: xiaobendan001    时间: 2024-12-6 07:38
引脚设置为高祖输入状态嘛
作者: a185980800    时间: 2024-12-6 07:59
你没有算按键的阻值吗。
作者: Dokkis    时间: 2024-12-6 09:04
WL0123 发表于 2024-12-6 07:07
P5.4设置高阻模式   P5M0 = 0x00; P5M1 = 0x10;

就是设置成高阻模式下还有电压
作者: Dokkis    时间: 2024-12-6 09:08
a185980800 发表于 2024-12-6 07:59
你没有算按键的阻值吗。

按键的阻值,按键也有阻值吗,还是说按键连接的电阻,这个我算好了的,但是p5.4处有电压 s1和s2处的就不准了
作者: Dokkis    时间: 2024-12-6 09:08
xiaobendan001 发表于 2024-12-6 07:38
引脚设置为高祖输入状态嘛

就是设置成高阻模式下还有电压
作者: qinlu123    时间: 2024-12-6 10:11
用放大器跟随一下再进IO口
作者: qinlu123    时间: 2024-12-6 10:12
再说了你这玩意为什么非要和计算的一样才行,直接把按键按下去看看实际读数然后把读数记下来不就得了
作者: pllcai    时间: 2024-12-6 10:14
在按键上并联0.01uf的电容
作者: npn    时间: 2024-12-6 12:10
a185980800 发表于 2024-12-6 07:59
你没有算按键的阻值吗。

按键的阻值在毫欧级别可以忽略不计。
作者: jjy1039    时间: 2024-12-6 15:40
你可以把电阻串联,这样就好计算了

51hei截图_20241206153938.png (113.25 KB, 下载次数: 0)

51hei截图_20241206153938.png

作者: WL0123    时间: 2024-12-6 21:09
Dokkis 发表于 2024-12-6 09:04
就是设置成高阻模式下还有电压

你仔细看看你的程序里设置的是什么模式!犯这么低级的错误。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1