前一段时间我拿到一些样片,然后去打板测试
上电后自动运行IO轮流输出的程序,也就是出厂程序。这证明打的板子没有问题,可以正常使用。
但是问题就来了,我发现我自己的程序跑不起来。比如这么一个最简单的点灯程序。
#include "reg51.h"
#include "intrins.h"
sbit led1 = P1^1;
sbit led2 = P1^2;
sbit led3 = P1^3;
sbit led4 = P1^4;
void delay(int tim) //@11.0592MHz
{
unsigned char i, j;
i = 20;
j = 109;
for(i=0;i<tim;i++)
{
do
{
while (--j);
} while (--i);
}
}
void main()
{
while(1)
{
led2 = 1;
delay(200);
led2 = 0;
delay(200);
}
}
之后就找原因,先是看说3.0 3.1 3.2 必须至少有一个引脚是上拉,那我就上拉,接了一个10k电阻在VCC和P3.0之间。
结果就是,还是不行,那这个算是什么情况呢?
后面我看了一下手册,发现这样一段话,IO口在这一代(STC-Y6)中是必须要手动进行配置的,不能沿用以前C51单片机的开发思维,直接赋值。
那么如何配置输入输出呢,这个在STC-ISP软件上的范例程序这一窗口里就有了,直接抄一下
所以代码修改为这样,大致就是增加了点儿端口模式设置
#include "reg51.h"
#include "intrins.h"
sbit led1 = P1^1;
sbit led2 = P1^2;
sbit led3 = P1^3;
sbit led4 = P1^4;
sfr P0M0 = 0x94;
sfr P0M1 = 0x93;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P2M0 = 0x96;
sfr P2M1 = 0x95;
sfr P3M0 = 0xb2;
sfr P3M1 = 0xb1;
sfr P4M0 = 0xb4;
sfr P4M1 = 0xb3;
sfr P5M0 = 0xca;
sfr P5M1 = 0xc9;
sfr P6M0 = 0xcc;
sfr P6M1 = 0xcb;
sfr P7M0 = 0xe2;
sfr P7M1 = 0xe1;
void delay(int tim) //@11.0592MHz
{
unsigned char i, j;
i = 20;
j = 109;
for(i=0;i<tim;i++)
{
do
{
while (--j);
} while (--i);
}
}
void main()
{
P1M0 = 0x00; //Set P1 OUTPUT
P1M1 = 0x00;
while(1)
{
led1 = 1;
delay(200);
led1 = 0;
delay(200);
}
}
官方的教程中也有类似的,比如这样的配置双向口读写操作。
#include "reg51.h"
#include "intrins.h"
sfr P0M0 = 0x94;
sfr P0M1 = 0x93;
sbit P00 = P0^0;
void main()
{
P0M0 = 0x00; //设置P0.0~P0.7为双向口模式
P0M1 = 0x00;
P00 = 1; //P0.0口输出高电平
P00 = 0; //P0.0口输出低电平
P00 = 1; //读取端口前先使能内部弱上拉电阻
_nop_(); //等待两个时钟
_nop_(); //
CY = P00; //读取端口状态
while (1);
}
但是还是不行,这时候我就去找找别人的代码了,比如这一个 stc8g和ch552 - 立创开源硬件平台
我看了下才知道,嚯,原来是头文件现在也变成新的了,以前时候开发,都是使用#include "reg51.h" 现在这句话变成了#include "STC8.h" , 而我没有用对所以就没法让LED亮起来。
#include "intrins.h"
#include "STC8.h"
void Delay300ms() //@24.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 37;
j = 135;
k = 138;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
P1M0=0x00;
P1M1=0x00;
while(1)
{
P11=0;
Delay300ms();
P11=1;
Delay300ms();
}
}
修改一下自己的代码,主要就改了头文件,因为新的头文件基本把一些定义都定好了,所以很多不需要在main文件里再写
#include "STC8.h"
#include "intrins.h"
sbit led1 = P1^1;
sbit led2 = P1^2;
sbit led3 = P1^3;
sbit led4 = P1^4;
void delay(int tim) //@11.0592MHz
{
unsigned char i, j;
int k;
i = 15;
j = 90;
for(k=0;k<tim;k++)
{
do
{
while (--j);
} while (--i);
}
}
void main()
{
P1M0 = 0x00; //Set P1 OUTPUT
P1M1 = 0x00;
P1 = 0x00;
while(1)
{
delay(10);
P1 = P1<<1;
delay(10);
if(P1==0)
{
P1 = 0x01;
}
if(P1>0x0F)
{
P1 = 0x00;
}
}
}
OK,现在测试成功
如果还是不行那么你需要检查一下,main.c在不在你的项目里面。。
端口的配置
所有的 I/O 口均有 4 种工作模式:准双向口/弱上拉(标准 8051 输出口模式)、推挽输出/强上拉、高 阻输入(电流既不能流入也不能流出)、开漏输出。可使用软件对 I/O 口的工作模式进行容易配置
除 P3.0 和 P3.1 外,其余所有 I/O 口上电后的状态均为高阻输入状态,用户在使 用 I/O 口时必须先设置 I/O 口模式
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;
如何设置,比如说要把所有P1和P3接口设置为双向模式,此时电流比较弱
P1M0 = 0x00; //Set P1 OUTPUT
P1M1 = 0x00;
P3M0 = 0x00; //Set P3 OUTPUT
P3M1 = 0x00;
然后我需要用一下P37作为推挽输出,这时候用这一句就可以(需要头文件包含STC8.h)
P3PU = 0x40;
初次之外还有施密特触发控制寄存器PxNCS,电平速率转换PxSR,电流控制寄存器PxDR,输入使能寄存器PxIE
(x=0,1,2,3,4,5....)