找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 897|回复: 12
打印 上一主题 下一主题
收起左侧

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);           // 检查按键
      }
        }




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1133081 发表于 2024-12-6 07:07 | 只看该作者
P5.4设置高阻模式   P5M0 = 0x00; P5M1 = 0x10;
回复

使用道具 举报

板凳
ID:1109793 发表于 2024-12-6 07:38 | 只看该作者
引脚设置为高祖输入状态嘛
回复

使用道具 举报

地板
ID:857072 发表于 2024-12-6 07:59 来自触屏版 | 只看该作者
你没有算按键的阻值吗。
回复

使用道具 举报

5#
ID:1076567 发表于 2024-12-6 09:04 | 只看该作者
WL0123 发表于 2024-12-6 07:07
P5.4设置高阻模式   P5M0 = 0x00; P5M1 = 0x10;

就是设置成高阻模式下还有电压
回复

使用道具 举报

6#
ID:1076567 发表于 2024-12-6 09:08 | 只看该作者
a185980800 发表于 2024-12-6 07:59
你没有算按键的阻值吗。

按键的阻值,按键也有阻值吗,还是说按键连接的电阻,这个我算好了的,但是p5.4处有电压 s1和s2处的就不准了
回复

使用道具 举报

7#
ID:1076567 发表于 2024-12-6 09:08 | 只看该作者
xiaobendan001 发表于 2024-12-6 07:38
引脚设置为高祖输入状态嘛

就是设置成高阻模式下还有电压
回复

使用道具 举报

8#
ID:446156 发表于 2024-12-6 10:11 | 只看该作者
用放大器跟随一下再进IO口
回复

使用道具 举报

9#
ID:446156 发表于 2024-12-6 10:12 | 只看该作者
再说了你这玩意为什么非要和计算的一样才行,直接把按键按下去看看实际读数然后把读数记下来不就得了
回复

使用道具 举报

10#
ID:1138748 发表于 2024-12-6 10:14 | 只看该作者
在按键上并联0.01uf的电容
回复

使用道具 举报

11#
ID:57657 发表于 2024-12-6 12:10 | 只看该作者
a185980800 发表于 2024-12-6 07:59
你没有算按键的阻值吗。

按键的阻值在毫欧级别可以忽略不计。
回复

使用道具 举报

12#
ID:92781 发表于 2024-12-6 15:40 | 只看该作者
你可以把电阻串联,这样就好计算了

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

51hei截图_20241206153938.png
回复

使用道具 举报

13#
ID:1133081 发表于 2024-12-6 21:09 | 只看该作者
Dokkis 发表于 2024-12-6 09:04
就是设置成高阻模式下还有电压

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

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表