STC89C52单片机的基础项目代码

开发板

本人开发板:普中科技

 

C语言问题

1、使用  _nop_();   需要写头文件        #include "intrins.h"

2、!  取反符号

项目实验

都是基础简单实现对应功能。

LED灯的闪烁

电路连接情况

JP12 与 JP10  导线连接;LE 与 VCC跳线帽连接。

代码

#include <STC89C5xRC.H>

sbit D11 = P0^0; 
sbit D12 = P0^1; 
sbit D13 = P0^2; 
sbit D14 = P0^3; 
sbit D15 = P0^4; 
sbit D16 = P0^5; 
sbit D17 = P0^6; 
sbit D18 = P0^7; 

void Delay300ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 13;
	j = 156;
	k = 83;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

int main()
{
    P0=0X00;
    while(1)
    {
        D11=1;  D12=0;  D13=1;  D14=0;
        D15=1;  D16=0;  D17=1;  D18=0;
        Delay300ms();
        D11=0;  D12=1;  D13=0;  D14=1;
        D15=0;  D16=1;  D17=0;  D18=1;
        Delay300ms();
    }
}

结果

LED灯交替闪烁。

独立按键

电路连接情况

JP5与JP11 导线连接。

代码

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

sbit D11 = P0^0; 
sbit D12 = P0^1; 
sbit D13 = P0^2; 
sbit D14 = P0^3; 
sbit D15 = P0^4; 
sbit D16 = P0^5; 
sbit D17 = P0^6; 
sbit D18 = P0^7; 

sbit K1 = P2^0; 
sbit K2 = P2^1; 
sbit K3 = P2^2; 
sbit K4 = P2^3; 
sbit K5 = P2^4; 
sbit K6 = P2^5; 
sbit K7 = P2^6; 
sbit K8 = P2^7; 

void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 54;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}

void Key_scan()
{
    if(K1==0)
    {
        Delay5ms();
        if(K1==0)
        {
            D11=1;
            while(K1==0);
        }
    }
    else    if(K2==0)
    {
        Delay5ms();
        if(K2==0)
        {
            D12=1;
            while(K2==0);
        }
    }
     else    if(K3==0)
    {
        Delay5ms();
        if(K3==0)
        {
            D13=1;
            while(K3==0);
        }
    }
     else    if(K4==0)
    {
        Delay5ms();
        if(K4==0)
        {
            D14=1;
            while(K4==0);
        }
    }
     else    if(K5==0)
    {
        Delay5ms();
        if(K5==0)
        {
            D15=1;
            while(K5==0);
        }
    }
     else    if(K6==0)
    {
        Delay5ms();
        if(K6==0)
        {
            D16=1;
            while(K6==0);
        }
    }
     else    if(K7==0)
    {
        Delay5ms();
        if(K7==0)
        {
            D17=!D17;
            while(K7==0);
        }
    }
    else    if(K8==0)
    {
        Delay5ms();
        if(K8==0)
        {
            D18=!D18;
            while(K8==0);
        }
    }
}


int main()
{
    P0=0X00;
    while(1)
    {
        Key_scan();
    }
}

结果

按键K1-K6,按下开启D11 - D16;   K7、K8按下D17、D18取反,为亮或灭;

按键点亮数码管

电路连接情况

静态共阳数码管 JP3与P1导线连接;按键为K1;

代码

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

#define     SMG_display     P1

sbit K1 = P2^0; 

unsigned char code SMG_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,       //共阳编码   高电平熄灭
											0xff,0xc1,0x8c,0xc8};		// off 	U	P 	n

                                                
//unsigned char code SMG_code[18] = {                                 //  共阴编码  (高电平点亮)
//    0x3f, 0x06, 0x5b,  0x4f , 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 
//    0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,0xff, 0x00};

unsigned char count;

void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 54;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}

