找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1491|回复: 4
收起左侧

初学单片机,一键功能循环程序设计问题;

[复制链接]
ID:457802 发表于 2019-1-4 17:24 | 显示全部楼层 |阅读模式
初学单片机,要做个轻触按键实现两个IO口的输出并循环;
状态如下:
          IO1(LED);                IO2(EN);
1:   高电平;                       高电平;
2:   低电平;                       5秒发出一个0.2S的低电平脉冲;
3:   1kHz的50%的PWM;      5秒发出一个0.2S的低电平脉冲;
循环

写的程序如下:
去掉红色字符,写到单片机里,IO1的输出状态正常;
加上红色字符,想让IO2也输出,就不正常了;不知道为什么;
还有如果把“void Dis2()”里的时间沿长,按键也要久按才能切换状态;
请大家指教;
(程序语句,也是我参考不同人的不同方案,加上自己看视频慢慢学的);
请多赐教;

还有本想来想把“void Dis1()”用定时器准确定时的,但发现到第三步就不能循环了;

#include<reg52.h>
#include<intrins.h>

typedef unsigned char uint8;
typedef unsigned int uint16;

sbit LED=P1^0;
sbit LED2=P1^2;
sbit EN=P1^4;
sbit key=P3^4;
uint8 count = 0;

void delay(unsigned char a)
{
        unsigned int i,j;
        for(i=0;i<a;i++)
  for(j=0;j<500;j++);
}

void Dis1()
{
                unsigned char b,c;       
          LED=1;
                while(1)
                {
                        LED=0;
                        for(b=0; b<10; b++)
                        {
                                for(c=0;c<10;c++);
                        }
                        LED=1;
                        for(b=0; b<100; b++);
                        break;       
                }
        }

void Dis2()
{
                unsigned int i,j;       
                while(1)
                {
                        EN=1;
                        for(j=0; j<5000; j++)
                                {
                                for(i=0;i<10;i++);
                                }
                        EN=0;
                        for(j=0; j<1000; j++);
                        EN=1;
                        for(j=0; j<5000; j++)
                                {
                                for(i=0;i<10;i++);
                                }
                        break;       
                }
        }

void main()
{
  LED=1;
        EN=1;
        LED2=1;       
  while(1)
        {
                if(key==0)
                        {
                                delay(20);
                                if(key==0)
                                        {
                                                while(key==0);
                                                        {
                                                                count++;
                                                                count%=3;
                                                        }
                                        }
                        }

                switch(count)
                {
                        case 0:LED=1;EN=1;break;
                        case 1:LED=0;Dis2();break;
                        case 2:Dis1();Dis2();break;
                }
        }
}


回复

使用道具 举报

ID:459687 发表于 2019-1-4 19:59 | 显示全部楼层
小兄弟真是个新手,问题不少,首先你while(1)循环最后加个break,循环就跳出了,那你还加while循环干什么,白白增加程序阅读难度;
第二,所有程序都是顺序执行的,加上红色部分count==0时应该没问题,因为一个命令就回到循环了;为1时LED=0,然后等Dis2执行一遍再循环,应该问题也不大,虽然不是正常程序写法,但应该满足你的要求;但为2时就无法满足了,首先执行dis1,输出一个脉冲后,要去执行dis2这时LED一直是高电平,也就是你dis2执行多长时间LED就多长时间的高电平,然后返回来继续,这样LED和EN两个口是交替操作的,当然不能满足你的要求;
第三,你要在switch(count)的程序执行完了才能回到上面的按键检测,当然要等dis2执行完才能检测到按键。

评分

参与人数 1黑币 +100 收起 理由
admin + 100 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:213173 发表于 2019-1-4 21:51 | 显示全部楼层
给你改了,要用定时器,你试试。
#include<reg52.h>
#include<intrins.h>

typedef unsigned char uchar;
typedef unsigned int uint;

sbit LED=P1^0;
sbit LED2=P1^2;
sbit EN=P1^4;
sbit key=P3^4;

uchar count=0,count1=0;
uint num=0;
bit i=0,j=0;

void delay(uint a)
{
        uint i,j;
        for(i=0;i<a;i++)
                for(j=0;j<500;j++);
}

void Timer0Init()        //500微秒@12.000MHz
{
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x0C;                //设置定时初值
        TH0 = 0xFE;                //设置定时初值
        TR0 = 1;                //定时器0开始计时
        EA = 1;
        ET0 = 1;
}

void main()
{
        LED2=1;
        Timer0Init();
        while(1)
        {
                if(key==0)
                {
                        delay(20);
                        if(key==0)
                        {
                                count++;
                                if(count>2)
                                        count=0;
                                while(!key);
                        }
                }
        }
}
/**************中断服务程序*****************/
void timer0() interrupt        1        //500微秒@12.000MHz
{
        TL0 = 0x0C;                //设置定时初值
        TH0 = 0xFE;                //设置定时初值
        i=~i;
        if(count==0){LED=1;EN=1;}
        if(count!=0)
        {
                num++;
                if(num<=9600)
                        j=1;
                else j=0;
                if(num>=10000)
                        num=0;
        }
        if(count==1){LED=0;EN=j;}
        if(count==2){LED=i;EN=j;}
}

评分

参与人数 1黑币 +90 收起 理由
admin + 90 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:457802 发表于 2019-1-5 08:41 | 显示全部楼层
kanghl1 发表于 2019-1-4 19:59
小兄弟真是个新手,问题不少,首先你while(1)循环最后加个break,循环就跳出了,那你还加while循环干什么, ...

谢谢点评,我一定加油学习;
回复

使用道具 举报

ID:457802 发表于 2019-1-5 08:57 | 显示全部楼层
wulin 发表于 2019-1-4 21:51
给你改了,要用定时器,你试试。
#include
#include

谢谢您,对程序逻辑我又进一步的了解了;
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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