嵌入式stm简单程序仿真

一、一个stm32的LED程序的编译

打开keil5并建立新工程

在这里插入图片描述

选择需要的芯片

在这里插入图片描述

创建一个新文件夹

在这里插入图片描述

输入代码:

#define PERIPH_BASE           ((unsigned int)0x40000000)
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C 
 
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
 
 
#define LED0  MEM_ADDR(BITBAND(GPIOA_ODR_Addr,8))
//#define LED0 *((volatile unsigned long *)(0x422101a0)) //PA8
typedef  struct
{
    
    
   volatile  unsigned  int  CR;
   volatile  unsigned  int  CFGR;
   volatile  unsigned  int  CIR;
   volatile  unsigned  int  APB2RSTR;
   volatile  unsigned  int  APB1RSTR;
   volatile  unsigned  int  AHBENR;
   volatile  unsigned  int  APB2ENR;
   volatile  unsigned  int  APB1ENR;
   volatile  unsigned  int  BDCR;
   volatile  unsigned  int  CSR;
} RCC_TypeDef;
 
#define RCC ((RCC_TypeDef *)0x40021000)
 
typedef  struct
{
    
    
volatile  unsigned  int  CRL;
volatile  unsigned  int  CRH;
volatile  unsigned  int  IDR;
volatile  unsigned  int  ODR;
volatile  unsigned  int  BSRR;
volatile  unsigned  int  BRR;
volatile  unsigned  int  LCKR;
} GPIO_TypeDef;
 
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
 
void  LEDInit( void )
{
    
    
     RCC->APB2ENR|=1<<2;  //GPIOA ????
     GPIOA->CRH&=0XFFFFFFF0;
     GPIOA->CRH|=0X00000003; 
}
 
//????
void  Delay_ms( volatile  unsigned  int  t)
{
    
    
     unsigned  int  i,n;
     for (n=0;n<t;n++)
         for (i=0;i<800;i++);
}
 
int  main( void )
{
    
    
     LEDInit();
     while (1)
     {
    
    
         LED0=0;
         Delay_ms(500);
         LED0=1;
         Delay_ms(500);
     }
}

将代码保存后把文件加入工程

在这里插入图片描述
在这里插入图片描述

打开项目点击目标选项

在这里插入图片描述
注意记得勾选生成HEX文件
在这里插入图片描述

编译执行生成HEX文件

在这里插入图片描述
在这里插入图片描述
到此LED的程序完成。
stm32仿真以后有时间完成。

二、一个51程序设计和仿真

在keil5上重新建一个工程选上C51芯片

在这里插入图片描述

创建文本输入代码

#include<reg51.h>
#include<intrins.h>
char tab[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};	//共阳极字模
unsigned char yi,er,san,si; 	 //yi,er为东西数码管两位,san,si为南北
unsigned char dxtime,nbtime;	//东西倒计时,南北倒计时?
unsigned char deng; 	//led红绿灯
void display1(unsigned char yi,er); 	//函数声明	
void display2(unsigned char san,si);
void led();
void Delay100us();
void Timer0Init(void);
void main()		//主函数
{
    
    
	Timer0Init();      //调用中断函数
	dxtime=30;nbtime=25;		//初始化东西倒计时,南北倒计时
	deng=0X1E;		//初始化交通灯
	while(1)
	{
    
    
	display1(yi,er);  //调用东西数码管显示函数
	display2(san,si);  //调用南北数码管显示函数
	led();           //调用交通灯函数
	}
}	
void Timer0Init(void)		//定时器50ms
{
    
    
	TMOD = 0x01;   		//选择定时方式一
  TH0 =(65536-50000)/256;// 0x15;
	TL0 = (65536-50000)%256;//0x9f;
	TF0 = 0;		
	TR0 = 1;		
	EA=1;		//开中断总允许
	ET0=1;	
}
unsigned char cnt = 0;//定义计数变量
int flag=1;		//标致位
void time0()interrupt 1		//定时中断一
{
    
    
	TH0 =(65536-50000)/256;// 高八位0x15;(写入计数初值)
	TL0 = (65536-50000)%256;//第八位0x9f;
	cnt++;		//计数加一
	if(cnt==20)		//计数到二十,50ms×20=1s,数码管显示时间减一
	{
    
    dxtime--;
		nbtime--;
		cnt=0;		//计数复位
	}
	if(flag)		//flag=1,东西为绿灯(南北先是红灯,再是黄灯)
	{
    
    
	if(nbtime==0)		//红灯时间计完
  {
    
     nbtime=5;deng=0x2e;}		//黄灯开始计时
	if(dxtime==0)		//黄灯和绿灯倒计时到0
		{
    
    
		dxtime=25;nbtime=30;		//东西倒计时赋值为25,南北绿灯赋值为30
		deng=0x33;				//东西红灯亮,南北绿灯亮
		flag=1-flag;			//flag由1变0
		}
	}
	else				//flag=0,东南北为绿灯(东西先是红灯,再是黄灯)
	{
    
    
	if(dxtime==0)		//红灯时间计完
  {
    
     dxtime=5;deng=0x35;}		//黄灯开始计时
  if(nbtime==0)			//黄灯和绿灯倒计时到0
		{
    
    
		dxtime=30;nbtime=25;		//东西倒计时赋值为25,南北绿灯赋值为30
		deng=0x1E;				//南北红灯亮,东西绿灯亮
		flag=1-flag;			//flag由0变1
		}
	}
}
void display1(unsigned char yi,er)	//东西数码管
{
    
    
	yi=dxtime/10;er=dxtime%10;		//十位,个位
	P1=0XFE;P0=tab[yi];		//通过P1选中十位,从P0写入
	Delay100us();					//延时
	P1=0XFD;P0=tab[er];		//通过P1选中个位,从P0写入
	Delay100us();
}
void display2(unsigned char san,si)		//南北数码管同理
{
    
    
	san=nbtime/10;si=nbtime%10;
	P1=0XFB;P2=tab[san];
	Delay100us();
	P1=0XF7;P2=tab[si];
  Delay100us();
}
void led()		//LED显示
{
    
    
	P3=deng;		//通过P3
}
void Delay100us()		//延时函数
{
    
    
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 2;
	j = 15;
	do
	{
    
    
		while (--j);
	} while (--i);
}

保存.c文件并进行编译

在这里插入图片描述

编译后执行生成HEX文件

在这里插入图片描述

建立proteus工程进行仿真

建立新工程

在这里插入图片描述

找出原器件并连线

在这里插入图片描述

将HEX文件代入C51芯片并进行仿真

在这里插入图片描述
进行仿真
在这里插入图片描述

小结:

通过这次作业我对stm32有了更多的了解,对proteus仿真更加熟练。

猜你喜欢

转载自blog.csdn.net/qq_45321687/article/details/108962377