C51单片机的问题:认能告诉我,为啥led1灯不灭,或者程序哪有问题,芯片频率是12MHZ的.

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C51单片机的问题:认能告诉我,为啥led1灯不灭,或者程序哪有问题,芯片频率是12MHZ的.相关的知识,希望对你有一定的参考价值。

#include <reg52.h>
#define uint unsigned int
sbit p1=P1^0;
void Delay(uint n);
void main()
p1=0;//假设P1^0口连接led1灯,则led1灯亮;
Delay(1000);
p1=1;//led1灯灭。但是这步烧写到板子上时led1灯一直是亮的,程序是对的,为什么不灭。

void Delay(uint n)
uint x,y;
for(x=0;x<n;x++)
for(y=0;y<n;y++);

参考技术A 我感觉是你得延时太长了,(在硬件没有问题的前提下)当第二个for(y=0;y<110;y++)时,若n=1000,则延时函数执行一次约1000ms的时间,如果向你那样写,延时理论上在10s左右,还有你得程序没有while(1);结尾,是否是因为程序跑飞引起的。 参考技术B 检查电路,确定灯是接到P1^0上。
直接赋值为0,看看是否灭,如果灭就是程序有问题,延时太短或太长都可能
参考技术C 是你的小失误,你把LED点亮 延时1000, LED灭你没有延时 所有你看不到LED灭
p1 = 0;
Delay(1000);
p1 = 1;
Delay(1000);
这样就可以实现你的功能了。努力学习吧!追问

你说的倒不 错,只是本意是想让它亮一下就还掉,单片机上(烧上板子后)什么老是不停的执行你所写的代码?我没有用while(1)将它们当主体呀?按我软件的思想应该是执行第二个Delay(1000)时,主函数应该eixt了呀?还有书上不说是12MHZ的执行一条指令是1us,那么我所写的Delay()应该是1000000us=1s,发现执行时间隔少说有10秒?谢谢你的解答.

追答

还有书上不说是12MHZ的执行一条指令是1us,那么我所写的Delay()应该是1000000us=1s,发现执行时间隔少说有10秒?谢谢你的解答.
没有说12MHZ执行一条指令1us 是一个机器周期
你那个你那是软件延时,软件延时就是单片机执行你那for循环耗费的时间,根本计算不了不准确只有通过keil仿真查看,如果要精准必须定时器。

1000000us=1s //unsigned int 是多少字节,0 - 65536

想执行一次就

p1 = 0;
Delay(1000);
p1 = 1;
Delay(1000);
while(1);

本回答被提问者和网友采纳
参考技术D 因为你灯灭了以后直接就跳到主函数的第一步又把灯给点着了,因为单片机执行指令的时间太短所以你根本看不出灯灭了。追问

我的程序应该是只执行一次而以呀?什么会又跳回,难道是单片机的哪个地方我没理解到?

追答

我想起来了,这好像是和编译器有关的,你用的是keil吧,keil在执行程序编译时当程序结束后就会返回入口函数,如果你想程序执行一次,你可以在p1=1;语句之后加入while(1);语句让程序一直留在这里,这样你的灯就是亮一次,然后一直处于关闭状态。

第5个回答  2012-12-05 如果可以,给个截图你的硬件是怎么连的,尤其是led那边,有点你必须清楚,直接用单片机驱动led而没设定单片机输入/输出的状态(普通i/o,推挽之类),可能就会出问题

AVR单片机教程——串口接收

上一讲中,我们实现了单片机开发板向电脑传输数据。在这一讲中,我们将通过电脑向单片机发送指令,让单片机根据指令控制LED。这一次,两端的TX与RX需要交叉连接,单片机TX连接串口工具RX也是需要的,因为程序会根据指令反馈信息。

为了简单起见,我们的程序只需要控制4个板载LED。指令包含两个字节:第一个字节为rygb中的一个,分别表示红、黄、绿、蓝灯;第二个字节为01,表示灯不亮或亮。

然而,a2这样的指令是没有意义的,却是可能出现的。即使用户已经熟悉了这8条指令,也可能会不小心打错。我们应当记住,用户是世界上最愚蠢的人,我们要把他们可能犯的错误都想到,然后在程序中合理地处理。比如,对于不合法的指令,程序忽略指令,并返回What?给电脑;对于合法的,则执行并返回Done!

#include <ee1/led.h>
#include <ee1/uart.h>

int main(void)
{
    led_init();
    uart_init(UART_DUPLEX);
    char temp[3];
    while (1)
    {
        uart_scan_string_n(temp, 2);
        bool good = true;
        led_t led;
        switch (temp[0])
        {
            case 'r': led = LED_RED   ; break;
            case 'y': led = LED_YELLOW; break;
            case 'g': led = LED_GREEN ; break;
            case 'b': led = LED_BLUE  ; break;
            default:  good = false;     break;
        }
        bool on;
        switch (temp[1])
        {
            case '0': on = false;   break;
            case '1': on = true ;   break;
            default:  good = false; break;
        }
        if (good)
        {
            led_set(led, on);
            uart_print_string("Done!
");
        }
        else
            uart_print_string("What?
");
    }
}

while循环的周期是多少呢?没有delay语句,是不是循环在很快地扫描呢?不是,uart_scan_string_n函数一直等待直到串口接收到了规定量的数据。

实际上,这一系列串口接收的函数的功能非常受限——程序必须等待数据到来,不能错过它,这与scanf等函数从缓冲区读取数据不同。当然,单片机系统中的串口输入(以及输出)也可以实现缓冲区,并且是一种实用并常用的做法,但这要涉及到中断,是以后的内容。你可以试着利用数据手册以及其他资源实现一个带缓冲的串口输入输出。在avr-gcc中,使用中断要先#include <avr/interrupt.h>,串口接收中断写为ISR(USART0_RX_vect) { }

?

作业:

  1. 如果通过串口发送指令r11g1,只有红色LED会亮,因为程序对指令的解读是r11g1,而我只是不小心(故意)多打了一个1,本意是想让红色和绿色LED都亮。改进程序解决这个问题。

  2. 基于uart_scan_char,实现my_scan_int函数,从串口上读取十进制整数(注意正负号与溢出等;你可以了解一下atoi)。

以上是关于C51单片机的问题:认能告诉我,为啥led1灯不灭,或者程序哪有问题,芯片频率是12MHZ的.的主要内容,如果未能解决你的问题,请参考以下文章

谁能告诉我下单片机80c51的各引脚的作用?

为啥一打开串口调试助手,单片机的程序就停了?

毕业回馈-89C51之GPIO使用(流水灯)

怎么在51单片机中读取文件 如何在Keil C51使用fopen函数 也就是如何在C51中编写 能打开文件程序

STC89C51单片机相比于其他单片机具有那些优点?

STM32与80C51