打印

香主,IAR下对EEPROM写保护操作报错

[复制链接]
4404|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
black.lu|  楼主 | 2010-7-13 12:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 black.lu 于 2010-7-13 18:41 编辑

IAR的自带例程里有这样的操作:FLASH->IAPSR &= (u8)(~FLASH_IAPSR_DUL);
而我的操作:FLASH_IAPSR_DUL=0;就报错,编译不过,我看过系统头文件,已经对FLASH_IAPSR_DUL进行了定义,所以不存在没定义的问题。
而且编译报错是Error[Pe137]: expression must be a modifiable lvalue,即指FLASH_IAPSR_DUL不可修改,这是为什么啊,一直没解决掉,后来也没管他,今天打干扰的时候出问题了……郁闷。
沙发
sheriff| | 2010-7-13 14:07 | 只看该作者
宏定义是常量,不能赋值,变量才能被赋值

使用特权

评论回复
板凳
pkat| | 2010-7-13 14:57 | 只看该作者
常量肯定是不能被赋值的

使用特权

评论回复
地板
stm8s103| | 2010-7-13 15:00 | 只看该作者
楼主先找本C语言的书看看,
什么是左值(lvalue),什么是右值(rvalue)。

使用特权

评论回复
5
black.lu|  楼主 | 2010-7-13 17:19 | 只看该作者
谢谢楼上各位的回答,关于C语言的问题,左值和右值的概念我还是懂的,如果是常量宏定义,我不否认我的写法是有问题的。但是如果去IAR自带的iostm8.h的头文件中看,
#define FLASH_IAPSR_DUL          FLASH_IAPSR_bit.DUL
不难发现 FLASH_IAPSR_DUL不是常量,而是结构体的成员变量,所以不会存在赋值、以及左右值的问题。
在头文件中队FLASH_IARSR的结构体定义为:
__IO_REG8_BIT(FLASH_IAPSR, 0x505F, __READ, __BITS_FLASH_IAPSR);即该寄存器为只读。
我现在唯一的解决办法是更改系统头文件,将该寄存器更改为可读可写(__READ_WRITE),才可以解决在密码开启之后的数据写保护问题。(当然单片机复位不算)
更改后的结果是:编译能通过、密钥开启后可以通过DUL清零(即重新写保护),与PDF资料相符。
还是想请权威人士给一个肯定的结论,这样的操作是不是有风险,还是IAR本身的问题?

使用特权

评论回复
6
stm8s103| | 2010-7-13 17:32 | 只看该作者
工程使用的ST的固件库没有?

如果使用了,楼主你找错了文件。
(使用库并没有包含iostm8.h,而是包含stm8s.h)

使用特权

评论回复
7
black.lu|  楼主 | 2010-7-13 18:40 | 只看该作者
我没有使用库,库太繁琐。直接操作寄存器,自己写的,对了我的开发环境是IAR,我看安装目录下的头文件夹内都是是io打头的头文件,LS是用的STVD吗?
6# stm8s103

使用特权

评论回复
8
stm8s103| | 2010-7-13 18:46 | 只看该作者
楼主把反映问题的最小工程上传吧

使用特权

评论回复
9
black.lu|  楼主 | 2010-7-13 19:29 | 只看该作者
/*******************************************************************************
Copyright (C), 2003-2009, winpark Electronics Co., Ltd.
Flie name:         for STM8Sxxx--eeprom
Author:                black.lu       
Version:        V1.00
Date:                2010-6-29
Description:对STM8系列单片机的内部EEPROM进行操作
*******************************************************************************/
#include "File_Include.h"
//----------------------------------------------------------
#define MASS_KEY1        0XAE        //写操作密钥,注意FLASH与EEPROM的密钥相反
#define MASS_KEY2        0X56
//----------------------------------------------------------

