嵌入式学习②——STM32入门初步之LED闪烁

文章目录

  • 前言
  • 一、STM32实现LED闪烁
    • 1.安装mdk5和stm32
    • 2.使用μVision5创建工程
    • 3.STM32编写程序
    • 4.编译运行程序
  • 二、C51实现程序
    • 1.安装Proteus和Keil4
    • 2.使用Keil4创建工程
    • 3.程序实现
    • 4.Proteus仿真
  • 总结


前言

为什么使用STM32而不是8051? 是因为51的频率太低,无法满足计算需求?是51的管脚太少,无法满足众多外设的IO? 是51的功耗太大,电池挺不住?是51的功能太弱,而你要使用SPI、I2C、ADC、DMA? 是51的内存太小而你要存储的东西太多?

当你需要使用STM32某些功能,而51实现不了的时候, 那STM32自然不需要学习,你会直接去寻找STM32某方面的使用方法。
现在我们就来一起从头开始学习STM32的技术


一、STM32实现LED闪烁

示例

1.安装mdk5和stm32

安装mdk5

嵌入式学习②——STM32入门初步之LED闪烁_第1张图片
安装STM32

嵌入式学习②——STM32入门初步之LED闪烁_第2张图片
完成下载

2.使用μVision5创建工程

  • 打开软件

嵌入式学习②——STM32入门初步之LED闪烁_第3张图片

  • 创建工程

嵌入式学习②——STM32入门初步之LED闪烁_第4张图片

  • 选择单片机

嵌入式学习②——STM32入门初步之LED闪烁_第5张图片

  • 安装完成

嵌入式学习②——STM32入门初步之LED闪烁_第6张图片

  • 创建工程如下

嵌入式学习②——STM32入门初步之LED闪烁_第7张图片
头文件如下

嵌入式学习②——STM32入门初步之LED闪烁_第8张图片

3.STM32编写程序

1.main.c

int main()
{
     	
	LED_Init();		      //LED端口及时钟初始化
	while(1)
	{
     
		led_display();    //led显示			
	}	
}

2.led.c

void LED_Init()	  //端口初始化
{
     
	GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量,用来初始化GPIO

	SystemInit();	//时钟初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

	/* 配置GPIO的模式和IO口*/
	GPIO_InitStructure.GPIO_Pin=LED;  //选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 //设置推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率
	GPIO_Init(GPIOC,&GPIO_InitStructure); 	   /* 初始化GPIO */
}

void led_display()
{
     
	GPIO_SetBits(GPIOC,LED);
	delay(6000000);            //延时约为1s
	GPIO_ResetBits(GPIOC,LED);
	delay(6000000);
}

3.led.h

#ifndef _led_H
#define _led_H
#include "stm32f10x.h"
#define LED GPIO_Pin_All	//管道宏定义
void LED_Init(void);
void led_display(void);

#endif 

4.编译运行程序

运行结果如下:

嵌入式学习②——STM32入门初步之LED闪烁_第9张图片


二、C51实现程序

1.安装Proteus和Keil4

软件安装步骤在这里不做赘述

2.使用Keil4创建工程

  • 创建工程

嵌入式学习②——STM32入门初步之LED闪烁_第10张图片

  • 选择单片机

嵌入式学习②——STM32入门初步之LED闪烁_第11张图片

  • 创建程序如下
    嵌入式学习②——STM32入门初步之LED闪烁_第12张图片
    嵌入式学习②——STM32入门初步之LED闪烁_第13张图片

  • 进行Options设置

<需勾选Create HEX File>
嵌入式学习②——STM32入门初步之LED闪烁_第14张图片

3.程序实现

1.main


#include	
#include"lcd.h"

sbit Ky1=P3^0;	  //切换
sbit Ky2=P3^1;	  //数据加1
sbit Ky3=P3^2;	  //进入/退出设置
sbit Ky4=P3^3;	  //数据减1

sbit BEEP=P1^5;	   //接蜂鸣器

sbit LED=P2^0;	   //接LED

unsigned char Dis_SMG[8];//保存时钟的数据
unsigned char sec,min,hour;
unsigned char year,month,day,week;

unsigned char alarm_hour1=8;
unsigned char alarm_min1=0;

unsigned char alarm_hour2=8;
unsigned char alarm_min2=15;

unsigned char alarm_hour3=9;
unsigned char alarm_min3=0;

