久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1719|回復: 6
打印 上一主題 下一主題
收起左側

stc8g單片機通過pwm調節led亮度,通電的時候會亮起再滅下

[復制鏈接]
跳轉到指定樓層
樓主
想學pwm,所以在網上下了一個臺燈的代碼自己修改了一下,按鍵key是負責led亮滅,key1短按可以增加led亮度,key2短按減少亮度,長按都可以無極調光,LIGHT是p33口輸出,我設置了通電會自動亮起,亮度為50,但是它通電會亮起再滅掉再亮起,設置成通電不亮起,也會亮一下,在主函數最開始的時候加過LIGHT=0,也還是不行嘞,我試過原來的代碼也會亮一下,但是不知道哪里有問題,有沒有大佬看一下
main.c文件
#include        "config.h"
#include        "gpio.h"
#include        "UART.h"
#include        "delay.h"
#include         "stdio.h"
#include        "STC8xxxx.H"
#include        "stdio.h"
#include        "string.h"
#include         "light.h"
#include        "my_uart.h"
#include        "key.h"

void main(void)
{
        light_init();                //使用定時器0作pwm功能
        key_init();
        EA = 1;
        
        delay_ms(5000);
        light_open();

        while (1)
        {
                delay_ms(1);
               
                if(key_open())
                {
                        light_key_open();
                }
                if(scan_key())
                {
                        //按鍵按下
                        light_task();
                }
        }
}


key.c文件

#include "key.h"

#define KEY    P32
#define Key2   P30
#define Key1   P31

bit ShortTouchFlag1=0;      //按鍵1短按按鍵有效標志
bit LongTouchFlag1=0;       //按鍵1長按按鍵有效標志
bit LongTouchRelease1=1;    //按鍵1長按釋放過的標志
bit ShortTouchFlag2=0;      //按鍵2短按按鍵有效標志
bit LongTouchFlag2=0;       //按鍵2長按按鍵有效標志
bit LongTouchRelease2=1;    //按鍵2長按釋放過的標志
bit Flag_1s=1;              //秒任務標志位
bit HFlag = 0;               
bit ON_OFF_Flag = 0;   

unsigned int uiKeyTimeCnt1; //按鍵1計數
unsigned int uiKeyTimeCnt2; //按鍵2計數


//P54作io輸入口
void key_init(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                //結構定義
        GPIO_InitStructure.Pin  = GPIO_Pin_5;                //指定要初始化的IO,
        GPIO_InitStructure.Mode = GPIO_HighZ;                //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);        //初始化

        // GPIO_InitStructure.Pin  = GPIO_Pin_All;                //指定要初始化的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(GPIO_P6,&GPIO_InitStructure);        //初始化
}

unsigned char key_open(void)   //掃描開關按鍵
{
        if(KEY==0)
        {
                delay_ms(15);
                if(KEY==0)
                {
                          while(KEY==0);
                                ON_OFF_Flag = 1;
                                return 1;
                }               
        }               
        return 0;
}

