新人求助 51单片机

[复制链接]
2449|17
 楼主| javachen 发表于 2019-11-19 09:40 | 显示全部楼层 |阅读模式
想做个东西之前是做硬件的 一步步的学   上电延时3s后 I/0输出高电平  3s后高电平变为500us周期 50%占空的方波
[code]#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;

sbit led=P2^0;         //定义P20口是led


/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能                   : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0Init()
{     //T1设置
        TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

        TH0=0XFF;        //给定时器赋初值,定时250US
        TL0=0X06;
        ET0=1;//打开定时器0中断允许
        TR0=1;//打开定时器       
        EA=1;//打开总中断
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{       
        Timer0Init();  //定时器初始化
        while(1);               
}

/*******************************************************************************
* 函 数 名         : void Timer0() interrupt 1
* 函数功能                   : 定时器0中断函数
* 输    入         : 无                                                                                          
* 输    出         : 无
*******************************************************************************/
void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFF;        //给定时器赋初值,定时250Us
        TL0=0X06;
        i++;
        if(i<=12000)
        {
                led=0;       
        }       
       
        if(i>12000&&i<24000)
        {   
                led=1;       
        }
        if(i>=24000)
        {  
                ??????/不会;     
        }   
                       
}
上面是延时的

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

sbit LED=P2^0;    //定义LED端口

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
TH0=0xff;              //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
TL0=0x06;
EA=1;            //总中断打开
ET0=1;           //定时器中断打开
TR0=1;           //定时器开关打开
}
/*------------------------------------------------
                    主程序
------------------------------------------------*/
main()
{
Init_Timer0();
while(1);
}

/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=0x00;                  //重新赋值
TL0=0x06;

LED=~LED;        //
定时的   
分开来,都能实现 ,就是合不起来  有没有人交一下  ,之前程序都是找人做的 ,
 楼主| javachen 发表于 2019-11-19 09:41 | 显示全部楼层
大神么  新手求助
dirtwillfly 发表于 2019-11-19 13:00 | 显示全部楼层
没看懂你有什么具体问题?
建议说下具体的问题
384432662 发表于 2019-11-19 15:34 | 显示全部楼层
void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFF;        //给定时器赋初值,定时250Us
        TL0=0X06;
        if(i>=24000)
        {  
                LED=~LED;//不会;     
        }else{  
                i++;
                if(i<=12000)
                {
                        led=0;        
                       }        
        
                if(i>12000&&i<24000)
                {   
                        led=1;        
                }
               }
                        
}
 楼主| javachen 发表于 2019-11-19 15:58 | 显示全部楼层
