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

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

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

sys.c代码如下:
#include "sys.h"
////////////////////////////////////////////////////////////////////////////////

//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK
//系统相关代码
   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2013/6/27
//版本:V1.1
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//******************************************************************************
//V1.0 20130625
//支持选项字编程
//支持IAR EEPROM变量定义操作
//支持系统时钟初始化设置,包括HSE/HSI设置以及分频设置
//V1.1 20130627
//增加中断管理函数ITC_Set和EXTI_Config
////////////////////////////////////////////////////////////////////////////////
  

//解锁STM8S的FLASH
//0,程序存储区(FLASH)解锁
//1,数据存储区(EEPROM)解锁
void STMFLASH_Unlock(u8 type)
{
    if(type==0)
//程序存储区(FLASH)解锁
    {
        FLASH->PUKR=FLASH_UNLOCK_KEY1;
        FLASH->PUKR=FLASH_UNLOCK_KEY2;
    }
    else
//数据区(EEPROM)解锁
    {
        FLASH->DUKR=FLASH_UNLOCK_KEY2;
//注意,这里和数据手册写的有出入!!!
        FLASH->DUKR=FLASH_UNLOCK_KEY1;
    }

while(!(FLASH->IAPSR&(1<<3)));
//等待解锁成功
}
//STM8S的FLASH上锁
//0,程序存储区(FLASH)上锁
//1,数据存储区(EEPROM)上锁
void STMFLASH_Lock(u8 type)
{

if(type==0)FLASH->IAPSR&=~(1<<1);
//主程序存储区(FLASH)上锁

else FLASH->IAPSR&=~(1<<3);
//数据存储区(EEPROM)上锁
}
//等待FLASH操作完成
//type:
//0,等待程序存储区(FLASH)操作
//1,等待数据存储区(EEPROM)操作
//返回值:0,成功;1,失败.
u8 STMFLASH_WaitForLastOperation(u8 type)
{
    u8  status=0X00;
    u32 timeout=0XFFFFF;
#if defined(STM8S208)||defined(STM8S207)||defined(STM8S007)||defined(STM8S105)||\
    defined(STM8S005)||defined(STM8AF52Ax)||defined(STM8AF62Ax)||defined(STM8AF626x)  
    if(type==0)//等待FLASH操作结束
    {
        while((status==0x00)&&timeout)
        {
            status=FLASH->IAPSR&(1<<2|1<<0);
            timeout--;
        }
    }else
//等待EEPROM操作结束
    {
        while((status==0x00)&&timeout)
        {
            status=FLASH->IAPSR&(1<<6|1<<0);
            timeout--;           
        }
    }
#else//STM8S103, STM8S903

while((status&&timeout)

{

status=FLASH->IAPSR&(1<<2|1<<0);

timeout--;   

}
#endif
    if(timeout==0)return 1;

return 0;
}
//擦除选项字
//addr:选项字地址
void STMFLASH_EraseOptionByte(u16 addr)
{
    FLASH->CR2|=1<<7;
//选项字写使能
    FLASH->NCR2&=~(1<<7);
//互补选项字写使能

if(addr==0x4800)
//写ROP,没有互补选项字
    {
       *((NEAR u8*)addr)=0X00;
//清零
    }else
    {
       *((NEAR u8*)addr)=0X00;
//清零
       *((NEAR u8*)((u16)(addr+1)))=0XFF;//互补设置
    }
    STMFLASH_WaitForLastOperation(0);//等待写完成
    FLASH->CR2&=~(1<<7);
//选项字写禁止
    FLASH->NCR2|=1<<7;
//互补选项字写禁止
}
//编程选项字
//addr:选项字地址
//data:要写入的值
void STMFLASH_ProgramOptionByte(u16 addr,u8 data)
{
   
FLASH->CR2|=1<<7;
//选项字写使能
    FLASH->NCR2&=~(1<<7);
//互补选项字写使能

if(addr==0x4800)
//写ROP,没有互补选项字
    {
       *((NEAR u8*)addr)=data;
//写选项字
    }else
    {
       *((NEAR u8*)addr)=data;
//写选项字
       *((NEAR u8*)((u16)(addr+1)))=(u8)(~data);//写互补字节
    }
    STMFLASH_WaitForLastOperation(0);
//等待写完成
    FLASH->CR2&=~(1<<7);
//选项字写禁止
    FLASH->NCR2|=1<<7;
//互补选项字写禁止
}
//读取OPT字节
//addr:OPT字节地址
//返回值:读取到的内容,如果>0XFF,则读数有问题.如果<=0XFF,正确的OPT读数
u16 STMFLASH_ReadOptionByte(u16 addr)
{
    u8 value_optbyte,value_optbyte_complement=0;
    u16 res_value=0;

    value_optbyte=*((NEAR u8*)addr);
//读取OPT字节
    value_optbyte_complement=*(((NEAR u8*)addr)+1); //读取互补OPT字节
    res_value=value_optbyte;
//返回值为opt值

if(value_optbyte!=(u8)(~value_optbyte_complement))res_value=0X5555;//OPT有误

if(addr==0X4800)res_value=value_optbyte;

//ROP不存在互补opt,直接返回opt值
    return res_value;
}
//以下三个函数,以支持IAR独有的__eeprom关键字操作
//EEPROM完成操作等待
void __eeprom_wait_for_last_operation(void)
{

STMFLASH_WaitForLastOperation(1);
//等待操作结束
}
//EEPROM,在指定位置写入一个字节数据
//addr:地址
//data:要写入的数据
void __eeprom_program_byte(unsigned short addr,unsigned char data)
{

__eeprom_wait_for_last_operation();  
  
STMFLASH_Unlock(1);

*(PointerAttr u8*)(u16)addr=data;

__eeprom_wait_for_last_operation();

STMFLASH_Lock(1);   
}   
//EEPROM,在指定位置写入一个long型数据(4字节)
//addr:地址
//data:要写入的long型数据
void __eeprom_program_long(unsigned short addr,unsigned long data)
{

__eeprom_wait_for_last_operation();  
  
STMFLASH_Unlock(1);

*(PointerAttr u8*)(u16)addr=(u8)(data>>24);  

__eeprom_wait_for_last_operation();

*(PointerAttr u8*)(u16)(addr+1)=(u8)(data>>16);  

__eeprom_wait_for_last_operation();

*(PointerAttr u8*)(u16)(addr+2)=(u8)(data>>8);  

__eeprom_wait_for_last_operation();

*(PointerAttr u8*)(u16)(addr+3)=(u8)(data&0XFF);  

__eeprom_wait_for_last_operation();  

STMFLASH_Lock(1);
}
继承事业,薪火相传
返回列表