打印

MDK4.6环境下STM32F10xxxx.S一段一段看

[复制链接]
楼主: 明月小厨
手机看帖
扫描二维码
随时随地手机跟帖
41
明月小厨|  楼主 | 2013-1-3 10:22 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 明月小厨 于 2013-1-3 11:24 编辑

好象提示至少有三个.h文件要添加;
一个是IO;
一个是RCC
一个是SPI;
还有其它的没有不记得了;
这都是#include "stm32f10x.h"
中有相关的操作,包括相关的.h文件;如果直接把相关的地方注释掉当然也不会提示错误的;


不过还是添加上比较好些;
因为.h文件很多,要处理的内容太多了,MDK和ST的策略是最重要公用的在#include "stm32f10x.h"
其它每个外设独立配置.h文件;


所以RCC一定要有的,不然时钟不配置不行的;
IO也是要有的,我们第一件事就是点个灯;要操作IO端口的;
SPI暂时不添加当然是可以的;

在出错的地方,你会发现有一大段都是#include ......
下次你用到其它的外设,就到这里把前面的注释去掉;

使用特权

评论回复
42
明月小厨|  楼主 | 2013-1-3 10:28 | 只看该作者
如果你是第一次搞这些,估计你的.h文件不见得有;或不全;
你可以去官网下载一个固件库文件;在固件库文件夹里面这些.h文件都有;

不是纯寄存器模式?怎么又要下载固件库?这个你要问MDK和ST;他们只准备了一套,专为固件库准备的;当然寄存器编程模式也可以用;(是不是里面有不少的垃圾我没仔细看);

如果你经常搞ARM,问题就大了,说不定能搜出来无数的.h文件;用哪个?
有的也许是IAR用的;有的也许是ADS用的;有的也许是谁家的开发板用的;
这里要是选错了;有什么麻烦你们试试看.

我们继续下一步;

使用特权

评论回复
43
明月小厨|  楼主 | 2013-1-3 10:32 | 只看该作者
很空的工程建立起来了;要点灯了;怎么点?
在main()里
添加一句
GPIOA_CRH=0x02;

编译它试试......

使用特权

评论回复
44
明月小厨|  楼主 | 2013-1-3 10:36 | 只看该作者
悲剧出现了;GPIOA_CRH没定义过;不能用,不是添加了io.h文件吗?
......
直接上路,不绕弯子;
习惯C51模式的兄弟对GPIOA->CRH不习惯;迁就一下吧;
在MDK,在这个工程下,用GPIOA->CRH可以的;
语句改成
GPIOA->CRH =0x02;
编译通过了;
以后的寄存器名称GPIOA_CRH用不了,只能GPIOA->CRH用;:(

使用特权

评论回复
45
明月小厨|  楼主 | 2013-1-3 10:38 | 只看该作者
本帖最后由 明月小厨 于 2013-1-3 11:26 编辑

正式点灯;我用的是正点原子的最小裸板;二个灯;一个是PA8;一个是PD2;
直接让PA8输出模式,然后输出0和1;

使用特权

评论回复
46
明月小厨|  楼主 | 2013-1-3 10:39 | 只看该作者
最好自己再定义一个延时1秒左右的延时程序;
不然一直亮,搞不清楚;

使用特权

评论回复
47
明月小厨|  楼主 | 2013-1-3 10:43 | 只看该作者
本帖最后由 明月小厨 于 2013-1-3 11:26 编辑

void SystemInit(void)
{}
void GPIO_init(void)
{
RCC->APB2ENR|=1<<2;
GPIOA->CRH=0X03;
}        
void delay(void)
{
u32 n=1000000;
for(;n>0;n--) ;  
}

int main(void)
{
       GPIO_init();   
       while(1)
              {
              delay();
              GPIOA->ODR = 0x0100;
              delay();
              GPIOA->BSRR = 0x01000000;
              }
}

使用特权

评论回复
48
明月小厨|  楼主 | 2013-1-3 10:48 | 只看该作者
RCC->APB2ENR|=1<<2;
这一句是从网上抄过来的,意思是开启IO部分的时钟线;
我理解IO外设也是挂在设备总线上的,相当于上个8255一样的外设;当然需要读写什么的;需要时序,当然也需要时钟的;

如果省略会有什么后果大家自己试试,验证一下;
其它的省略掉了,没有使用外部晶振,也没有设置PLL;直接使用内部RC时钟(默认);

使用特权

评论回复
49
明月小厨|  楼主 | 2013-1-3 10:54 | 只看该作者
到此,应该是说再见的时候了;
从零开始,到点灯完毕;下一步可以尝试操控一下TIM,SPI......

从昨天下午开始搞.S浪费了半天时间;晚上开始上网下棋,想想也许会有结果,就接着测试,到睡觉前完成它;好象也不是很费劲;
难怪现在搞编程的工资待遇不行,原来是太简单了.一天时间就勉强摸进门了;

使用特权

评论回复
50
明月小厨|  楼主 | 2013-1-3 11:02 | 只看该作者
本帖最后由 明月小厨 于 2013-1-3 15:16 编辑

如果你正准备搞STM32F10X;
看看这些,从零开始怎么搞起来的,少走弯路;1小时搞通;不是很省心很有成就感?
关键是这个过程很透明;复制别人搞过的工程模板;里面也许有你不想要的;不干净;
如果只点灯,不关灯;
全部相关的代码仅三句;
1.配置时钟;RCC->APB2ENR
2.配置端口;GPIOA->CRH
3.输出1;GPIOA->ODR;//输出0也可以用它;//我搞反了,应该是输出0点亮,输出1关灯;大家别计较了;我已经很辛苦很努力了;
一堆的库函数都免了;

使用特权

评论回复
51
明月小厨|  楼主 | 2013-1-3 11:06 | 只看该作者
本帖最后由 明月小厨 于 2013-1-3 12:09 编辑

香版主要是看见此贴肯定感觉很酷很菜;
发此贴见证菜鸟是如何成长的;
大家都可以象我一样动手试试,不要太依赖别人的例程;:):curse:
勇于尝试——没有难度;
我看论坛有人还在问,不用库函数编程行不行?
有这个功夫,自己早就有结果了;:victory:

