#include <iostm8s105s4.h>
unsigned int f_encoder;
//-----------------------------------------------------------
void WDT_Init(void)
{
IWDG_KR = 0xCC; //启动看门狗
IWDG_KR = 0x55; //解除写保护
IWDG_PR = 0x06; //256分频,最高1.02秒
IWDG_RLR = 15; //60ms
IWDG_KR = 0xAA; //写保护
}
//----------------------------------------------------------------
void WDT(void)
{
IWDG_KR = 0xAA; //喂狗指令WDT();
}
//----------------------------------------------------------------
void gpio_init(void)
{
PA_DDR = 0xFF;
PA_CR1 = 0xff;
PA_CR2 = 0x00;
PA_ODR = 0xFF;
PB_DDR = 0xFC;//C;
PB_CR1 = 0xff;
PB_CR2 = 0x00;
PB_ODR = 0xfC;
PC_DDR = 0xFF;
PC_CR1 = 0xff;
PC_CR2 = 0x00;
PC_ODR = 0xFF;
PD_DDR =0xFF;
PD_CR1 =0xff;
PD_CR2 = 0x00;
PD_ODR = 0xff;
PE_DDR = 0xFF;
PE_CR1 = 0xff;
PE_CR2 = 0x00;
PE_ODR = 0xBF;
PG_DDR = 0xFF;
PG_CR1 = 0xff;
PG_CR2 = 0x00;
PG_ODR = 0xFF;
}
#define FLASH_EOP 0X04 //标志位
#define FLASH_DUL 0X08 //标志位
void FLASH_Init(void) //端口重映射初始化函数,在此将PB0映射为TIM1_CH1
{
unsigned char *flash_OPT2;
unsigned char *flash_NOPT2;
flash_OPT2=(unsigned char*)0x4803; //OPT2寄存器的ADDR
flash_NOPT2=(unsigned char*)0x4804; //NOPT2寄存器的ADDR,此寄存器的值是OPT2的取反值
//-------------------------------------------------------------
//第一步 初始化FLASH
while( (FLASH_IAPSR & FLASH_DUL) == 0X00 )
{
FLASH_DUKR = 0XAE;
FLASH_DUKR = 0X56;
} //一旦配置失败,此处将陷入死循环。实际使用请加入超时机制,在此省略
//-------------------------------------------------------------
//第二步 对OPT进行编程,首先需要如下操作:开启opt编程
FLASH_CR2 |= 0X80; //OPT = 1
FLASH_NCR2 &= 0X7F; //NOPT = 0
//-------------------------------------------------------------
//第三步 修改内存
// 1.修改参数,启用复用功能
// 2.OPT2 和 NOPT2要相反
//修改OPT2
*flash_OPT2 = 0X20; // 0000 0001 AFR0=1,PC5复用为TIM2_CH1其它默认清0
while( (FLASH_IAPSR & FLASH_EOP) == 0 ); //等待操作完成
//修改NOPT2
*flash_NOPT2 =0XDF;// ~*flash_OPT2;
while( (FLASH_IAPSR & FLASH_EOP) == 0 ); //等待操作完成
//一旦配置失败,此处将陷入死循环。实际使用请加入超时机制,在此省略
//-------------------------------------------------------------
//第四步 对OPT进行编程,最后需要如下操作:禁用opt编程
FLASH_CR2 &= ~0X80; //OPT = 1
FLASH_NCR2 |= 0X80; //NOPT = 0
}
//=============================================================================
void TIM1_Init(void)
{
CLK_PCKENR1 |=0X80; //开启time1时钟
TIM1_SMCR |= 0X03;//2; //工作在编码器模式2
TIM1_CCMR1 |= 0X1; //IC1FP1映射到TI1)
TIM1_CCMR2 |= 0X1; //IC2FP2映射到TI2 CC2 MAP TI2FP2 CH2
// TIM1_ARRH = 0XEA; // 60000产生溢出 最大65535
// TIM1_ARRL = 0X60;
TIM1_IER |=0X1; //开中断 ,开中断前要有中断处理程序,中断里需要清除中断标志位
TIM1_CNTRH = 0xea; //我要有个大的初始化值
TIM1_CNTRL=0x56;
TIM1_CR1 =0X01; //启动计数
}
//==============================================================================
void main(void)
{
asm("sim"); //关总中断
gpio_init();
FLASH_Init();
TIM1_Init();
WDT_Init();
//-----------------------------
asm("rim"); //开总中断
while(1)
{
WDT(); //喂狗
//----------------------------------------------------------
f_encoder=(TIM1_ARRH<<8)|TIM1_ARRL;
}
}
//====================================================================
#pragma vector = TM1UPDATE_VECT
__interrupt void TIM1_UPDATE_ISR( void )
{
TIM1_SR1 = 0; // clear overflow flag
if(TIM1_CR1 & 0x10)
{
f_encoder--; //逆时针转
}
else
{
f_encoder++; //顺时针转
}
} |