相关链接:http://www.360doc.com/content/11/1114/21/7736891_164374659.shtml
#include "stm32f10x_lib.h" #define SYSTICK_TENMS (*((volatile unsigned long* )0xE000E01C)) //校验值寄存器 #define SYSTICK_CURRENT (*((volatile unsigned long* )0xE000E018)) //当前寄存器 #define SYSTICK_RELOAD (*((volatile unsigned long* )0xE000E014)) //重载寄存器 #define SYSTICK_CSR (*((volatile unsigned long* )0xE000E010)) //控制寄存器 unsigned long TimingDelay; /******************************** 变量定义 ---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; //GPIO ErrorStatus HSEStartUpStatus; typedef unsigned char BYTE; typedef unsigned char BOOL; /*********************************声明函数 -----------------------------------------------*/ void RCC_Configuration(void); void NVIC_Configuration(void); void GPIO_INIT(void); /*配置systick寄存器*/ void SysTick_Configuration(void) { SYSTICK_CURRENT = 0; //当前寄存器清0 SYSTICK_RELOAD = 9000; //重载寄存器的倒计数值9000,倒计数到0时,产生1MS中断 SYSTICK_CSR |= 0x03; //HCLK/8=9MHz作为Systick时钟,Systick打开中断功能 } void SysTick_Handler(void) //中断函数 { SYSTICK_CURRENT = 0; if(TimingDelay != 0) { TimingDelay--; } } void Delay(unsigned long nTime) { TimingDelay = nTime; while(TimingDelay != 0); //此句使得延时,即满足TimingDelay==0,才能进入下一指令的执行 } Test_GPIOA(vu16 *GPIOATemp) { GPIO_Write(GPIOA, ~(*GPIOATemp)); *GPIOATemp = *GPIOATemp << 1; if(*GPIOATemp > 256) { *GPIOATemp = 0x0001; } } int main() { vu16 GPIOAInitStatus = 0x0001; #ifdef DEBUG debug(); //在线调试使用 #endif RCC_Configuration(); NVIC_Configuration(); //启动GPIO模块时钟,如果不使用这句IO口将不工作 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB1Periph_TIM2 | RCC_APB2Periph_AFIO, ENABLE); GPIO_INIT(); SysTick_Configuration(); while(1) { Test_GPIOA(&GPIOAInitStatus); Delay(1000); } } /******************************************************************************* * 配置RCC *******************************************************************************/ void RCC_Configuration(void) { //复位RCC外部设备寄存器到默认值 RCC_DeInit(); //打开外部高速晶振 RCC_HSEConfig(RCC_HSE_ON); //等待外部高速时钟准备好 HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好 { //开启FLASH的预取功能 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //FLASH延迟2个周期 FLASH_SetLatency(FLASH_Latency_2); //配置AHB(HCLK)时钟=SYSCLK RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置APB2(PCLK2)钟=AHB时钟 RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB1(PCLK1)钟=AHB 1/2时钟 RCC_PCLK1Config(RCC_HCLK_Div2); //配置PLL时钟 == 外部高速晶体时钟*9 PLLCLK = 8MHz * 9 = 72 MHz RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //使能PLL时钟 RCC_PLLCmd(ENABLE); //等待PLL时钟就绪 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } //配置系统时钟 = PLL时钟 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //检查PLL时钟是否作为系统时钟 while(RCC_GetSYSCLKSource() != 0x08) { } } } /******************************************************************************* * NVIC配置函数 *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif /* 开启定时器2 */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /******************************************************************************* * GPIO 初始化 *******************************************************************************/ void GPIO_INIT(void) { GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //所有GPIO为同一类型端口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出的最大频率为50HZ GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA端口 } #ifdef DEBUG /******************************************************************************* * Function Name : assert_failed * Description : Reports the name of the source file and the source line number * where the assert_param error has occurred. * Input : - file: pointer to the source file name * - line: assert_param error line source number * Output : None * Return : None *******************************************************************************/ void assert_failed(u8* file, u32 line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* InfInite loop */ while (1) { } } #endif
关于51的定时器说明:
预备条件:晶振为12M,TMOD = 0x01,即定时器0为方式1,16 位定时器/计数器,模式选为0,即对单片机的晶体振荡器12分频后的脉冲进行计数。
这样定时器0的振荡模式为1MHz,
void timer0() interrupt 1 { TH0=(65536-50000)/256; //50ms 中断一次,计算方式见张毅刚版的《单片机原理与应用》 第二版 TL0=(65536-50000)%256; count++; if(count==20)//改为18时,适用于11.0592,比较精确 { count=0; sec++; } }
这样使得每1S,秒数增加1.
函数原型:
void GPIO_Write(GPIO_TypeDef* GPIOx, u16 PortVal);
相当于
GPIOx->BSRR = PortVal& 0xFF00;
GPIOx->BRR = (~PortVal)) & 0xFF00;