想通過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
51hei圖片_20241205151950.png (55.53 KB, 下載次數: 0)
下載附件
2024-12-5 15:26 上傳
還有一個就是我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); // 檢查按鍵
}
}
|