原创 stm32 LED

2011-6-29 15:06 4084 7 7 分类: MCU/ 嵌入式

又是LED,但是这一次不同。这次是没有用库的。刚开始出了点问题,问题在这里:

void LED_Init(){
 RCC->APB2ENR|=1<<2;

 GPIOA->CRH&=0xFFFFFFFF;
 GPIOA->CRL&=0xFFFFF0FF;
 GPIOA->CRL|=0x00000300;
 GPIOA->ODR|=1<<2;

 GPIOA->CRL&=0xFFFFFF0F;
 GPIOA->CRL|=0x00000030;
 GPIOA->ODR|=1<<1;
}

因为初始化的原因,即GPIOx_CRL复位值是0x4444 4444,所以要先把对应值清零,即: GPIOA->CRL&=0xFFFFF0FF;和 GPIOA->CRL&=0xFFFFFF0F;,加上这两句,才把LED调出来。下面是具体的程序:

 

#include<stm32f10x_lib.h>

#define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))

#define GPIOA_ODR_Addr (GPIOA_BASE+12)

#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)

//设置向量表偏移地址
//NVIC_VectTab:基址
//Offset:偏移量
void NVIC_SetVectorTable(u32 NVIC_VectTab,u32 Offset){
 SCB->VTOR=NVIC_VectTab|(Offset&(u32)0x1FFFFF80);
}

//不能在这里执行所有外设复位!否则至少引起串口不工作.     
//把所有时钟寄存器复位
void RCC_DeInit(){
 RCC->APB1RSTR=0x00000000;//复位结束
 RCC->APB2RSTR=0x00000000;

 RCC->AHBENR=0x00000014;//睡眠模式闪存和SRAM时钟使能,其他关闭
 RCC->APB1ENR=0x00000000;//外设时钟关闭
 RCC->APB2ENR=0x00000000;
 RCC->CR|=0x00000001;//使能内部高速时钟HSION

 RCC->CFGR&=0xF8FF0000;//复位SW[1:0],HPRE[3:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]

 RCC->CR&=0xFEF6FFFF;//复位HSEON,CSSON,PLLON
 RCC->CR&=0xFFFBFFFF;//复位HSEBYP
 RCC->CFGR&=0xFF80FFFF;//复位PLLLSRC,PLLXTPRE,PLLMUL[3:0] and USBPRE
 RCC->CIR=0x00000000;//关闭所有中断

 //配置向列表
#ifdef VECT_TAB_RAM
 NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else
 NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
}     

void Stm32_Clock_Init(u8 PLL){
 unsigned char temp=0;
 RCC_DeInit();//复位并配置向量表
 RCC->CR|=0x00010000;//外部高速时钟使能HSEON
 while(!(RCC->CR>>17));//等待外部时钟就绪
 RCC->CFGR=0x00000400;//APB1=DIV2;APB2=DIV1;AHB=DIV1;
 PLL-=2;//抵消2个单位
 RCC->CFGR|=PLL<<18;//设置PLL值2~16
 RCC->CFGR|=1<<16;//PLLSRC ON
 FLASH->ACR|=0x32;//FLASH 2个延时周期

 RCC->CR|=0x01000000;//PLLON
 while(!(RCC->CR>>25));//等待PLL锁定
 RCC->CFGR|=0x00000002;//PLL作为系统时钟
 while(temp!=0x02){//等待PLL作为系统时钟设置成功
  temp=RCC->CFGR>>2;
  temp&=0x03;
 }
}

static u8 fac_us=0;
static u16 fac_ms=0;

void delay_init(u8 SYSCLK){
 SysTick->CTRL&0xFFFFFFFB;
 fac_us=SYSCLK/8;
 fac_ms=(u16)fac_us*1000;
}

void delay_ms(u16 nms){
 u32 temp;
 SysTick->LOAD=(u32)nms*fac_ms;
 SysTick->VAL=0x00;
 SysTick->CTRL=0x01;
 do{
  temp=SysTick->CTRL;
 }while(temp&0x01&&!(temp&(1<<16)));
 SysTick->CTRL=0x00;
 SysTick->VAL=0x00;
}

void delay_us(u32 nus){
 u32 temp;
 SysTick->LOAD=nus*fac_us;
 SysTick->VAL=0x00;
 SysTick->CTRL=0x01;
 do{
  temp=SysTick->CTRL;
 }while(temp&0x01&&!(temp&(1<<16)));
 SysTick->CTRL=0x00;
 SysTick->VAL=0x00;
}

void LED_Init(){
 RCC->APB2ENR|=1<<2;

 GPIOA->CRH&=0xFFFFFFFF;
 GPIOA->CRL&=0xFFFFF0FF;
 GPIOA->CRL|=0x00000300;
 GPIOA->ODR|=1<<2;

 GPIOA->CRL&=0xFFFFFF0F;
 GPIOA->CRL|=0x00000030;
 GPIOA->ODR|=1<<1;
}

int main(){
 Stm32_Clock_Init(9);
 delay_init(72);
 LED_Init();
 while(1){
  PAout(1)=1;
  PAout(2)=1;
  delay_ms(300);
  PAout(1)=0;
  PAout(2)=0;
  delay_ms(300);
 }
}

 

发现其实不要配置那么多,下面这个程序就可以实现LED

 

#include<stm32f10x_lib.h>

#define BITBAND(addr,bitnum)((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))

#define GPIOA_ODR_Addr (GPIOA_BASE+12)

void LED_Init(){
 RCC->APB2ENR|=1<<2;

 GPIOA->CRL&=0xFFFFFF0F;
 GPIOA->CRL|=0x00000030;
 GPIOA->ODR|=1<<1;

 GPIOA->CRL&=0xFFFFF0FF;
 GPIOA->CRL|=0x00000300;
 GPIOA->ODR|=1<<2;
}

int main(){
 LED_Init();
 while(1){
 }
}


发现代码还可以缩减为:

#include<stm32f10x_lib.h>

void LED_Init(){
 RCC->APB2ENR|=1<<2;

 GPIOA->CRL&=0xFFFFFF0F;
 GPIOA->CRL|=0x00000030;
 GPIOA->ODR|=1<<1;

 GPIOA->CRL&=0xFFFFF0FF;
 GPIOA->CRL|=0x00000300;
 GPIOA->ODR|=1<<2;
}

int main(){
 LED_Init();
 while(1){
 }
}

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条