打印

新手 51呼吸灯求助

[复制链接]
1313|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HTelepathH|  楼主 | 2017-8-6 23:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
新手看了《手把手教你学51单片机》仿着写的下到板子 小灯常亮
端口没有问题 找了两天不知道问题出在哪里 来求助了
#include<reg52.h>
sbit LED=P2^7;

unsigned char H_RH=0;
unsigned char H_RL=0;
unsigned char L_RH=0;
unsigned char L_RL=0;

void ConfigPWM(unsigned int FR,unsigned char DC);
void AdjustDC(unsigned char dc);

void main()
{
        EA=1;
        ConfigPWM(100,10);
        TH1=0x3C;
        TL1=0xBC;
        ET1=1;
        TR1=1;
        while(1);
}

void ConfigPWM(unsigned int FR,unsigned char DC)
{
        unsigned long per;
        unsigned int high,low;
        per=(12000000/12)/FR;
        high=(per*DC)/100;
        low=per-high;
        high=65536-high+12;
        low=65536-low+12;
        H_RH=(unsigned char)(high>>8);
        H_RL=(unsigned char)high;
        L_RH=(unsigned char)(low>>8);
        L_RL=(unsigned char)low;
        TMOD&=0x0F;
        TMOD|=0x10;
        TMOD&=0xF0;
        TMOD|=0x01;
        TH0=H_RH;
        TL0=H_RL;
        ET0=1;
        TR0=1;
        LED=1;               
}

void AdjustDC(unsigned char dc)
{
        unsigned int high,low;
       
        high=(10000*dc)/100;//10000=((12000000/12)/100)
        low=10000-high;
        high=65536-high+12;
        low=65536-low+12;
        H_RH=(unsigned char)(high>>8);
        H_RL=(unsigned char)high;
        L_RH=(unsigned char)(low>>8);
        L_RL=(unsigned char)low;                          
}

void interruptTimer0() interrupt 1
{
        if(LED==1)
        {
                TH0=L_RH;
                TL0=L_RL;
                LED=0;
         }
         else
         {
                 TH0=H_RH;
                TL0=H_RL;
                LED=1;
         }
}

void interruptTimer1() interrupt 3
{
        unsigned char code DC[13]={5, 18, 30, 41, 51, 60, 68, 75, 81, 86, 90, 93, 95};
        static unsigned char i=0;
        static bit flag=0;
        TH1=0x3C;
        TL1=0xBC;
        AdjustDC(DC[i]);
        if(flag==0)
    {
                i++;
                if(i==12){flag=1;}
        }
        else
        {
                i--;
                if(i==0){flag=0;}
        }
}


相关帖子

沙发
dirtwillfly| | 2017-8-7 08:11 | 只看该作者
没看楼主说的那个,难道里面没教写程序的注释

使用特权

评论回复
板凳
youbruce| | 2017-8-7 12:10 | 只看该作者
对程序有点陌生了,你试下把下面的全局变量
unsigned char H_RH=0;
unsigned char H_RL=0;
unsigned char L_RH=0;
unsigned char L_RL=0;
改成
unsigned char H_RH;
unsigned char H_RL;
unsigned char L_RH;
unsigned char L_RL;

使用特权

评论回复
地板
HTelepathH|  楼主 | 2017-8-7 12:34 | 只看该作者
dirtwillfly 发表于 2017-8-7 08:11
没看楼主说的那个,难道里面没教写程序的注释

看了注释,自己写试着减少了一个设置的函数,(直接把定时器的重载值算出来了)原版我放在下面了,因为不是一个配套的板子,所以端口有点不一样

使用特权

评论回复
5
HTelepathH|  楼主 | 2017-8-7 12:35 | 只看该作者
#include <reg52.h>

sbit PWMOUT = P0^0;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char HighRH = 0;  //高电平重载值的高字节
unsigned char HighRL = 0;  //高电平重载值的低字节
unsigned char LowRH  = 0;  //低电平重载值的高字节
unsigned char LowRL  = 0;  //低电平重载值的低字节
unsigned char T1RH = 0;
unsigned char T1RL = 0;
unsigned long PeriodCnt = 0;

void ConfigTimer1(unsigned int ms);
void ConfigPWM(unsigned int fr, unsigned char dc);

