1、51单片机——郭天祥课后习题解答

注:前两课太过简单,不做赘述。

Lesson3

3.1、利用定时计数器 T0 从 P1.0 输出周期为 1s 的方波,让发光二极管以 1HZ 闪烁,设晶振频率为12MHz

//main.c

#include <REGX52.H>
#include "intrins.h"

void Init(void);

unsigned char m_t0;

void main(void)
{
   
    Init();
    
    while(1);
}

void Init(void)
{
   
    TMOD = 0x01;
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void Timer0()interrupt 1
{
   
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    
    m_t0++;
    if(m_t0 >= 10)
    {
   
        m_t0 = 0;
        P1_0 = ~P1_0;
    }
}

3.2、利用定时计数器 T1 产生定时时钟,由 P1 口控制 8 个发光二极管,使 8 个指示灯依次一个一个闪动,
闪动频率为10次/秒(8 个灯依次亮一遍为一个周期) 循环,设晶振频率为12MHz

//main.c

#include <REGX52.H>
#include "intrins.h"

void Init(void);

unsigned char m_t1, m_temp = 0xfe;

void main(void)
{
   
    Init();
    
    while(1)
    {
   
        P1 = m_temp;
        if(m_t1 >= 2)
        {
   
            m_t1 = 0;
            m_temp = _crol_(m_temp, 1);
        }
    }
}

void Init(void)
{
   
    TMOD = 0x10;
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    EA = 1;
    ET1 = 1;
    TR1 = 1;
}

void Timer1()interrupt 3
{
   
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    m_t1++;
    
}

3.3、同时用两个定时器控制蜂鸣器发声,定时器 0 控制频率,定时器 1 控制同个频率持续的时间,间隔 2s 依次输出 1,10,50,100,200,400,800,1k Hz的方波,设晶振频率为 12MHz

//main.c

#include <REGX52.H>
#include "intrins.h"
#include "delay.h"

void Init(void);

sbit beep = P2^3;

unsigned char m_t0, m_t1, m_count;
unsigned int m_freq;

void main(void)
{
   
    Init();
    
    while(1);
}

void Timer0()interrupt 1
{
   
    TR0 = 0;
    TH0 = (65536 - m_freq) / 256;
    TL0 = (65536 - m_freq) % 256;
    
    m_t0++;
    
    if(m_t1 <= 40)
    {
   
        if(m_t0 >= 10)		//10*50000 = 0.5s,周期为1s,频率为1Hz
        {
   
            m_t0 = 0;
            m_freq = 50000;
            beep = ~beep;
        }
    }
    if(m_t1 > 40 && m_t1 <= 80)
    {
   
        m_t0 = 0;
        m_freq = 50000;
        beep = ~beep;
    }
    if(m_t1 > 80 && m_t1 <= 120)
    {
   
        m_t0 = 0;
        m_freq = 10000;
        beep = ~beep;
    }
    if(m_t1 > 120 && m_t1 <= 160)
    {
   
        m_t0 = 0;
        m_freq = 5000;
        beep = ~beep;
    }
    if(m_t1 > 160 && m_t1 <= 200)
    {
   
        m_t0 = 0;
        m_freq = 2500;
        beep = ~beep;
    }
    if(m_t1 > 200 && m_t1 <= 240)
    {
   
        m_t0 = 0;
        m_freq = 1250;
        beep = ~beep;
    }
    if(m_t1 > 240 && m_t1 <= 280)
    {
   
        m_t0 = 0;
        m_freq = 625;
        beep = ~beep;
    }
    if(m_t1 > 280 && m_t1 <= 320)
    {
   
        m_t0 = 0;
        m_freq = 312; 
        beep = ~beep;
    }
    
    TR0 = 1;
}

void Timer1()interrupt 3
{
   
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    m_t1++;
    
    if(m_t1 >= 320)		//40 * 8, 40 为 2s
    {
   
        m_t1 = 0;
        m_freq = 50000;
    }
}

void Init(void)
{
   
    m_freq = 50000;
    beep = 0;
    TMOD = 0x11;
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    EA = 1;
    ET0 = 1;
    TR0 = 1;
    ET1 = 1;
    TR1 = 1;
}

在定时器0 的中断处理函数中关闭定时器0 的原因是因为在定时器0 的中断处理函数中程序运行的时间比定时器0定时的时间 50ms 要长,会影响定时器0 的运行。

3.4、用定时器以间隔 500ms 在 6 位数码管上依次显示0、1、2、3…C、D、E、F,重复。设时钟频率为 12M

//main.c
#include <REGX52.H>
#include "intrins.h"
#include "delay.h"

void Init(void);
void Nixie_Display(unsigned char m_num);

sbit wela = P2^7;
sbit dula = P2^6;

unsigned char Nixie_Array[] = {
   0x3f, 0x06, 0x5b, 0x4f, 
                               0x66, 0x6d, 0x7d, 0x07,
                               0x7f, 0x6f, 0x77, 0x7c,
                               0x39, 0x5e, 0x79, 0x71};

unsigned char m_t1, m_count;

void main(void)
{
   
    Init();
    
    while(1)
    {
   
        if(m_t1 >= 10)
        {
   
            m_t1 = 0;
            if(m_count >= 16)
            {
   
                m_count = 0;
            }
            Nixie_Display(m_count++);
        }
        
    }
}

void Timer1()interrupt 3
{
   
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    m_t1++;
}

void Init(void)
{
   
    TMOD = 0x10;
    TH1 = (65536 - 50000) / 256;
    TL1 = (65536 - 50000) % 256;
    
    EA = 1;
    ET1 = 1;
    TR1 = 1;
}

void Nixie_Display(unsigned char m_num)
{
   
    wela = 1;
    P0 = 0xc0;
    wela = 0;
    
    dula = 1;
    P0 = Nixie_Array[m_num];
    dula = 0;
    
    delay_ms(1);
}

Lesson4

4.1、利用动态扫描方法在六位数码管上显示出稳定的 654321,时钟频率为11.0592M

//main.c

#include <REGX52.H>
#include "intrins.h"
#include "delay.h"

void Init(void);
void Nixie_Display(unsigned char m_num);

sbit wela = P2^7;
sbit dula = P2^6;
unsigned char Num_Array[] = {
   0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf};
unsigned char Nixie_Array[] = {
   0x3f, 0x06, 0x5b, 0x4f, 
                               0x66, 0x6d, 0x7d, 0x07,
                               0x7f, 0x6f, 0x77, 0x7c,
                               0x39, 0x5e, 0x79, 0x71};

unsigned char New_Array[] = {
   0x7d, 0x6d, 0x66, 0x4f, 0x5b, 0x06};

unsigned char m_count;

void main(void)
{
   
    while(1)
    {
   
        Nixie_Display(m_count++);
        if(m_count >= 6)
        {
   
            m_count = 0;
        }
    }
}

void Nixie_Display(unsigned char m_num)
{
   
    wela = 1;
    P0 = Num_Array[m_num];
    wela = 0;
    
    dula = 1;
    P0 = New_Array[m_num];
    dula = 0;
    
    delay_ms(1);
}

4.2、用动态扫描方法和定时器1 在数码管的前三位显示出秒表,精确到 1%秒,即最后一位显示 1%秒,一直循环下去,设时钟频率为 12M

//main.c

#include <REGX52.H>
#include "intrins.h"
#include "delay.h"

void Init
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值