前言:
该文源于回答一个朋友的问题,代码为该朋友上传,略作修改,在此说明问题以及解决问题的思路,以减少新手错误。
电路图:
该位朋友未上传电路图,说明如下:
stc8g1k08a-sop8控制led代码问题
p5.4接开关,开关接高电平。
p5.5接led。
功能上电延迟2秒检测运行,单按键控制led亮灭。按下点亮,再按下熄灭。
目前代码上电后没有任何反应
据此画出上述电路图,其中R1是必须存在的,R1确定了按钮没有按下时,该引脚是0,按钮按下时,引脚为1.
LED1应该存在限流电阻,一般为几千欧姆。
该位朋友上传程序如下:
问题程序
#include "STC8G.H" // 定义引脚
sbit BUTTON = P5^4;
sbit LED = P5^5; void DelayMs(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 120; j++);
}void main() {bit ledState = 0; DelayMs(2000);LED = 0;while (1) {if (BUTTON == 1) { DelayMs(20);if (BUTTON == 1) {ledState = !ledState;LED = ledState;while (BUTTON == 1);}}}
}
其实看到这个程序就知道问题在哪里了,除了传统的MCS51单片机,现在的STC新出的单片机,都需要进行引脚的设置。
引脚设置方法:
//P0M0 = 0x00; // 设置 P0.0~P0.7 为双向口模式
//P0M1 = 0x00;
//P1M0 = 0xff; // 设置 P1.0~P1.7 为推挽输出模式
//P1M1 = 0x00;
//P2M0 = 0x00; // 设置 P2.0~P2.7 为 高阻输入模式
//P2M1 = 0xff;
//P3M0 = 0xff; // 设置 P3.0~P3.7 为开漏模式
//P3M1 = 0xff;
P0P1P2上电状态
上电后M0寄存器为0,M1寄存器为1,因此上电后默认为高阻输入模式,这种高阻输入模式,肯定是无法点亮LED灯的。
端口均需要对M0和M1寄存器进行设置后才可以作为输出管脚使用。
其它3种状态,均可以点灯,区别如下:
双向口模式,需要连接电阻,连接LED,一般连接LED的阴极,LED的阳极接电源,中间串电阻,推荐这种接法,该模式输出电流受到限制,推荐电流控制在1毫安左右。高电平输出电流较小,只有110uA,见下表,因此不能直接点亮LED。
按上述连接,LED阴极接单片机IO,阳极经电阻接电源,设置为开漏模式,可以点灯,该状态能输出0电平点灯,也可以高电平点灯,但不推荐。
推挽输出,随便二极管怎么接都可以,是输出强电流的,该种模式需要对单片机的IO进行限流,如输出0时引脚碰到电源或输出1时引脚碰到地,可能会烧坏单片机的引脚。推挽模式引脚连接LED的阴极时,LED的阳极接电源。单片机引脚接LED的阳极时,LED的阴极接地。LED与电源或地之间需要串联电阻,推荐1-5.1K,尽量取大。
推荐电路图
按键应使用0有效,单片机内部启用上拉电阻,可以节省一个电阻,批量生产时有积极意义。
同理,这里的LED也没有串联电阻,工作原理也是启用单片机内部的上拉电阻,用内部的上拉电阻点亮LED。将该引脚输出0,则LED熄灭。
修改后的程序如下,仅是增加IO M0和M1寄存器的设置。
区别在于增加了P5端口的引脚配置,P5.5配置为推挽输出,P5.4配置为双向IO口
本人的KEIL在编译中提示ledState语法有问题,因此做了调整。初始状态1或0也是可以的。
已发布相关视频,因无法上传视频,发到了BS,可点我链接访问,2个继电器的指示灯,上面的是受控的LED灯,下面的是按钮的指示灯,都是高有效。
需要注意的是,按钮作为输入引脚使用时,因为楼主需要高有效,因此必须将该IO下拉,就是该引脚必须使用一个外接的电阻,接到GND。电阻的取值范围1-10K,通常取4.7K。
该程序经过编译,烧入单片机能够正常运行,视频见上述链接。
正常工作程序
#include <STC8G.H> // 定义引脚sbit BUTTON = P5^4;
sbit LED = P5^5;
bit ledState = 0x20^0; ////P0M0 = 0x00; // 设置 P0.0~P0.7 为双向口模式
//P0M1 = 0x00;
//P1M0 = 0xff; // 设置 P1.0~P1.7 为推挽输出模式
//P1M1 = 0x00;
//P2M0 = 0x00; // 设置 P2.0~P2.7 为 高阻输入模式
//P2M1 = 0xff;
//P3M0 = 0xff; // 设置 P3.0~P3.7 为开漏模式
//P3M1 = 0xff;void DelayMs(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 120; j++);
}void main() {
P3M0 = 0xff; // 设置 P3.0~P3.7 为开漏模式
P3M1 = 0xff;
P5M0 = 0x20; // 设置 P3.0~P3.7 为开漏模式
P5M1 = 0x00;ledState = 1; //DelayMs(2000);LED = 0;while (1) {if (BUTTON == 1) { DelayMs(20);if (BUTTON == 1) {ledState = !ledState;LED = ledState;while (BUTTON == 1);}}}
}