void Key_scan()
{
    if(K1==0)
    {
        Delay5ms();
        if(K1==0)
        {
            D11=1;
            SMG_display=SMG_code[count++];
            if(count>=14)
                count=0;
            while(K1==0);
        }
    }
}


int main()
{
    SMG_display=SMG_code[0];
    while(1)
    {
        Key_scan();
    }
}

结果

多次按下K1,数码管显示依次为  0到9,“全灭,P,U,n ”

动态数码管显示

电路连接情况

数码管为共阴。

J12与PI 导线连接;J21中LE与VCC连接;J16与J15连接;

J6中3(A)接P22;        2(B)接P23;       1(C)接P24;

代码

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

#define     SMG_display     P1

sbit LSA = P2^2;        // 控制位选的IO
sbit LSB = P2^3;
sbit LSC = P2^4;

// 显示内容
//unsigned char code SMG_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,       //
//												0xff,0xc1,0x8c,0xc8};		// off 	U	P 	n
// 显示缓存
unsigned char code SMG_buff[8]={0,1,2,3,4,5,6,7};

unsigned char code SMG_code[18] = {                                 //  共阴编码  (高电平熄灭、低电平点亮)
    0x3f, 0x06, 0x5b,  0x4f , 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 
    0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,0xff, 0x00};


void Display()
{   
    unsigned char i;
    unsigned int j;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
            case 0: LSA=0; LSB=0; LSC=0; break;     // 选择第1个数码管
            case 1: LSA=1; LSB=0; LSC=0; break;     // 选择第2个数码管
            case 2: LSA=0; LSB=1; LSC=0; break;     // 选择第3个数码管
            case 3: LSA=1; LSB=1; LSC=0; break;     // 选择第4个数码管
            case 4: LSA=0; LSB=0; LSC=1; break;     // 选择第5个数码管
            case 5: LSA=1; LSB=0; LSC=1; break;     // 选择第6个数码管
            case 6: LSA=0; LSB=1; LSC=1; break;     // 选择第5个数码管
            case 7: LSA=1; LSB=1; LSC=1; break;     // 选择第6个数码管
        }
        SMG_display = SMG_code[SMG_buff[i]];        // 显示对应数码管的值
        j = 200;                                    // 延长数码管显示的持续时间
        while (j--);
        SMG_display = 0x00;                         // 关闭当前数码管,为下一个数码管显示做准备
    }
}

int main()
{
    while(1)
    {
        Display();
    }
}

结果:

八个数码管依次显示:0 到 7

矩阵按键

电路连接情况

JP4接P0引脚;        

代码

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

#define     SMG_display     P1
#define     KEY_in          P0

sbit LSA = P2^2;        // 控制位选的IO
sbit LSB = P2^3;
sbit LSC = P2^4;

unsigned char SMG_buff[8]={17,17,17,17,17,17,17,17};

unsigned char code SMG_code[18] = {                                 //  共阴编码  (高电平熄灭、低电平点亮)
    0x3f, 0x06, 0x5b,  0x4f , 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,       //0-9
    0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,0xff, 0x00};                 //

unsigned char KeyValue;
    
void Display()
{   
    unsigned char i;
    unsigned int j;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
            case 0: LSA=0; LSB=0; LSC=0; break;     // 选择第1个数码管
            case 1: LSA=1; LSB=0; LSC=0; break;     // 选择第2个数码管
            case 2: LSA=0; LSB=1; LSC=0; break;     // 选择第3个数码管
            case 3: LSA=1; LSB=1; LSC=0; break;     // 选择第4个数码管
            case 4: LSA=0; LSB=0; LSC=1; break;     // 选择第5个数码管
            case 5: LSA=1; LSB=0; LSC=1; break;     // 选择第6个数码管
            case 6: LSA=0; LSB=1; LSC=1; break;     // 选择第5个数码管
            case 7: LSA=1; LSB=1; LSC=1; break;     // 选择第6个数码管
        }
        SMG_display = SMG_code[SMG_buff[i]];        // 显示对应数码管的值
        j = 200;                                    // 延长数码管显示的持续时间
        while (j--);
        SMG_display = 0x00;                         // 关闭当前数码管,为下一个数码管显示做准备
    }
}

