相关链接: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;