unsigned char alarm_hour4=9;
unsigned char alarm_min4=15;

unsigned char alarm_hour5=10;
unsigned char alarm_min5=0;

unsigned char alarm_hour6=10;
unsigned char alarm_min6=15;

unsigned char alarm_hour7=11;
unsigned char alarm_min7=0;

unsigned char alarm_hour8=11;
unsigned char alarm_min8=15;

unsigned char alarm_hour9=12;
unsigned char alarm_min9=0;

unsigned char alarm_hour10=13;
unsigned char alarm_min10=0;

unsigned char alarm_hour11=13;
unsigned char alarm_min11=15;

unsigned char alarm_hour12=14;
unsigned char alarm_min12=0;

unsigned char alarm_hour13=14;
unsigned char alarm_min13=15;

unsigned char alarm_hour14=15;
unsigned char alarm_min14=0;

unsigned char alarm_hour15=15;
unsigned char alarm_min15=15;

unsigned char alarm_hour16=16;
unsigned char alarm_min16=0;

unsigned char alarm_hour17=16;
unsigned char alarm_min17=15;

unsigned char alarm_hour18=17;
unsigned char alarm_min18=0;

unsigned char set_state;
unsigned char set_state2;
unsigned char state=0;

void Dig_Dis();
void Dig_Dis2();
void Dig_Dis3();
void Dig_Dis4();
void Dig_Dis5();
void Delay(unsigned int i);
void Delay1ms(unsigned int c);
void Keycan();
void Keycan2();
void Keycan3();
void Keycan4();
void Keycan5();

void TimerConfiguration();
void Int0Configuration();

void main()
{
     	
	LED=1;
	LcdInit();
	year=20;
	month=04;
	day=25;
	week=2;
	sec=50;
	min=59;
	hour=7;
	TimerConfiguration();
	Int0Configuration();
	LCDWrite_String(4, 1, 8, "Welcome!");
	while(1)
	{
     
		Keycan();
		LCDWrite_String(0, 0, 3, "   ");
			
		Dig_Dis();
	}	
}

void Delay1ms(unsigned int c)   //误差 0us
{
     
    unsigned char a,b;
	for (; c>0; c--)
	{
     
		for(b=199;b>0;b--)
		{
     
			for(a=1;a>0;a--);
		}
        
	}
    
}

void TimerConfiguration()
{
     
    TMOD = 0x01; //选择工作方式1
    TH0 = 0x3C;	 //设置初始值
    TL0 = 0x0B0; 
	TH1=(65536-2000)/256;		
	TL1=(65536-2000)%256;
    EA = 1;			 //打开总中断
    ET0 = 1;		 //打开定时器0中断
    TR0 = 1;		 //启动定时器0
}

void Int0Configuration()
{
     
	//设置INT0
	IT0=1;//跳变沿出发方式(下降沿)
	EX0=1;//打开INT0的中断允许。
	EA=1;//打开总中断	
}

void Keycan()
{
     
		unsigned int i;
		if(state==1)
		{
     
			if(Ky1==0)		//检测按键Ky1是否按下
			{
     
				Delay1ms(10);	//消除抖动
				if(Ky1==0)
				{
     
					set_state++;
					if(set_state>=7)
						set_state=0;					
				}

				while((Ky1==0))	 //检测按键是否松开
				{
     
					Delay1ms(1);
					i++;
				}
				i=0;
			}
			if(Ky2==0)		//检测按键Ky2是否按下
			{
     
				Delay1ms(10);	//消除抖动
				if(Ky2==0)
				{
     
					if(set_state==0)
					{
     
						sec++;
						if(sec>=60)
							sec=1;
					}
					else if(set_state==1)
					{
     
						min++;
						if(min>=60)
							min=1;	
					}
					else if(set_state==2)
					{
     
						hour++;
						if(hour>=24)
							hour=0;
					}	
					else if(set_state==3)
					{
     
						day++;
						if(day>=32)
							day=1;
					}
					else if(set_state==4)
					{
     
						week++;
						if(week==8)
							week=1;
					}	
					else if(set_state==5)
					{
     
						month++;
						if(month>=13)
							month=1;
					}	
					else
					{
     
						year++;
						if(year>99)
							year=0;
					}				
				}

				while((Ky2==0))	 //检测按键是否松开
				{
     
					Delay1ms(1);
					i++;
				}
				i=0;
			}

			if(Ky4==0)		//检测按键Ky4是否按下
			{
     
				Delay1ms(10);	//消除抖动
				if(Ky4==0)
				{
     
					if(set_state==0)
					{
     
						sec--;
						if(sec<1)
							sec=59;
					}
					else if(set_state==1)
					{
     
						min--;
						if(min<1)
							min=59;	
					}
					else if(set_state==2)
					{
     
						hour--;
						if(hour==0)
							hour=23;
					}
					else if(set_state==3)
					{
     
						day--;
						if(day==0)
							day=31;
					}

					else if(set_state==4)
					{
     
						week--;
						if(week==0)
							week=7;
					}
					
					else if(set_state==5)
					{
     
						month--;
						if(month==0)
							month=12;
					}
					else
					{
     
						year--;
						if(year==0)
							year=99;
					}				
				}

				while((Ky4==0))	 //检测按键是否松开
				{
     
					Delay1ms(1);
					i++;
				}
				i=0;
			}
		}
}

