找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1102|回复: 8
收起左侧

单片机模式0做一个渐亮渐灭的效果,按键调速有没有可能实现,搞了10天没办法

[复制链接]
ID:879080 发表于 2022-10-21 11:09 | 显示全部楼层 |阅读模式
用的是STC15W24S单片机,P1输出,P3口输入,三个按键,两个调速度快慢,一个调模式。我想把void Mode_0(void)做成可调速的渐亮渐灭效果。
两年的单片机学习之路却搞不定,麻烦各位师傅们指点。谢谢了!
#include <STC15W204S.H>

unsigned char RunMode;
//**********************************System Fuction*************************************************
void Delay1ms(unsigned int count)
{
        unsigned int i,j;
        for(i=0;i<count;i++)
        for(j=0;j<120;j++);
}



unsigned char GetKey(void)
{
        unsigned char KeyTemp,CheckValue,Key = 0x00;
        CheckValue = P3&0x32;
        if(CheckValue==0x32)
                return 0x00;

        Delay1ms(10);
        KeyTemp = P3&0x32;
        if(KeyTemp==CheckValue)
                return 0x00;

        if(!(CheckValue&0x02))
                Key|=0x01;
        if(!(CheckValue&0x10))
                Key|=0x02;
        if(!(CheckValue&0x20))
                Key|=0x04;
        return Key;
}

unsigned int TimerCount,SystemSpeed,SystemSpeedIndex;
void InitialTimer0(void)
{
        TMOD  = 0x00;                        
        TH0 = TL0 = 0xFC;               
        ET0=1;                                       
        TR0=1;                              
        EA=1;
}