void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 54;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}

void Key_scan()                 // 取键值函数
{   
    unsigned char keyState = KEY_in;
    unsigned char X, Y, Z;
    KeyValue = 0xFF;            // 初始化KeyValue为0xFF,即无键按下的状态
    KEY_in = 0x0f;                  // 先对P1置数进行行扫描
    if (KEY_in != 0x0f)             // 判断是否有键按下
    {
        Delay5ms();             // 延时,软件去干扰
        if (KEY_in != 0x0f)         // 确认按键按下
        {
            X = KEY_in;             // 保存行扫描时有键按下时状态
            KEY_in = 0xf0;          // 列扫描
            Y = KEY_in;             // 保存列扫描时有键按下时状态
            Z = X | Y;          // 取出键值
            // 根据取出的键值判断是哪一个键被按下
            switch (Z)
            {
                case 0xee:  KeyValue = 1;   break;
                case 0xde:  KeyValue = 2;   break;
                case 0xbe:  KeyValue = 3;   break;
                case 0x7e:  KeyValue = 4;   break;
                
                case 0xed: KeyValue = 5; break;
                case 0xdd: KeyValue = 6; break;
                case 0xbd: KeyValue = 7; break;
                case 0x7d: KeyValue = 8; break;
                
                case 0xeb: KeyValue = 9; break;
                case 0xdb: KeyValue = 10; break;
                case 0xbb: KeyValue = 11; break;
                case 0x7b: KeyValue = 12; break;
                
                case 0xe7: KeyValue = 13; break;
                case 0xd7: KeyValue = 14; break;
                case 0xb7: KeyValue = 15; break;
                case 0x77: KeyValue = 16; break;
                
            }
            SMG_buff[0]=KeyValue;
        }
    }
}

int main()
{
    while(1)
    {
        Key_scan();
        Display();
    }
}

结果:

矩阵按键依次按下:数码管依次显示为:1-9,a-f, 全亮 

蜂鸣器继电器

电路连接情况

蜂鸣器接P21;继电器接P20;

代码

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

#define     KEY_in          P0

sbit Relay  = P2^0;
sbit Buzzer = P2^1;

unsigned char KeyValue;
 
void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 54;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}

void Key_scan()                 // 取键值函数
{   
    unsigned char keyState = KEY_in;
    unsigned char X, Y, Z;
    KeyValue = 0xFF;            // 初始化KeyValue为0xFF,即无键按下的状态
    KEY_in = 0x0f;                  // 先对P1置数进行行扫描
    if (KEY_in != 0x0f)             // 判断是否有键按下
    {
        Delay5ms();             // 延时,软件去干扰
        if (KEY_in != 0x0f)         // 确认按键按下
        {
            X = KEY_in;             // 保存行扫描时有键按下时状态
            KEY_in = 0xf0;          // 列扫描
            Y = KEY_in;             // 保存列扫描时有键按下时状态
            Z = X | Y;          // 取出键值
            // 根据取出的键值判断是哪一个键被按下
            switch (Z)
            {
                case 0xee:  KeyValue = 1;   break;
                case 0xde:  KeyValue = 2;   break;
                case 0xbe:  KeyValue = 3;   break;
                case 0x7e:  KeyValue = 4;   break;
                
                case 0xed: KeyValue = 5; break;
                case 0xdd: KeyValue = 6; break;
                case 0xbd: KeyValue = 7; break;
                case 0x7d: KeyValue = 8; break;
                
                case 0xeb: KeyValue = 9; break;
                case 0xdb: KeyValue = 10; break;
                case 0xbb: KeyValue = 11; break;
                case 0x7b: KeyValue = 12; break;
                
                case 0xe7: KeyValue = 13; break;
                case 0xd7: KeyValue = 14; break;
                case 0xb7: KeyValue = 15; break;
                case 0x77: KeyValue = 16; break;
                
            }
            if(KeyValue==1)
                Relay=!Relay;
            else if(KeyValue==2)
                Buzzer=!Buzzer;
        }
    }
}