/***********************************************************
* 函数:void STM8_EEPROM_Init(void)
* 说明:EEPROM的寄存器初始化
* 参数:无
* 输出:无
* 返回:无
***********************************************************/
void STM8_EEPROM_Init(void)
{
        //都初始化为默认值
        FLASH_CR1=0X00;
        FLASH_CR2=0X00;
        FLASH_NCR2=0XFF;       
}
/***********************************************************
* 函数:void STM8_EEPROM_MASS(void)
* 说明:对STM8的EEPROM写使能和写保护
* 参数:bool mass_en
                0--写保护
                1--写使能
* 输出:无
* 返回:无
***********************************************************/
void STM8_EEPROM_MASS(bool mass_en)
{
        if(mass_en)                //写使能
        {
                FLASH_DUKR=MASS_KEY1;       
                FLASH_DUKR=MASS_KEY2;
                while(!FLASH_IAPSR_DUL)asm("nop");        //等待硬件置位       
        }
        else                        //写保护
        {
                FLASH_IAPSR_DUL=0;               
        }
}
/***********************************************************
* 函数:void STM8_EEPROM_Write_Byte(void)
* 说明:EEPROM写一字节函数
* 参数:uint16 address----写入数据的地址
                uint8 dat----写入的一字节数据
                bool mass_en----密钥开启选择
* 输出:无
* 返回:无
***********************************************************/
void STM8_EEPROM_Write_Byte(uint16 address, uint8 dat, bool mass_en)
{
        if(mass_en)                //是否需要密钥
        {
                STM8_EEPROM_MASS(1);        //密钥使能
        }
        *((uint8 *)address)=dat;        //写入地址
//        STM8_EEPROM_MASS(0);        //禁止写入,直接在使用时将其禁止
}
/***********************************************************
* 函数:uint8 STM8_EEPROM_Read_Byte(uint8 address)
* 说明:EEPROM读取地址一字节函数
* 参数:address----需要读取的地址
* 输出:无
* 返回:uint8
***********************************************************/
uint8 STM8_EEPROM_Read_Byte(uint16 address)
{
        uint8 lc_dat_buf;
        lc_dat_buf=*((uint8 *)address);        //读取偏移地址数据
        return lc_dat_buf;
}
/***********************************************************
* 函数:void STM8_EEPROM_Write_NByte(void)
* 说明:EEPROM写N字节函数
* 参数:uint16 address----写入数据的起始地址的地址
                uint8 *p----写入的数据指针
                uint8 n-----写入的个数
* 输出:无
* 返回:无
***********************************************************/
void STM8_EEPROM_Write_NByte(uint16 address, uint8 *p, uint8 n)
{
        uint16 lc_adr_buf;
        uint8 i;
        STM8_EEPROM_MASS(1);        //密钥使能
        lc_adr_buf=address;                //起始地址
        for(i=0;i<n;i++)
        {
                *((uint8 *)lc_adr_buf)=*p;
                lc_adr_buf++;
                p++;
        }       
        STM8_EEPROM_MASS(0);        //禁止写入       
}
/***********************************************************
* 函数:void STM8_EEPROM_Read_NByte(void)
* 说明:EEPROM读N字节函数
* 参数:uint16 address----读取的数据的起始偏移地址
                uint8 *p----读取后存入的首地址
                uint8 n-----读取的个数
* 输出:无
* 返回:无
***********************************************************/
void STM8_EEPROM_Read_NByte(uint16 address, uint8 *p, uint8 n)
{
        uint16 lc_adr_buf;
        uint8 i;
        for(i=0;i<n;i++)
        {
                *p=*((uint8 *)lc_adr_buf);
                p++;
                lc_adr_buf++;                       
        }       
}

使用特权

评论回复
10
black.lu|  楼主 | 2010-7-13 19:31 | 只看该作者
我的EEPROM的驱动文件部分的代码都在上面了,红色句就是编译不过的。

使用特权

评论回复
11
ShakaLeo| | 2010-7-13 21:16 | 只看该作者
这个问题挺有意思
我的理解: 寄存器定义的时候类型为READ,那么这个寄存器就相当于定义了一个const修饰的常变量,是不能当左值用的。而把寄存器定义改为READ WRITE型的时候,这个寄存器就可读可写的了。
这么做有没有风险,得看STM8手册上对该寄存器的描述

使用特权

评论回复
12
ShakaLeo| | 2010-7-14 08:32 | 只看该作者
今天看了一下IAREWARM,感觉昨天猜对了,io_macros.h中:
#define __READ_WRITE
#ifdef __cplusplus
#define __READ          /* Not supported */
#else
#define __READ          const
#endif
#define __WRITE         /* Not supported */

使用特权

评论回复
13
black.lu|  楼主 | 2010-7-14 08:34 | 只看该作者
如果按PDF上的说明,FLASH_IAPSR寄存器的DUL位是可以通过写入密钥来硬件置位,(中文手册36页,英文手册51页)软件清零的。即该位是可读可写的。

使用特权

评论回复
14
ShakaLeo| | 2010-7-14 08:58 | 只看该作者
那就不太清楚了,对STM8不熟悉,很可能是这个寄存器中有其它的位是只读位,头文件中就把整个寄存器定义成只读了

使用特权

评论回复
15
mcu5i51| | 2010-7-14 09:01 | 只看该作者
IAR 头文件错误不止一处呀,尽量使用库文件吧;

使用特权

评论回复
16
IJK| | 2010-7-14 09:21 | 只看该作者
自己进行些小修改,就可以了,比如:
__IO_REG8_BIT(FLASH_IAPSR_RW, 0x505F, __READ, __BITS_FLASH_IAPSR);即该寄存器为可读写。
#define FLASH_IAPSR_RW_DUL          FLASH_IAPSR_RW_bit.DUL

FLASH_IAPSR_RW_DUL=0;

使用特权

评论回复
17
stm8s103| | 2010-7-14 11:31 | 只看该作者
本帖最后由 stm8s103 于 2010-7-14 11:36 编辑

楼主上传最小反映问题工程。

光代码没用,无解。

这里仅仅是个编译错误,要找错误得看上下文环境。

使用特权

评论回复
18
black.lu|  楼主 | 2010-7-14 12:27 | 只看该作者
……还有哪些错误啊,能不能举例下,免得我以后遇到又没辙,感谢!
15# mcu5i51

使用特权

评论回复
19
mcu5i51| | 2010-7-14 17:54 | 只看该作者
好像TM2部分在103F3时有错误吧,还有级的少一个端口定义;记不清了,后来就用库了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:零起点,电子承载梦想,为生活debug!

0

主题

162

帖子

1

粉丝