void main()
{
    EA = 1;     //开总中断
    ENLED = 0;  //使能独立LED
    ADDR3 = 1;
    ADDR2 = 1;
    ADDR1 = 1;
    ADDR0 = 0;
   
    ConfigPWM(100, 10);  //配置并启动PWM
    ConfigTimer1(50);    //用T1定时调整占空比
    while (1);
}
void ConfigTimer1(unsigned int ms)
{
    unsigned long tmp;  //临时变量
   
    tmp = 11059200 / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp + 12;           //补偿中断响应延时造成的误差
    T1RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
    T1RL = (unsigned char)tmp;
    TMOD &= 0x0F;   //清零T1的控制位
    TMOD |= 0x10;   //配置T1为模式1
    TH1 = T1RH;     //加载T1重载值
    TL1 = T1RL;
    ET1 = 1;        //使能T1中断
    TR1 = 1;        //启动T1
}
void ConfigPWM(unsigned int fr, unsigned char dc)
{
    unsigned int high, low;
   
    PeriodCnt = (11059200/12) / fr; //计算一个周期所需的计数值
    high = (PeriodCnt*dc) / 100;    //计算高电平所需的计数值
    low  = PeriodCnt - high;        //计算低电平所需的计数值
    high = 65536 - high + 12;       //计算高电平的定时器重载值并补偿中断延时
    low  = 65536 - low  + 12;       //计算低电平的定时器重载值并补偿中断延时
    HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节
    HighRL = (unsigned char)high;
    LowRH  = (unsigned char)(low>>8);  //低电平重载值拆分为高低字节
    LowRL  = (unsigned char)low;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = HighRH;   //加载T0重载值
    TL0 = HighRL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
    PWMOUT = 1;     //输出高电平
}
void AdjustDutyCycle(unsigned char dc)
{
        unsigned int high, low;

        high = (PeriodCnt*dc)/100;
        low = PeriodCnt - high;
        high = 65536 - high + 12;
        low = 65536 - low + 12;
        HighRH = (unsigned char)(high >> 8);
        HighRL = (unsigned char)high;
        LowRH = (unsigned char)(low >> 8);
        LowRL = (unsigned char)low;
}
void InterruptTimer0() interrupt 1
{
    if (PWMOUT == 1)  //当前输出为高电平时,装载低电平值并输出低电平
    {
        TH0 = LowRH;
        TL0 = LowRL;
        PWMOUT = 0;
    }
    else              //当前输出为低电平时,装载高电平值并输出高电平
    {
        TH0 = HighRH;
        TL0 = HighRL;
        PWMOUT = 1;
    }
}

void InterruptTimer1() interrupt 3
{
        unsigned char code table[13] = {
        5, 18, 30, 41, 51, 60, 68, 75, 81, 86, 90, 93, 95
        };
        static bit dir = 0;
        static unsigned char index = 0;

        TH1 = T1RH;
        TL1 = T1RL;

        AdjustDutyCycle(table[index]);
        if(dir == 0)
        {
                index++;
                if(index >= 12)
                {
                        dir = 1;
                }
        }
        else
        {
                index--;
                if(index == 0)
                {
                        dir = 0;
                }
        }
}

使用特权

评论回复
6
HTelepathH|  楼主 | 2017-8-7 12:37 | 只看该作者
我修改成自己的端口,其他复制他的程序,下载到板子没问题,自己写就是找不到问题出在哪里

使用特权

评论回复
7
gujiamao12345| | 2017-8-7 13:05 | 只看该作者
给一个软件的呼吸灯吧
#define _BV(N)  (1 << N)
static void set_led_gradation(uint16_t hwLevel)
{
    static uint16_t s_hwCounter = 0;
   
    if (hwLevel >= s_hwCounter) {
        LED1_ON();
    } else {
        LED1_OFF();
    }
   
    s_hwCounter++;
    s_hwCounter &= TOP;
}

static void breath_led(void)
{
    static uint16_t s_hwCounter = 0;
    static int16_t s_nGray = (TOP >> 1);
   
    s_hwCounter++;
    if (!(s_hwCounter & (_BV(10)-1))) {
        s_nGray++;
        if (s_nGray == TOP) {
            s_nGray = 0;
        }
    }
   
    set_led_gradation(ABS(s_nGray - (TOP >> 1)));
}
ON和OFF就是置高置低

使用特权

评论回复
8
gujiamao12345| | 2017-8-7 13:06 | 只看该作者
youbruce 发表于 2017-8-7 12:10
对程序有点陌生了,你试下把下面的全局变量
unsigned char H_RH=0;
unsigned char H_RL=0;

这是什么意思?

使用特权

评论回复
9
pentiumyto| | 2017-8-7 16:39 | 只看该作者
调整占空比的 void ConfigTimer1(unsigned int ms) 在哪里???
不调整怎么做呼吸效果。

使用特权

评论回复
10
HTelepathH|  楼主 | 2017-8-7 20:17 | 只看该作者
我用了两个定时器两个中断,一个配置pwm,一个调整占空比

使用特权

评论回复
11
山东电子小菜鸟| | 2017-8-15 09:56 | 只看该作者
请使用单步调试

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