首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM8时钟切换(支持HSI/HSE切换)+EEPROM操作支持(就像定义变量一样)(转子原子)3

STM8时钟切换(支持HSI/HSE切换)+EEPROM操作支持(就像定义变量一样)(转子原子)3

//软件中断优先级设置函数
//vector:中断向量号(0~24)
//prio:优先级(1~3),禁止设置为0
//STM8的优先级分为软件优先级和硬件优先级,软件优先级优先于硬件优先级.
//硬件优先级由向量号确定,向量号越小,优先级越高.
//软件优先级可以通过本函数设置.
//STM8软件优先级设置可以分为4个等级(0~3),实际上可设置的就三个等级:1~3
//优先级顺序:0<1<2<3,3的优先级最高,高优先级的中断可以打断低优先级的中断
//多个中断同时发生:在软件优先级相同的情况下,由硬件优先级决定谁先响应.
void ITC_Set(u8 vector,u8 priority)
{

if(priority==0)return;
//不能设置为优先级0

if(priority==2)priority=0;
//优先级2:00B

if(vector<4)

{

ITC->ISPR1&=~(3<<vector*2);
//清除原来的设置

ITC->ISPR1|=priority<<vector*2;
//设置优先级


}else if(vector<8)

{

ITC->ISPR2&=~(3<<(vector-4)*2);
//清除原来的设置

ITC->ISPR2|=priority<<(vector-4)*2;
//设置优先级


}else if(vector<12)

{

ITC->ISPR3&=~(3<<(vector-8)*2);
//清除原来的设置

ITC->ISPR3|=priority<<(vector-8)*2;
//设置优先级


}else if(vector<16)

{

ITC->ISPR4&=~(3<<(vector-12)*2);
//清除原来的设置

ITC->ISPR4|=priority<<(vector-12)*2;//设置优先级


}else if(vector<20)

{

ITC->ISPR5&=~(3<<(vector-16)*2);
//清除原来的设置

ITC->ISPR5|=priority<<(vector-16)*2;//设置优先级


}else if(vector<24)

{

ITC->ISPR6&=~(3<<(vector-20)*2);
//清除原来的设置

ITC->ISPR6|=priority<<(vector-20)*2;//设置优先级


}else if(vector<28)

{

ITC->ISPR7&=~(3<<(vector-24)*2);
//清除原来的设置

ITC->ISPR7|=priority<<(vector-24)*2;//设置优先级


}else if(vector<32)

{

ITC->ISPR8&=~(3<<(vector-28)*2);
//清除原来的设置

ITC->ISPR8|=priority<<(vector-28)*2;//设置优先级


}
}
//外部中断配置函数
//GPIO:0~5(对应GPIO_A~GPIO_E和TLI)
//TRIM:0~3(即00B~11B)
//00,下降沿和低电平触发
//01,仅上升沿触发
//10,仅下降沿触发
//11,上升沿和下降沿触发
void EXTI_Config(u8 GPIOx,u8 TRIM)
{

TRIM&=0X03;
//取低2位有效

if(GPIOx<4)
//GPIOA~D

{

EXTI->CR1&=~(3<<GPIOx*2);
//清除原来的设置

EXTI->CR1|=TRIM<<GPIOx*2;
//设置触发方式

}else if(GPIOx==GPIO_E)
//GPIOE

{

EXTI->CR2&=~(3<<0);
//清除原来的设置

EXTI->CR2|=TRIM;
//设置触发方式

}else if(GPIOx==GPIO_TLI)
//TLI触发方式设置

{

TRIM&=0X01;
//仅最低位有效.

EXTI->CR2&=~(1<<2);
//清除原来的设置

EXTI->CR2|=TRIM<<2;
//设置TLI触发方式

}
}
//自动切换新时钟源(仅HSI/HSE)
//newsrc:0,HSI
//       1,HSE
//返回值:0,修改成功;1,修改失败.
u8 System_Clk_AutoSwitch(u8 newsrc)
{

u16 timeout=0xffff;

u8 oldsrc=CLK->CMSR;
//老的时钟源

CLK->SWCR|=1<<1;
//使能时钟切换功能

CLK->SWCR&=~(1<<2);
//关闭切换中断

if(newsrc==0)CLK->SWR=0XE1;
//HSI

else CLK->SWR=0XB4;

while((CLK->SWCR&(1<<0))&timeout)timeout--;
//等待切换完成

if(oldsrc==0XE1&&newsrc==0XB4)CLK->ICKR&=~(1<<0);
//关闭HSI

else if(oldsrc==0XB4&&newsrc==0XE1)CLK->ECKR&=~(1<<0);
//关闭HSE

if(timeout)return 0;

else return 1;
}
//设置分配系数
//div:0~7,代表2的0~7次幂分频
void System_Clk_DivSet(u8 div)
{

CLK->CKDIVR=0;
//清除原来的设置

CLK->CKDIVR=div&0X07;
//设置DIV
}
   

//STM8时钟配置
//clksrc:0,HSI(16M)做为时钟源;1,HSE(最大24M)作为时钟源
//div:分配系数,0~7,代表2的0~7次幂分频
void stm8_clock_init(u8 clksrc,u8 div)
{

u16 fwait=0;

fwait=STMFLASH_ReadOptionByte(OPT_FLASHWAIT_ADDR);
//读取wait值

if(clksrc==1&&STM8_HSE_B16M&&div==0)
//HSE做时钟,且外部晶振大于16M,且未分频

{

if(fwait!=0X01)//没有设置wait值,则需要设置

{

STMFLASH_Unlock(1);
//先解锁  

STMFLASH_ProgramOptionByte(OPT_FLASHWAIT_ADDR,1);
//大于16Mhz,写入1个flash等待周期

STMFLASH_ProgramOptionByte(OPT_HSESTARTUP_ADDR,0XB4);
//稳定周期设置为128个时钟周期

STMFLASH_Lock(1);
//上锁

}



}else //否则,不需要flash等待周期

{

if(fwait==0X01)//设置了wait值,则需要去掉

{

STMFLASH_Unlock(1);

STMFLASH_EraseOptionByte(OPT_FLASHWAIT_ADDR);
//HSI,不需要FLASH等待周期,提高速度

STMFLASH_EraseOptionByte(OPT_HSESTARTUP_ADDR);
//不需要稳定周期

STMFLASH_Lock(1);

}  

}

System_Clk_DivSet(div);
//设置分频

while(System_Clk_AutoSwitch(clksrc));
//切换时钟
}
继承事业,薪火相传
返回列表