使用特权

评论回复
52
明月小厨|  楼主 | 2013-1-3 12:11 | 只看该作者
没完没了的错误对我打击也不小,我还在想,要不行就用库函数吧;反正很多人也都是在用的;
晚上一时理不清楚头绪,上网杀了几盘棋;:lol:lol:lol:lol我是围棋高手;

使用特权

评论回复
53
明月小厨|  楼主 | 2013-1-3 12:51 | 只看该作者
GPIOA->BSRR
这个寄存器可以进行单个位操作;不影响其它端口的状态;点关灯用它更好;


使用特权

评论回复
54
明月小厨|  楼主 | 2013-1-3 14:55 | 只看该作者
定时器什么的先放一放,内部时钟比较复杂,比我想象的复杂;RCC有一大堆要理清楚;不然后来的工作没法做;
APB,APB1,APB2,SYSCLK......PLL,HSI,HSE;
后面的内容已经超出本标题标题的讨论范围;另外发贴,一步一个脚印深入浅出学习STM32F103;

使用特权

评论回复
55
明月小厨|  楼主 | 2013-1-3 15:42 | 只看该作者
当HSI被用于作为PLL时钟的输入时,系统时钟能得到的最大频率是36MHz。
晕倒,我的PCB已经排好了,没有外部时钟;只能跑到36MHZ;:curse::curse::curse::curse::curse::curse:

使用特权

评论回复
56
明月小厨|  楼主 | 2013-1-3 15:44 | 只看该作者
这样的话ADC的速度也受影响了;:curse::curse::curse::curse::curse::curse:

使用特权

评论回复
57
明月小厨|  楼主 | 2013-1-3 15:58 | 只看该作者
解决办法:
HSI信号输出到MOC(PA8);然后在外面绕一圈,再到OSCin;
精度可以牺牲,速度不能牺牲;

使用特权

评论回复
58
江陵龙少| | 2013-1-3 23:11 | 只看该作者
明月小厨 发表于 2013-1-2 15:26
Stack_Mem       SPACE   Stack_Size

//SPACE (%与SPACE 同义) 分配一片连续的字节存储区域并初始化为0

NOINIT和SPACE一起用不矛盾:
NOINIT用来指示DATA段不初始化,或初始化为0。
它一般与空间预留指示符SPACE、DCB、DCD、 DCDU, DCQ, DCQU, DCW, or DCWU 配合使用,且这些
空间预留指示符均以0值初始化。

使用特权

评论回复
59
江陵龙少| | 2013-1-3 23:32 | 只看该作者
明月小厨 发表于 2013-1-2 15:50
Stack         Heap:又冒出来一个堆,长度减半;难道这就算是双堆栈了?

Heap和Stack是不同的概念
在编译器的库函数中,有很多库函数用Heap(堆)来存储局部变量,用户有时需要编写这样一个函数:
__user_initial_stackheap()  来初始化堆栈(库要用的),在MDK下,如:
; User Initial Stack & Heap
                AREA    |.text|, CODE, READONLY

                IMPORT  __use_two_region_memory
                EXPORT  __user_initial_stackheap
__user_initial_stackheap

                LDR     R0, =  Heap_Mem
                LDR     R1, =(Stack_Mem + USR_Stack_Size)
                LDR     R2, = (Heap_Mem +      Heap_Size)
                LDR     R3, = Stack_Mem
                BX      LR

在ADS1.2下,如:
__user_initial_stackheap   
    LDR   R0, =bottom_of_heap               
;    LDR   R1, =StackUsr                       
    LDR   R2, =top_of_heap               
    LDR   R3, =bottom_of_Stacks               
    MOV   PC, LR

这个函数用来返回栈顶、栈底、堆顶、堆底的位置。

使用特权

评论回复
60
明月小厨|  楼主 | 2013-1-4 17:02 | 只看该作者

说的很好;没听明白;R0,R1,R2和栈顶有什么关系?
下面贴个图出来;小小成果.被我发现了;
这里设置支持简体中文后编译器乱码会少很多;


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则