//掃面按鍵
//返回 1 按下  0 沒有
unsigned char scan_key(void)
{
        if(Key1==0)                     //如果按鍵1按下
        {
            uiKeyTimeCnt1++;            //累加按鍵計時
        }
        if(uiKeyTimeCnt1>100 && LongTouchRelease1==1)   //當按鍵超過2秒且此前釋放過一次時
        {
                LongTouchFlag1 = 1;         //長按標志位置1,用于長按2秒后立即處理長按動作
                LongTouchRelease1 = 0;                 //長按釋放標志置0,表示長按未釋放
                HFlag = 1;
        }
        if(Key1==1)                     //當按鍵松開(也可能是抖動彈開)
        {
                if(uiKeyTimeCnt1>2 && uiKeyTimeCnt1<=100)   //只有大于20mS,且小于2秒,才判為短按
                {
                        uiKeyTimeCnt1 = 0;      //清零按鍵計時
                        ShortTouchFlag1 = 1;        //短按標志位置1
                        LongTouchFlag1 = 0;     //長按標志位置0        
                        HFlag = 1;
                }
                if(uiKeyTimeCnt1>100)       //如果松開按鍵時按鍵超過2秒,則為長按釋放
                {
                        uiKeyTimeCnt1 = 0;      //清零按鍵計時
                        LongTouchRelease1 = 1;  //長按釋放標志位置1,表示長按已釋放
                }        
        }

        if(Key2==0)                     //如果按鍵2按下
        {
            uiKeyTimeCnt2++;            //累加按鍵計時
        }
        if(uiKeyTimeCnt2>100 && LongTouchRelease2==1)   //當按鍵超過2秒且此前釋放過一次時                          
        {
                LongTouchFlag2 = 1;         //長按標志位置1,用于長按2秒后立即處理長按動作
                LongTouchRelease2 = 0;      //長按釋放標志置0,表示長按未釋放
                HFlag = 1;
        }
        if(Key2==1)                     //當按鍵松開(也可能是抖動彈開)
        {
                if(uiKeyTimeCnt2>=2 && uiKeyTimeCnt2<=100)  //只有大于等于20mS,且小于2秒,才判為短按
                {
                        uiKeyTimeCnt2 = 0;      //清零按鍵計時
                        ShortTouchFlag2 = 1;    //短按標志位置1
                        LongTouchFlag2 = 0;     //長按標志位置0        
                        HFlag = 1;
                }
                if(uiKeyTimeCnt2>100)       //如果松開按鍵時按鍵超過2秒,則為長按釋放
                {
                        uiKeyTimeCnt2 = 0;      //清零按鍵計時
                        LongTouchRelease2 = 1;  //長按釋放標志位置1,表示長按已釋放
                }        
        }
        if(HFlag==1)
        {
                return 1;
        }
        else
        {
                return 0;
        }
}


light.c文件

#include "light.h"

#include        "timer.h"
#include        "GPIO.h"
#include  "key.h"

extern bit ShortTouchFlag1;      //按鍵1短按按鍵有效標志
extern bit LongTouchFlag1;       //按鍵1長按按鍵有效標志
extern bit LongTouchRelease1;    //按鍵1長按釋放過的標志
extern bit ShortTouchFlag2;      //按鍵2短按按鍵有效標志
extern bit LongTouchFlag2;       //按鍵2長按按鍵有效標志
extern bit LongTouchRelease2;    //按鍵2長按釋放過的標志
extern bit ON_OFF_Flag;          //按鍵開關標志

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;
        
#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)             //通電的時候自動亮起
{
                light_switch_state = 1;
                set_duty_cycle(50);                //設置占空比
          brightness = 50;
}

void light_key_open(void)      //開關key操作
{
                if(ON_OFF_Flag==1)
                        {
                                ON_OFF_Flag = 0;
                                if(light_switch_state==1)
                                {
                                        light_switch_state=0;
                                        EA = 0;
                                        set_duty_cycle(0);
                                        LIGHT = 0;                        
                                }
                                else
                                {
                                        EA = 1;
                                        light_switch_state=1;
                                        set_duty_cycle(brightness);                //設置占空比
                                }
                        }
}

