正点原子的寄存器篇的工程,通常由以下文件组成:
Source Group | startup_stm32f40_41_xxx.s | 启动文件 |
USER | main.c | 用户程序主文件 |
SYSTEM | delay.c usart.c sys.c | 原子团队自己写的文件 |
HARDWARE | xxx.c | main.c里面调用的一些函数的申明 |
接下来分析以下几个固有的文件。
首先是delay.c
1 #include "delay.h" 2 #include "sys.h" 26 27 static u8 fac_us=0;// us的延时 28 static u16 fac_ms=0;// ms的延时 //把uc_os相关的条件编译去掉后,就只剩下这些了,其实就是定义了初始化和三个延时函数。
一个延时x us(x作为参数传入函数),另两个延时都是ms延时,只是xms这个函数,基本计数单位还是systick,而后面的ms函数,调用了xms函数,延时更长了。 44 void delay_init(u8 SYSCLK) 45 { 49 SysTick->CTRL&=~(1<<2); 50 fac_us=SYSCLK/8; 51 61 fac_ms=(u16)fac_us*1000; 63 } //SysTick是结构体指针,定义在core_cm4.h中: #define SysTick ((SysTick_Type *) SysTick_BASE )
//SysTick有4个寄存器来控制,见如下:
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
SysTick_BASE 是寄存器的基地址,后面程序中通过如SysTick->LOAD的操作,完成对寄存器的调用。 后面的函数实现都比较好理解,就不啰嗦了。具体可以查询CPU中对SysTick的介绍
111 void delay_us(u32 nus) 112 { 113 u32 temp; 114 if(nus==0)return; 115 SysTick->LOAD=nus*fac_us; 116 SysTick->VAL=0x00; 117 SysTick->CTRL=0x01 ; 118 do 119 { 120 temp=SysTick->CTRL; 121 }while((temp&0x01)&&!(temp&(1<<16))); 122 SysTick->CTRL=0x00; 123 SysTick->VAL =0X00; 124 } 131 void delay_xms(u16 nms) 132 { 133 u32 temp; 134 SysTick->LOAD=(u32)nms*fac_ms; 135 SysTick->VAL =0x00; 136 SysTick->CTRL=0x01 ; 137 do 138 { 139 temp=SysTick->CTRL; 140 }while((temp&0x01)&&!(temp&(1<<16))); 141 SysTick->CTRL=0x00; 142 SysTick->VAL =0X00; 143 } 146 void delay_ms(u16 nms) 147 { 148 u8 repeat=nms/540; 150 u16 remain=nms%540; 151 while(repeat) 152 { 153 delay_xms(540); 154 repeat--; 155 } 156 if(remain)delay_xms(remain); 157 }
后面的思路类同,不单独介绍这些文件,只有在main中直接或者间接调用了这些,再回去学习这些函数。
int main(void) { Stm32_Clock_Init(336,8,2,7); //这个程序在卖家写的sys.c中,这个是对芯片内部时钟树的初始化,对RCC寄存器做了配置。 delay_init(168); //已经介绍了 LED_Init(); //对GPIO进行配置,也在sys.c中,设置GPIO的各种模式 while(1) { LED0=0; //对GPIO的置位 LED1=1; delay_ms(500); LED0=1; LED1=0; delay_ms(500); } }
一个小小的例子,引出好多东西,接下来需要了解的是RCC部分,GPIO部分。
原文:http://www.cnblogs.com/nasduc/p/4668937.html