完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一、硬件部分
1.IO口选择 使用GPIOB、GPIOC、GPIOD三个端口控制LED灯,在stm32手册中可以查找对应IO口来作为实验输出口。 2其余硬件 除stm32芯片外,还需准备红黄绿三色LED灯若干,导线(杜邦线)若干,面包板一块。 杜邦线: 杜邦线主要用于电路实验,在进行电路实验的时候可以和插针进行连接,而且他具有非常好的牢靠性,也能够省略焊接的过程,快速的进入电路实验,在电子产品的应用中非常广泛。 杜邦线在网上搜索有很多,可根据自己实验要求购买不同杜邦线。 此外,接线时尽量避免用杜邦线串联,可能接触不良或过程中松动。可用一根杜邦线,长度不够时可通过面包板卡槽连接两根杜邦线。 面包板: 面包板是由于板子上有很多小插孔,专为电子电路的无焊接实验设计制造的。由于各种电子元器件可根据需要随意插入或拔出,免去了焊接,节省了电路的组装时间,而且元件可以重复使用,所以非常适合电子电路的组装、调试和训练。 面包板使用教程可在网上搜索,也可在网上购买后向商家询问。 3.连线 连线方面,LED灯短脚连接IO口,长脚连接电源口(注:不要连接5v端口,5v端口没有电阻保护,容易烧坏LED灯) 在连线过程中可以借助面包板辅助连线。 二、软件部分 创立工程文件,编写代码后编译生成hex文件。 2.1寄存器配置 通过配置寄存器的值改变IO的值进行变化。 led.h #ifndef __LED_H #define __LED_H #include "sys.h" //LED端口定义 #define LED0 BIT_ADDR(GPIOB_ODR_Addr,6) // PB6输出 #define LED1 BIT_ADDR(GPIOC_ODR_Addr,6) // PC6输出 #define LED2 BIT_ADDR(GPIOD_ODR_Addr,2) // PD2输出 void LED_Init(void); //初始化 #endif led.c #include "sys.h" #include "led.h" //初始化PB6、PC6和PD2为输出口,并使能这3个口的时钟 //LEDIO初始化 void LED_Init(void) { RCC->APB2ENR|=1<<3; //使能PORTB时钟 RCC->APB2ENR|=1<<4; //使能PORTC时钟 RCC->APB2ENR|=1<<5; //使能PORTD时钟 GPIOB->CRL&=0XF0FFFFFF; //PB6清零 GPIOB->CRL|=0X03000000; //PB6推挽输出 GPIOB->ODR|=1<<6; //PB6输出高 GPIOC->CRL&=0XF0FFFFFF; //PC6清零 GPIOC->CRL|=0X03000000; //PC6推挽输出 GPIOC->ODR|=1<<6; //PC6输出高 GPIOD->CRL&=0XFFFFF0FF; //PD2清零 GPIOD->CRL|=0X00000300;//PD2推挽输出 GPIOD->ODR|=1<<2; //PD2输出高 } 2.2主函数编写 通过编写一个简单的延时函数delay,控制LED轮流点亮。在主函数中,用一个while死循环保证三个LED灯可以轮回亮。用BIT_ADDR(GPIOX_ODR_Addr,n)函数来控制输出口的电平,从而达到控制LED的亮灭的功能。 test.c #include "sys.h" #include "led.h" void delay(unsigned int i) //简单延时函数 { unsigned char j; unsigned char k; for(;i>0;i--) for(j=500; j>0; j--) for(k =200; k>0; k--); } int main(void) { LED_Init(); //初始化与LED连接的硬件接口 while(1) { LED0=0; //灯亮 LED1=1; //灯灭 LED2=1; delay(20); //延时 LED0=1; LED1=0; LED2=1; delay(20); LED0=1; LED1=1; LED2=0; delay(20); } } 2.3程序烧录 程序烧录是把想要的数据通过刻录机等工具刻制到光盘、烧录卡(GBA)等介质中。这里指的是将程序烧录进stm32芯片中是芯片运转功能。 Flymcu是与mcuisp功能类似的 串口下载(烧录)工具软件。 下面提供mcuisp软件 mcuisp软件下载链接,百度网盘链接: https://pan.baidu.com/share/init?surl=WyvtnCJad_BqXbwTzhcofw 提取码:h2xc 在烧录之前,我们要先选择串口,我这里的串口为COM3. 之后我们选择的DTR的低电平复位,RTS高电平进BootLoader,这个选择项选中,flymcu就会通过DTR和RTS信号来控制板载的一键下载功能电路,以实现一键下载功能。如果不选择,则无法实现一键下载功能。 串口波特率则可以通过bps那里设置,对于STM32F103,可以设置为最高:460800,而如果是 F4,则建议最高设置为:76800 即可。 配置完成后点击开始编程,程序就会自动烧录进板子中,成功烧录后,就会显示下图右方的文字。 2.4成功展示 三、用汇编实现流水灯 代码: RCC_APB2ENR EQU 0x40021018 GPIOA_CRH EQU 0x40010804 GPIOA_ODR EQU 0x4001080C GPIOB_CRL EQU 0x40010C00 ;寄存器映射 GPIOB_ODR EQU 0x40010C0C GPIOC_CRH EQU 0x40011004 GPIOC_ODR EQU 0x4001100C Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3 ;NOINIT: = NO Init,不初始化。READWRITE : 可读,可写。ALIGN =3 : 2^3 对齐,即8字节对齐。 Stack_Mem SPACE Stack_Size __initial_sp AREA RESET, DATA, READONLY __Vectors DCD __initial_sp DCD Reset_Handler AREA |.text|, CODE, READONLY THUMB REQUIRE8 PRESERVE8 ENTRY Reset_Handler MainLoop BL LED2_Init BL LED2_ON BL Delay ;LED2灯闪烁 BL LED2_OFF BL Delay BL LED1_Init BL LED1_ON BL Delay ;LED1灯闪烁 BL LED1_OFF BL Delay BL LED3_Init BL LED3_ON BL Delay ;LED3灯闪烁 BL LED3_OFF BL Delay B MainLoop LED1_Init PUSH {R0,R1, LR} ;R0,R1,LR中的值放入堆栈 LDR R0,=RCC_APB2ENR ;LDR是把地址装载到寄存器中(比如R0)。 ORR R0,R0,#0x08 ;开启端口GPIOB的时钟,ORR 按位或操作,01000将R0的第二位置1,其他位不变 LDR R1,=RCC_APB2ENR STR R0,[R1] ;STR是把值存储到寄存器所指的地址中,将r0里存储的值给rcc寄存器 ;上面一部分汇编代码是控制时钟的 LDR R0,=GPIOB_CRL ORR R0,R0,#0X00000020 ;GPIOB_Pin_1配置为通用推挽输出;开启的是pb1,所以是2,为0010,是推挽输出模式,最大速度为2mhz LDR R1,=GPIOB_CRL STR R0,[R1] LDR R0,=GPIOB_ODR BIC R0,R0,#0X00000002 ;BIC 先把立即数取反,再按位与 LDR R1,=GPIOB_ODR ;GPIOB_Pin_1输出为0;由r1控制ord寄存器 STR R0,[R1] ;将ord寄存器的值变为r0的值 POP {R0,R1,PC} ;将栈中之前存的R0,R1,LR的值返还给R0,R1,PC LED1_OFF PUSH {R0,R1, LR} LDR R0,=GPIOB_ODR BIC R0,R0,#0X00000002 ;因为是PB1所以对应二进制0010;GPIOB_Pin_1输出为0,LED1熄灭 LDR R1,=GPIOB_ODR STR R0,[R1] POP {R0,R1,PC} LED1_ON PUSH {R0,R1, LR} LDR R0,=GPIOB_ODR ORR R0,R0,#0X00000002 ;GPIOB_Pin_1输出为1,LED1亮 LDR R1,=GPIOB_ODR STR R0,[R1] POP {R0,R1,PC} LED2_Init PUSH {R0,R1, LR};R0,R1,LR中的值放入堆栈 LDR R0,=RCC_APB2ENR ORR R0,R0,#0x04 ;打开GPIOA的时钟 LDR R1,=RCC_APB2ENR STR R0,[R1] LDR R0,=GPIOA_CRH ORR R0,R0,#0X00020000 ;GPIOA_Pin_12配置为通用推挽输出 LDR R1,=GPIOA_CRH STR R0,[R1] LDR R0,=GPIOA_ODR BIC R0,R0,#0X00001000 LDR R1,=GPIOA_ODR ;GPIOA_Pin_12输出为0 STR R0,[R1] POP {R0,R1,PC} LED2_OFF PUSH {R0,R1, LR} LDR R0,=GPIOA_ODR BIC R0,R0,#0X00001000 ;GPIOA_Pin_12输出为0,LED2熄灭 LDR R1,=GPIOA_ODR STR R0,[R1] POP {R0,R1,PC} LED2_ON PUSH {R0,R1, LR} LDR R0,=GPIOA_ODR ORR R0,R0,#0X00001000 ;GPIOA_Pin_12输出为1,LED2亮 LDR R1,=GPIOA_ODR STR R0,[R1] POP {R0,R1,PC} LED3_Init PUSH {R0,R1, LR} LDR R0,=RCC_APB2ENR ORR R0,R0,#0x10 ;打开GPIOC的时钟 LDR R1,=RCC_APB2ENR STR R0,[R1] LDR R0,=GPIOC_CRH ORR R0,R0,#0X02000000 ;GPIOC_Pin_14配置为通用推挽输出 LDR R1,=GPIOC_CRH STR R0,[R1] LDR R0,=GPIOC_ODR BIC R0,R0,#0X00004000 ;GPIOC_Pin_14输出为0 LDR R1,=GPIOC_ODR STR R0,[R1] POP {R0,R1,PC} LED3_OFF PUSH {R0,R1, LR} LDR R0,=GPIOC_ODR BIC R0,R0,#0X00004000 ;GPIOC_Pin_14输出为0,LED3熄灭 LDR R1,=GPIOC_ODR STR R0,[R1] POP {R0,R1,PC} LED3_ON PUSH {R0,R1, LR} LDR R0,=GPIOC_ODR ORR R0,R0,#0X00004000 ;GPIOC_Pin_14输出为1,LED3亮 LDR R1,=GPIOC_ODR STR R0,[R1] POP {R0,R1,PC} Delay PUSH {R0,R1, LR} MOVS R0,#0 MOVS R1,#0 MOVS R2,#0 DelayLoop0 ADDS R0,R0,#1 CMP R0,#300 BCC DelayLoop0 MOVS R0,#0 ADDS R1,R1,#1 CMP R1,#300 BCC DelayLoop0 MOVS R0,#0 MOVS R1,#0 ADDS R2,R2,#1 CMP R2,#15 BCC DelayLoop0 POP {R0,R1,PC} END END 可直接编译不在进行其他设置,需重新烧录。 四、小结 本次实验实践性很强,需要细心和耐心,其中芯片的使用和端口的查找需要时间。在实验中会有诸多问题,可想同学或老师请教。 |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 14:52 , Processed in 1.259803 second(s), Total 78, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号