void light_task(void)     //調節亮度
{
        if(ShortTouchFlag1==1)
                {
                        ShortTouchFlag1 = 0;
                        brightness = current_brightness + 20;
                        if(brightness > 70)        //防止超過100
                        {
                                brightness = 100;                                
                        }
                        if(brightness == 20)
                        {
                                brightness = 10;
                        }
                        set_duty_cycle(brightness);
                }
               
                if(LongTouchFlag1==1)
                {
                        LongTouchFlag1 = 0;
      while(brightness<100)               
                        {
        brightness = current_brightness + 1;
                                set_duty_cycle(brightness);
                                delay_ms(10);
                                scan_key();
                                if(LongTouchRelease1==1)
                                {
                                  break;
                                }
                        }                        
                }               
               
                if(ShortTouchFlag2==1)
                        {
                                ShortTouchFlag2 = 0;
                                brightness = current_brightness - 20;
        if(brightness >70)
                                {                                       
                                        brightness = 70;
                                }
                                if(brightness <10)
                                {
                                        brightness = 0;
                                        light_switch_state = 0;
                                }
                                set_duty_cycle(brightness);
                        }
               
                        if(LongTouchFlag2==1)
                        {
                                LongTouchFlag2 = 0;
                                while(brightness>6&&LongTouchRelease2==0)
                                {
                                        brightness = current_brightness - 1;
                                        set_duty_cycle(brightness);
                                        delay_ms(10);
                                        scan_key();
                                        if(LongTouchRelease2==1)
                                        {
                                                break;
                                        }
                                }
                        }
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:879348 發表于 2024-6-6 14:44 | 只看該作者
有沒有可能這個亮起是不受代碼控制的,你的硬件沒有下拉電阻
回復

使用道具 舉報

板凳
ID:1080935 發表于 2024-6-6 14:51 | 只看該作者
1、初始化最開始把LED管腳設為滅掉狀態(可以單獨用此程序,后續程序不要,判斷是否能在開始關閉LED)。
2、確認電路問題,復位是LED是否亮起,如果亮起可能要調整電路。
回復

使用道具 舉報

地板
ID:961114 發表于 2024-6-6 15:23 | 只看該作者
學會這個 基本上都懂了
回復

使用道具 舉報

5#
ID:1076567 發表于 2024-6-6 15:55 | 只看該作者
wufa1986 發表于 2024-6-6 14:44
有沒有可能這個亮起是不受代碼控制的,你的硬件沒有下拉電阻

有下拉電阻的,應該是代碼的問題,后面我把主函數里的EA=0,然后在light_open()函數里加了EA=1,就可以了
回復

使用道具 舉報

6#
ID:1076567 發表于 2024-6-6 15:56 | 只看該作者
STC莊偉 發表于 2024-6-6 15:23
學會這個 基本上都懂了

好的感謝
回復

使用道具 舉報

7#
ID:1076567 發表于 2024-6-6 15:59 | 只看該作者
LaoYuTou 發表于 2024-6-6 14:51
1、初始化最開始把LED管腳設為滅掉狀態(可以單獨用此程序,后續程序不要,判斷是否能在開始關閉LED)。
2 ...

好的感謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 好姑娘影视在线观看高清 | 国产精品久久久久久久免费观看 | 国产在线精品一区二区三区 | 成人在线精品 | 91精品国产自产在线老师啪 | 伊人最新网址 | av天天澡天天爽天天av | 美女黄网| 三级免费 | 亚洲欧美中文日韩在线v日本 | 亚洲精品视频免费 | 欧美精品久久久久久 | 亚洲一区二区在线视频 | 一级黄色日本片 | 日韩精品一区二区三区在线播放 | 欧美精品日韩 | 99小视频 | 国产精品成人69xxx免费视频 | 国产成人精品一区二区三区 | 欧美精品第一区 | 精品国产一区二区三区久久久四川 | 黄色男女网站 | 色婷婷精品国产一区二区三区 | 欧美全黄| 在线视频 亚洲 | 久久久婷婷 | 久草久草久草 | 日韩国产一区二区 | 久久岛国| 亚洲综合在线视频 | 一区二区三区四区视频 | 国产农村妇女精品一区 | 久久精品国内 | 亚洲精品成人在线 | 全免费a级毛片免费看视频免 | 亚洲一区在线日韩在线深爱 | 久久久久久国产精品 | 免费看黄色视屏 | 日本免费在线观看视频 | 亚洲精品中文字幕中文字幕 | 久久专区|