int main()
{
    while(1)
    {
        Key_scan();
    }
}

结果:

按下S1按键,继电器工作;按下S2按键,蜂鸣器工作;

定时器0的使用

电路连接情况

J12与P1导线相连;

代码

#include <STC89C5xRC.H>

sbit D11 = P1^0; 
sbit D13 = P1^2; 
sbit D15 = P1^4; 

unsigned int count_led1;
unsigned int count_led3;
unsigned int count_led5;

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
    ET0=1;
	EA=1;
}

int main()
{
    Timer0Init();
    P1=0X00;
    while(1)
    {
        
    }
}

void timer0() interrupt 1 
{
    count_led1++;
    count_led3++;
    count_led5++;
    if(count_led1==100)
    {
        D11=!D11;
        count_led1=0;
    }
    if(count_led3==200)
    {
        D13=!D13;
        count_led3=0;
    }
    if(count_led5==400)
    {
        D15=!D15;
        count_led5=0;
    }
    
}

结果

定时器每1ms执行一次;

count_led1加到100,LED1电平取反;count_led3加到200,LED3电平取反;.......。。。。

定时器1的使用

电路连接情况

同定时器0相同,连接led灯;

代码

#include <STC89C5xRC.H>

sbit D11 = P1^0; 
sbit D13 = P1^2; 
sbit D15 = P1^4; 
sbit D17 = P1^6; 
sbit D18 = P1^7; 

unsigned int count_led1;
unsigned int count_led3;
unsigned int count_led5;
unsigned int count_led7,count_led8;

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
    ET0=1;
    EA=1;
}

void Timer1Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
    ET1=1;
	EA=1;
}

int main()
{
    Timer0Init();
    Timer1Init();
    P1=0X00;
    while(1)
    {
        
    }
}

void timer0() interrupt 1 
{
    count_led1++;
    count_led3++;
    count_led5++;
    if(count_led1==200)
    {
        D11=!D11;
        count_led1=0;
    }
    if(count_led3==400)
    {
        D13=!D13;
        count_led3=0;
    }
    if(count_led5==800)
    {
        D15=!D15;
        count_led5=0;
    }
}

void timer1() interrupt 3
{
    count_led7++;
    count_led8++;
    if(count_led7==100)
    {
        D17=!D17;
        count_led7=0;
    }
    if(count_led8==200)
    {
        D18=!D18;
        count_led8=0;
    }
}



结果:

LED闪烁。

中断0的使用

电路连接情况

数码管动态显示连接P1;中断功能INT0引脚P23接K1(JP5的8);

代码

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

#define     SMG_display     P1
#define     KEY_in          P0

sbit LSA    = P2^2;        // 控制位选的IO
sbit LSB    = P2^3;
sbit LSC    = P2^4;

unsigned char SMG_buff[8]={17,17,17,17,17,17,17,17};

unsigned char code SMG_code[18] = {                                 //  共阴编码  (高电平熄灭、低电平点亮)
    0x3f, 0x06, 0x5b,  0x4f , 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,       //0-9
    0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,0xff, 0x00};                 //

unsigned char count;  
    
void Display()
{   
    unsigned char i;
    unsigned int j;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
            case 0: LSA=0; LSB=0; LSC=0; break;     // 选择第1个数码管
            case 1: LSA=1; LSB=0; LSC=0; break;     // 选择第2个数码管
            case 2: LSA=0; LSB=1; LSC=0; break;     // 选择第3个数码管
            case 3: LSA=1; LSB=1; LSC=0; break;     // 选择第4个数码管
            case 4: LSA=0; LSB=0; LSC=1; break;     // 选择第5个数码管
            case 5: LSA=1; LSB=0; LSC=1; break;     // 选择第6个数码管
            case 6: LSA=0; LSB=1; LSC=1; break;     // 选择第5个数码管
            case 7: LSA=1; LSB=1; LSC=1; break;     // 选择第6个数码管
        }
        SMG_display = SMG_code[SMG_buff[i]];        // 显示对应数码管的值
        j = 200;                                    // 延长数码管显示的持续时间
        while (j--);
        SMG_display = 0x00;                         // 关闭当前数码管,为下一个数码管显示做准备
    }
}