unsigned int code SpeedCode[]={   1,   2,   3,   5,   8,  10,  14,  17,  20,  30,
                                  40,  50,  60,  70,  80,  90, 100, 120, 140, 160,
                                  180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//30
void SetSpeed(unsigned char Speed)
{
        SystemSpeed =SpeedCode[Speed];
}

void LEDShow(unsigned int LEDStatus)
{
        P1 = ~(LEDStatus&0xFF);

}

void InitialCPU(void)
{
        RunMode = 0x00;
        TimerCount = 0;
        SystemSpeedIndex = 10;

        P1 = 0xFF;

        P3 = 0xFF;
        Delay1ms(500);
        P1 = 0xFF;

        P3 = 0xFF;
        SetSpeed(SystemSpeedIndex);

}

//Mode 0
unsigned int LEDIndex = 0;
bit LEDDirection = 1,LEDFlag = 1;
void Mode_0(void)
{
        
}
//Mode 1
void Mode_1(void)
{
        LEDShow(0x80>>LEDIndex);
        LEDIndex = (LEDIndex+1)%8;
}


void TimerEventRun(void)
{
        if(RunMode==0x00)
        {
                Mode_0();        
        }
        else if(RunMode ==0x01)
        {
                Mode_1();
        }

}
void Timer0(void) interrupt 1 using 1
{
        TF0 = 0;        
        if(++TimerCount>=SystemSpeed)
        {
                TimerCount = 0;
                TimerEventRun();
                                 
           }
}
unsigned char MusicIndex = 0;
void KeyDispose(unsigned char Key)
{
        if(Key&0x01)
        {
                LEDDirection = 1;
                LEDIndex = 0;
                LEDFlag = 1;
                RunMode = (RunMode+1)%2;

        }
        if(Key&0x02)
        {
                if(SystemSpeedIndex>0)
                {
                        --SystemSpeedIndex;
                        SetSpeed(SystemSpeedIndex);
                }
                else
                {

                }
        }
        if(Key&0x04)
        {
                if(SystemSpeedIndex<28)
                {
                        ++SystemSpeedIndex;
                        SetSpeed(SystemSpeedIndex);
                }
                else
                {

                }
        }        
}

//***********************************************************************************
main()
{
        unsigned char Key;
        InitialCPU();
        InitialTimer0();

        while(1)
        {
                Key = GetKey();
                if(Key!=0x00)
                {
                        KeyDispose(Key);
                }
        }
}


回复

使用道具 举报

ID:491577 发表于 2022-10-21 16:17 | 显示全部楼层
很简单,用定时器定时10ms,在定时器中断中计数产生秒的变量。用PWM产生0-100%PWM,频率100-1Khz,时间0-3秒钟,PWM从0-100%(每30msPWM增加1%),3-6秒,PWM从100-0%,然后循环。时间间隔一定要大于1秒,太短看不到效果。
回复

使用道具 举报

ID:713651 发表于 2022-10-21 17:01 | 显示全部楼层
总工说的对
回复

使用道具 举报

ID:161164 发表于 2022-10-21 17:36 | 显示全部楼层
你这种写法是传统单片机模式2的8位定时器吧
2022-10-21_173209.png


STC15的模式0是16位的
2022-10-21_172947.png

回复

使用道具 举报

ID:161164 发表于 2022-10-21 17:41 | 显示全部楼层
你这种写法是传统单片机模式2的8位定时器吧
2022-10-21_173209.png


STC15的模式0是16位的
2022-10-21_172947.png

回复

使用道具 举报

ID:879080 发表于 2022-10-21 19:32 | 显示全部楼层
lkc8210 发表于 2022-10-21 17:41
你这种写法是传统单片机模式2的8位定时器吧

是的,还不太会定时器。也知道这款单片机有16位自动重装功能。我学单片机也很久了,只熟悉delay()延时,看到&,|,!,参数传递这些都不理解了,很喜欢玩单片机,始终没办法提高自己水平,真是爱恨交加
回复

使用道具 举报

ID:879080 发表于 2022-10-21 19:35 | 显示全部楼层
hhh402 发表于 2022-10-21 16:17
很简单,用定时器定时10ms,在定时器中断中计数产生秒的变量。用PWM产生0-100%PWM,频率100-1Khz,时间0-3 ...

感谢指导,这样能用按键调时间吗? 谢谢
回复

使用道具 举报

ID:879080 发表于 2022-10-21 19:53 | 显示全部楼层
lkc8210 发表于 2022-10-21 17:41
你这种写法是传统单片机模式2的8位定时器吧

#define FOSC 11059200L

#define T1MS (65536-FOSC/1000)      //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式


    AUXR |= 0x80;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 1;
我看了官方的实例,应该这样改。
回复

使用道具 举报

ID:879080 发表于 2022-10-22 08:24 | 显示全部楼层
lkc8210 发表于 2022-10-21 17:41
你这种写法是传统单片机模式2的8位定时器吧

#include <REG52.H>

unsigned char RunMode;

#define FOSC 11059200L
#define T1MS (65536-FOSC/1000)      //1T模式
sfr AUXR = 0x8e;   
//**********************************System Fuction*************************************************
void Delay1ms(unsigned int count)
{
        unsigned int i,j;
        for(i=0;i<count;i++)
        for(j=0;j<120;j++);
}



unsigned char GetKey(void)
{
        unsigned char KeyTemp,CheckValue,Key = 0x00;
        CheckValue = P3&0x32;
        if(CheckValue==0x32)
                return 0x00;

        Delay1ms(10);
        KeyTemp = P3&0x32;
        if(KeyTemp==CheckValue)
                return 0x00;

        if(!(CheckValue&0x02))
                Key|=0x01;
        if(!(CheckValue&0x10))
                Key|=0x02;
        if(!(CheckValue&0x20))
                Key|=0x04;
        return Key;
}

unsigned int TimerCount,SystemSpeed,SystemSpeedIndex;
void InitialTimer0(void)
{

        AUXR |= 0x80;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 1;
}

unsigned int code SpeedCode[]={   1,   2,   3,   5,   8,  10,  14,  17,  20,  30,
                                  40,  50,  60,  70,  80,  90, 100, 120, 140, 160,
                                  180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//30
void SetSpeed(unsigned char Speed)
{
        SystemSpeed =SpeedCode[Speed];
}

void LEDShow(unsigned int LEDStatus)
{
        P1 = ~(LEDStatus&0xFF);
      
}

void InitialCPU(void)
{
        RunMode = 0x00;
        TimerCount = 0;
        SystemSpeedIndex = 10;

        P1 = 0xFF;
        
        P3 = 0xFF;
        Delay1ms(500);
        P1 = 0xFF;
        
        P3 = 0xFF;
        SetSpeed(SystemSpeedIndex);

}

//Mode 0
unsigned int LEDIndex = 0;
bit LEDDirection = 1,LEDFlag = 1;
void Mode_0(void)
{
       
}
//Mode 1
void Mode_1(void)
{
        LEDShow(0x80>>LEDIndex);
        LEDIndex = (LEDIndex+1)%8;
}


void TimerEventRun(void)
{
        if(RunMode==0x00)
        {
                Mode_0();        
        }
        else if(RunMode ==0x01)
        {
                Mode_1();
        }
      
}
void Timer0(void) interrupt 1 using 1
{
               
        if(++TimerCount>=SystemSpeed)
        {
                TimerCount = 0;
                TimerEventRun();
                                 
           }
}
unsigned char MusicIndex = 0;
void KeyDispose(unsigned char Key)
{
        if(Key&0x01)
        {
                LEDDirection = 1;
                LEDIndex = 0;
                LEDFlag = 1;
                RunMode = (RunMode+1)%2;

        }
        if(Key&0x02)
        {
                if(SystemSpeedIndex>0)
                {
                        --SystemSpeedIndex;
                        SetSpeed(SystemSpeedIndex);
                }
                else
                {

                }
        }
        if(Key&0x04)
        {
                if(SystemSpeedIndex<28)
                {
                        ++SystemSpeedIndex;
                        SetSpeed(SystemSpeedIndex);
                }
                else
                {

                }
        }        
}

//***********************************************************************************
main()
{
        unsigned char Key;
        InitialCPU();
        InitialTimer0();

        while(1)
        {
                Key = GetKey();
                if(Key!=0x00)
                {
                        KeyDispose(Key);
                }
        }
}
定时器改成了16位自动重装
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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