void Dig_Dis()
{
     
		LcdWriteCom(0x80+3);
		LcdWriteData('2');
		LcdWriteData('0');
		LcdWriteData('0'+year/10);
		LcdWriteData('0'+year%10);
		LcdWriteData('-');
		LcdWriteData('0'+month/10);
		LcdWriteData('0'+month%10);
		LcdWriteData('-');
		LcdWriteData('0'+day/10);
		LcdWriteData('0'+day%10);
		//--显示时钟--//
		LcdWriteCom(0xC0+4);
		LcdWriteData('0'+hour/10);
		LcdWriteData('0'+hour%10);
		LcdWriteData(':');
		LcdWriteData('0'+min/10);
		LcdWriteData('0'+min%10);
		LcdWriteData(':');
		LcdWriteData('0'+sec/10);
		LcdWriteData('0'+sec%10);

		LcdWriteCom(0xC0+14);
		LcdWriteData('0'+week/10);
		LcdWriteData('0'+week%10);
}

void time0() interrupt 1
{
     
	static unsigned int j;
	TH0=0Xfc;
	TL0=0X18;  //1ms
	j++;
	if(j==1000) //1s
	{
     
		j=0;
		sec++;
		if(sec==60)			  //秒满60清零
		{
     
			sec=0;
			min++;
			if(min==60)		   //分满60清零
			{
     
				min=0;
				hour++;
				if(hour==24)
					{
     
						hour=0;
						day++;
						week++;
						if(week>7)
						{
     
							week=0;
						}
						if(((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
						   &&(day==32)
						  )
						  {
     
						  	day=1;
							month++;
							if(month==13)
							{
     
								year++;
								month=0;
							}
						  }	
						  if(((month==4)||(month==6)||(month==9)||(month==11))
						   &&(day==31)
						  )
						  {
     
						  	day=1;
							month++;
						  }	
						if((((year%4)==0)&&(month==2))
						   &&(day==30)
						  )
						  {
     
						  	day=1;
							month++;
						  }	
						  if((((year%4)!=0)&&(month==2))
						   &&(day==29)
						  )
						  {
     
						  	day=1;
							month++;
						  }	
					}
				}				
			}					
		
		if((((hour==alarm_hour1)&&(min==alarm_min1)&&(sec<=10))||		
			((hour==alarm_hour2)&&(min==alarm_min2)&&(sec<=10))||	    
			((hour==alarm_hour3)&&(min==alarm_min3)&&(sec<=10))||	    
			((hour==alarm_hour4)&&(min==alarm_min4)&&(sec<=10))||
			((hour==alarm_hour5)&&(min==alarm_min5)&&(sec<=10))||		
			((hour==alarm_hour6)&&(min==alarm_min6)&&(sec<=10))||	    
			((hour==alarm_hour7)&&(min==alarm_min7)&&(sec<=10))||	    
			((hour==alarm_hour8)&&(min==alarm_min8)&&(sec<=10))||
			((hour==alarm_hour9)&&(min==alarm_min9)&&(sec<=10))||		
			((hour==alarm_hour10)&&(min==alarm_min10)&&(sec<=10))||	    
			((hour==alarm_hour11)&&(min==alarm_min11)&&(sec<=10))||	    
			((hour==alarm_hour12)&&(min==alarm_min12)&&(sec<=10))||
			((hour==alarm_hour13)&&(min==alarm_min13)&&(sec<=10))||		
			((hour==alarm_hour14)&&(min==alarm_min14)&&(sec<=10))||	    
			((hour==alarm_hour15)&&(min==alarm_min15)&&(sec<=10))||	    
			((hour==alarm_hour16)&&(min==alarm_min16)&&(sec<=10))||
			((hour==alarm_hour17)&&(min==alarm_min17)&&(sec<=10))||		
			((hour==alarm_hour18)&&(min==alarm_min18)&&(sec<=10))
		  )&&(week<=5))		
		{
     
			ET1=1;TR1=1;	  //开启铃声
			LED=0;
		}
		else
		{
     
			ET1=0;TR1=0;	 //关闭铃声
			LED=1;
		}
	}
}

void Beeper() interrupt 3
{
     
	TH1=(65536-2000)/256;		
	TL1=(65536-2000)%256;
	BEEP=!BEEP;
}

void Int0() interrupt 0		 
{
     
	Delay1ms(10);
	if(Ky3==0)
	{
     
		state++;
		state=state%2;
		if(state>0)
		{
     
			TR0=0;
		}
		else
		TR0=1;
		set_state=0;
		set_state2=0;
	}
}

2.lch.c

#include"lcd.h"

void LCDWrite_String(uchar x, uchar y, uchar z, uchar *s)	//x 0~15 , y 0,1,2,3 
{
     
	LCD_set_xy(x,y,z);
	while(*s)
	{
     
		LcdWriteData(*s);
		s++;
	}
}


void LCD_set_xy(uchar x,uchar y,uchar z)
{
     
	uchar i;
	if(y==0)
	{
     
		LcdWriteCom(0x80+x);
		for(i=0;i<z;i++)
		{
     
			LcdWriteData(' ');
		}
		LcdWriteCom(0x80+x);
	}
	if(y==1)
	{
     
		LcdWriteCom(0xc0+x);
		for(i=0;i<z;i++)
		{
     
			LcdWriteData(' ');
		}
		LcdWriteCom(0xc0+x);
	}
	if(y==2)
	{
     
		LcdWriteCom(0x94+x);
		for(i=0;i<z;i++)
		{
     
			LcdWriteData(' ');
		}
		LcdWriteCom(0x94+x);
	}
	if(y==3)
	{
     
		LcdWriteCom(0xd4+x);
		for(i=0;i<z;i++)
		{
     
			LcdWriteData(' ');
		}
		LcdWriteCom(0xd4+x);
	}
}


void Lcd1602_Delay1ms(uint16 i)
{
     
	while(i--);
}
void LcdWriteCom(uint8 c)	 //写命令
{
     
	Lcd1602_Delay1ms(1000);
	rs=0;
	rw=0;
	e=0;
	P0=c;
	e=1;
	Lcd1602_Delay1ms(10);
	e=0;
	/*
	P0=c<<4;
	e=1;
	e=0;*/       //四位的LCD要加上
}
void LcdWriteData(uint8 dat)	  //写数据
{
     
	Lcd1602_Delay1ms(1000);
	rs=1;
	rw=0;
	e=0;
	P0=dat;
	e=1;
	Lcd1602_Delay1ms(10);
	e=0;
	/*
	P0=dat<<4;
	e=1;
	e=0;*/	   //四位的LCD要加上
	rs=0;
}
void LcdInit()
{
     
	Lcd1602_Delay1ms(1000);
/*	wrc(0x32);	 
	wrc(0x28);
	wrc(0x28);	*/	//四位的LCD要加上
	LcdWriteCom(0x38);
	LcdWriteCom(0x38);
	LcdWriteCom(0x38);
	LcdWriteCom(0x06);
	LcdWriteCom(0x0c);
	LcdWriteCom(0x01);
}

编译时出现如下警告

linking...
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  ?C_START
    MODULE:  STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  ?C_START
    MODULE:  STARTUP.obj (?C_STARTUP)
    ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=15
"LED" - 0 Error(s), 2 Warning(s).

4.Proteus仿真

仿真图如下:

嵌入式学习②——STM32入门初步之LED闪烁_第15张图片


以下是GIF演示 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201008174047461.gif#pic_center)

总结

STM32在使用上比51方便许多

可以看出,若是不配置STM32的PLL,那么相对于51单片机,STM32闪烁LED灯只不过多了一个步骤----配置GPIO口为输出而已。

你可能感兴趣的:(阿为,stm32,嵌入式)