void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 54;
	j = 198;
	do
	{
		while (--j);
	} while (--i);
}

void INT0_Init(void)
{
	IT0 = 1;            //设置下降沿触发中断
	EX0 = 1;            //使能外部中断0
	EA = 1;             //使能全局中断
}

int main()
{
    INT0_Init();
    while(1)
    {
        SMG_buff[0] = count/100;
        SMG_buff[1] = count%100/10;
        SMG_buff[2] = count%10;
        
        Display();
    }
}

void ExInt0() interrupt 0
{
	if(P32 == 0)
	{
		Delay5ms();
		if(P32 == 0)
		{
			count++;
		}
	}
}

结果

K1按下,数码管显示的数值为检测到中断0成功识别到连续两次,P32引脚电平被拉低的次数。

8*8点阵

电路连接情况

74HC595移位数据:P595 A连接J12:用于控制位选。控制DPa,DPb......电平。

P0引脚接 J19 (绿色灯)或 J20 (红色灯)用于控制段选。显示一行(列)的八个灯亮灭。

代码

#include <STC12C5A60S2.H>

sbit LSA = P2^2;        // 控制位选的IO
sbit LSB = P2^3;
sbit LSC = P2^4;

sbit SER=P3^4;
sbit RCK=P3^5;
sbit SRCLK=P3^6;

unsigned char LED[]={0x00,0x18,0x3C,0x1E,0x0F,0x1E,0x3C,0x18};

void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;
 
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void MatrixLED_Init(void)
{
	RCK=0;
	SRCLK=0;	
}

void MatrixLED_Show(unsigned char Column,unsigned char Date)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SER=Date&(0x80>>i);
		SRCLK=1;
		SRCLK=0;
	}
	RCK=1;
	RCK=0;
	
	P0=~(0x80>>Column);
	Delay1ms();
	
}

void Display()
{   
    unsigned char i;
    unsigned int j;
    for (i = 0; i < 8; i++)
    {
        switch (i)
        {
            case 0: LSA=0; LSB=0; LSC=0; break;     // 选择第1个数码管
            case 1: LSA=1; LSB=0; LSC=0; break;     // 选择第2个数码管
            case 2: LSA=0; LSB=1; LSC=0; break;     // 选择第3个数码管
            case 3: LSA=1; LSB=1; LSC=0; break;     // 选择第4个数码管
            case 4: LSA=0; LSB=0; LSC=1; break;     // 选择第5个数码管
            case 5: LSA=1; LSB=0; LSC=1; break;     // 选择第6个数码管
            case 6: LSA=0; LSB=1; LSC=1; break;     // 选择第5个数码管
            case 7: LSA=1; LSB=1; LSC=1; break;     // 选择第6个数码管
        }
        MatrixLED_Show(i,LED[i]);
        j = 100;                                    // 延长数码管显示的持续时间
        while (j--);
        P0=0xFF;
    }
}
 

void main()
{
	MatrixLED_Init();
	while(1)
	{
		Display();
	}
}


结果

显示内容位心形图案。

结语

以上代码为89C52环境创建的项目代码,但本人开发板单片机型号为STC12C5A60S2,

测试过程中发现延时、定时器设定的理论时间 与 实物显示时间长短反应不一致。但可运行。

故基础部分再次结束。

我将再下一篇用STC12C5A60S2单片机芯片。

继续书写优化代码。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛋蛋的学习记录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值