384432662 发表于 2019-11-19 15:34
void Timer0() interrupt 1
{
        static u16 i;

好像可以了大神膜拜
 楼主| javachen 发表于 2019-11-19 16:02 | 显示全部楼层
javachen 发表于 2019-11-19 15:58
好像可以了大神膜拜
  1. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. typedef unsigned int u16;          //对数据类型进行声明定义
  3. typedef unsigned char u8;
  4. sbit led=P2^0;    //定义LED端口
  5. bit flag;

  6. /*------------------------------------------------
  7.                     定时器初始化子程序
  8. ------------------------------------------------*/
  9. void Init_Timer01(void)
  10. {
  11. TMOD |= 0x11;          //             
  12. TH0=0xff;              //
  13. TL0=0x06;           
  14. ET0=1;           //定时器中断打开
  15. TR0=1;           //定时器开关打开
  16. TH1=0xff;
  17. TL0=0x06;
  18. ET1=1;           //定时器中断打开
  19. TR1=1;
  20. EA=1;
  21. PT1=1;
  22. }
  23. /*------------------------------------------------
  24.                     主程序
  25. ------------------------------------------------*/
  26. main()
  27. {
  28. Init_Timer01();
  29. while(1);
  30. }

  31. /*------------------------------------------------
  32.                  定时器中断子程序
  33. ------------------------------------------------*/
  34. void Timer1_isr(void) interrupt 3
  35. {
  36. TH1=0xff;                  //重新赋值
  37. TL1=0x06;
  38. flag=~flag;        //指示灯反相,可以看到闪烁
  39.        

  40. }
  41. void Timer0() interrupt 1
  42. {
  43.         static u16 i;
  44.         TH0=0XFF;        //给定时器赋初值,定时250Us
  45.         TL0=0X06;
  46.         i++;
  47.         if(i<=12000)
  48.         {     
  49.                 led=0;
  50.                            
  51.         }       
  52.        
  53.         if(i>12000&&i<24000)
  54.         {   
  55.                 led=1;       
  56.         }
  57.         if(i>=24000&&i<=48000)
  58.         {                   
  59.                 led=flag;
  60.                           
  61.         }   
  62.        
  63.        
  64. }




  65. 为嘛我这样写不对  ,老是循环 i到65535 之后就重复 你这个不会啊
384432662 发表于 2019-11-19 16:15 | 显示全部楼层

不是大神。。。 我也在学    我那个i>=24000后就不会执行i++这个语句了
 楼主| javachen 发表于 2019-11-19 16:17 | 显示全部楼层
384432662 发表于 2019-11-19 16:15
不是大神。。。 我也在学    我那个i>=24000后就不会执行i++这个语句了 ...

好吧  你学的深一点  我还在初学  
 楼主| javachen 发表于 2019-11-19 16:41 | 显示全部楼层
384432662 发表于 2019-11-19 16:15
不是大神。。。 我也在学    我那个i>=24000后就不会执行i++这个语句了 ...

我想问下   如果要是在15s的时候 检测P2.1口有没有高电平输入 有的话脉冲保持 没有检测到脉冲停止 程序怎么改
384432662 发表于 2019-11-19 17:52 | 显示全部楼层
  1. void Timer0() interrupt 1
  2. {
  3.         static u16 i;
  4.         TH0=0XFF;        //给定时器赋初值,定时250Us
  5.         TL0=0X06;
  6.         if(i>=24000)
  7.         {  
  8.                 i++;                        //继续计时
  9.                 if(i>=60000)
  10.                 {
  11.                         i = 60001;        //给i赋值,防止溢出变0
  12.                         if()                //15s后判断P2.1输入
  13.                         {
  14.                            LED=~LED;        //高电平脉冲保持       
  15.                         }else{
  16.                            LED = 0;        //低电平脉冲停止
  17.                              }
  18.                 }else{

  19.                         LED=~LED;        //6-15s,脉冲保持
  20.                      }     
  21.         }else{  
  22.                 i++;
  23.                 if(i<=12000)
  24.                 {
  25.                         led=0;        
  26.                 }        
  27.         
  28.                 if(i>12000&&i<24000)
  29.                 {   
  30.                         led=1;        
  31.                 }
  32.              }
  33.                         
  34. }
梦幻泡影 发表于 2019-11-20 10:32 | 显示全部楼层
384432662 发表于 2019-11-19 16:15
不是大神。。。 我也在学    我那个i>=24000后就不会执行i++这个语句了 ...

这个很好解释,先看看你的代码:
void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFF;        //给定时器赋初值,定时250Us
        TL0=0X06;
        if(i>=24000)
        {  
                LED=~LED;//不会;     
        }
        else
        {  
                i++;
                if(i<=12000)
                {
                        led=0;        
                }        
        
                if(i>12000&&i<24000)
                {   
                        led=1;        
                }
       }               
}
在i < 24000这个区间,它的值是一直自增的,但当 i 的值大于或等于24000以后,由于你的代码在执行完if(i >= 24000)后,并没有对 i 的值做处理,因此程序就永远不会再进入else语句了,楼上那位兄弟写的也是有风险的,也是顾头不顾腚,当 i 的值大于某个参数后没做任何处理,于是它只能继续自增,直到溢出,你现在定义 i 的类型是unsigned int,万一以后被改成long类型,那岂不是要等很久才能看到它溢出?还有另一个问题,你这个 i 是用来计数的,可是为什么要设置为局部变量?由于定时器中断每隔250us会进一次中断,也就意味着每次进入中断都要重新初始化 i 的值,天知道下次进中断后会被系统分配到哪个地方去了。因此有两个建议:
       1、把 i 的值设置为全局变量,并且赋一个初始值,譬如 i = 0;
       2、在if(i >= 24000)里面增加对 i 的处理,譬如将它置0。
            if(i>=24000)
            {
                 i = 0;
                 LED=~LED;//不会;     
            }
 楼主| javachen 发表于 2019-11-20 16:05 | 显示全部楼层
假如时间不够 在15S之后还有延时的话  是不是需要用两个定时器  将脉冲产生的和延时分下来
maowentao0416 发表于 2019-11-20 18:39 来自手机 | 显示全部楼层
学到了
晓枫1997 发表于 2019-11-21 13:37 | 显示全部楼层
1.明白i的取值范围是多少
2.i需要进行复位归0处理,以免i的值溢出
3. u16 i;是2^16吧,我好久没有写C程序了
4.小工程中,可以裸跑程序可以多设置变量,以求稳定
IC芯片叶子 发表于 2019-11-21 14:31 | 显示全部楼层
本帖最后由 dirtwillfly 于 2019-11-22 08:25 编辑

感谢分享
平常心kxy 发表于 2019-11-21 20:04 | 显示全部楼层
记得上学那会儿就没人学单片机了。没想到这么多年过去了,还有人学51

评论

@SevenNights :是有在用,也有人做。但是现在是移动互联网时代,作为新人,为什么去做51单片机呢,以后拿到的薪水和工作环境发展前途都是不一样的。  发表于 2020-1-17 12:02
这位大神你在逗我?没人学单片机?51?不知道你可有兴趣拆开你身边的一些电子设备,电磁炉,遥控器,豆浆机,某些低端烤箱等,你看看它使用的芯片是不是51内核的  发表于 2019-12-26 11:43
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

19

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部