菜鸟入门2,在ARM开发环境下编写一个stm32简单程序及在proteus上仿真一个简单的51程序
这次的任务主要围绕mdk5进行,首先是安装mdk5及***,然后是在arm开发环境下编译简单stm32程序,并且在proteus上仿真一个简单的51程序。
什么是mdk?
Keil MDK,也称MDK-ARM、Realview MDK、I-MDK、uVision4 等。Keil MDK是由三家国内代理商提供技术支持和相关服务。
MDK-ARM软件为基于Cortex-M、Cortex-R4、ARM7、ARM9处理器设备提供了一个完整的开发环境。 MDK-ARM专为微控制器应用而设计,不仅易学易用,而且功能强大,能够满足大多数苛刻的嵌入式应用。
MDK-ARM有四个可用版本,分别是MDK-Lite、MDK-Basic、MDK-Standard、MDK-Professional。所有版本均提供一个完善的C / C++开发环境,其中MDK-Professional还包含大量的中间库。
(此处参考百度百科,特别感谢)
1.安装mdk5遇到的问题及解决方法
首先,按照链接: mdk5 安装步骤.正常安装
接下来,是我遇到的问题,希望能够给你一些解决方法的参考
1.问题:在把***得到的***输入到这里
时
会出现错误提示框。
解决方法: 用管理员的身份进入mdk5。
2.问题:***下载后,发现期限是2020年(已过期)
解决方法:从论坛中找到期限为2032年的mdk5***.并直接下载安装,操作如上。
操作成功如图
2.在arm开发环境下编译简单stm32程序
准备工作
关于GPIO
1、设置GPIO口的引脚为输入或者输出模式。我们在进行点灯代码的时候,一般设置为推挽输出模式。
2、操作寄存器,往寄存器里置1或者清零操作——这个步骤,固件库已经提供了专门的GPIO_SetBits函数和GPIO_ResetBits函数,我们只要去调用即可实现对IO口的置1和清零。
3、实现多种花样的LED闪动,使得自己熟悉GPIO的编程过程。
此处参考文章.
关于stm32库函数中文使用手册
参见这里.
关于实例程序(闪烁的LED灯),参见 这里.
正式编写
1.首先建立一个文件夹
2打开 Keil uVision5 ,并新建一个工程。
具体操作参见 这里.
3工程建立好后,新建一个文件。
3.在建立的文本文件中输入C中的main函数并保存
4.保存后,将文件添加到工程中
6.编译,成功但有警告
.\LED.axf: Warning: L6304W: Duplicate input file .\system_stm32f10x.o ignored.
去查了资料,发现原因:
system_stm32f2xx_1.c文件出现了两次包含,就是程序中有两个相同的system_stm32f2xx_1.c文件,所以解决方法就是,去掉一个即可;
编译成功无警告
7.接着复制以下代码。
#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);
}
}
编译成功
3.在proteus上仿真一个51程序
该系统为十字路口的交通灯系统,该十字路口有四个红绿灯,在仿真电路图中,横向竖向有两个红路灯和倒计时数码管。当横向绿灯亮60秒时,纵向的红灯亮相同的时间,随后是同时亮15秒黄灯,接着纵向绿灯亮三十秒,横向的红灯同时亮30秒。按下重置按钮,红路灯与数码管的状态回到刚开始。
代码如下
#include <reg51.h>
sbit czred=P0^0;
sbit czyellow=P0^1;
sbit czgreen=P0^2;
sbit nred=P0^3;
sbit nyellow=P0^4;
sbit ngreen=P0^5;
unsigned char redtime,yellowtime,greentime;
unsigned char code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char m;
void display(unsigned char a);
void delay();
void main()
{
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
ET0=1;EA=1;TR0=1;
m=1;
redtime=60;
yellowtime=15;
greentime=30;
while(1)
{
switch(m)
{case 1:
display(redtime);
czred=1;
czyellow=1;
czgreen=0;
nred=0;
nyellow=1;
ngreen=1;
break;
case 2:
display(yellowtime);
czred=1;
czyellow=0;
czgreen=1;
nred=0;
nyellow=1;
ngreen=1;
break;
case 3:
display(greentime);
czred=0;
czyellow=1;
czgreen=1;
nred=1;
nyellow=1;
ngreen=0;
break;
case 4:
display(yellowtime);
czred=0;
czyellow=1;
czgreen=1;
nred=1;
nyellow=0;
ngreen=1;
break;
case 5:
display(yellowtime);
czred=1;
czyellow=0;
czgreen=1;
nred=1;
nyellow=0;
ngreen=1;
break;
}
}
}
void display(unsigned char a) //数码管显示
{
unsigned char gw,sw,i;
gw=a%10;
sw=a/10%10;
for(i=0;i<2;i++)
{
P2=0xfd;
P1=num[gw];
delay();
P2=0xff;
P2=0xfe;
P1=num[sw];
delay();
P2=0xff;
}
}
void delay() //延时
{
unsigned char i;
for(i=0;i<200;i++);
}
void time0()interrupt 1 //中断
{
unsigned char n;
TH0=0x3c;
TL0=0xb0;
n=n+1;
if(n==20)
{
n=0;
if(m==5)
{
if(yellowtime==0)
{
m=1;
redtime=15;
}
else
{
yellowtime=yellowtime-1;
m=5;
}
}
if(m==1)
{
if(redtime==0)
{
m=2;
yellowtime=15;
}
else
{
redtime=redtime-1;
m=1;
}
}
if(m==2)
{
if(yellowtime==0)
{
m=3;
greentime=30;
}
else
{
yellowtime=yellowtime-1;
m=2;
}
}
if(m==3)
{
if(greentime==0)
{
m=4;
yellowtime=15;
}
else
{
greentime=greentime-1;
m=3;
}
}
if(m==4)
{
if(yellowtime==0)
{
m=1;
redtime=60;
}
else
{
yellowtime=yellowtime-1;
m=4;
}
}
}
}
在keil5中生成hex文件
并在proteus中仿真,仿真如图
交通灯闪烁情况
总结
以上就是今天要讲的内容,我学习到了如何在mdk5下编写程序,本文仅仅简单代表本小菜鸟对stm32的简单入门心得,特别鸣谢文中引用到的各路大佬的文章,我希望下次能呈现出更加通俗易懂又不浅薄的小经验。
上一篇: 在普通HTTP上安全地传输密码