为什么stm8l101 eeprom52的EEPROM可以从0x0000开始写

STM8单片机内部EEPROM问题_百度知道
STM8单片机内部EEPROM问题
程序如下,两个问题。第一:为什么DUL为0时才解锁?手册不是说这一位为1时解锁吗?第二:为什么使用STVD进行软件仿真时,把0x55写到EEPROM的0x4000的地址中,仿真结果,0x55却到了0x4001的地址上,而0x4000的地址是0。(仿真时,MEMORY的结果如下)void&main(void)& & & & //主函数{//unsigned&char&i;//unsigned&char&Data&=&0x55;//unsigned&int&*StratA//TIM_TIMER_IRQInit();while&(1){IWDG();//if&(TimeFlag.Flag2ms){TimeFlag.Flag2ms&=&0;E畅穿扳费殖渡帮杀爆辑EPROM_WriteByte(0x4000);& & & & //将0x55写到EEPROM的0x4000的地址中}}}void&EEPROM_Unlock(void)& & & & //EEPROM解锁{do{FLASH_DUKR&=&0x56;FLASH_DUKR&=&0xAE;}while((FLASH_IAPSR&&&0x08)&==&0);//等待解锁成功}void&EEPROM_Lock(void)& & & & //锁EEPROM{FLASH_IAPSR&|=&0x08;//Set&DUL//FLASH_IAPSR&&=&0x;//Clear&EOP}void&EEPROM_WriteByte(unsigned&int&StartAddress)& &//写一个字节到EEPROM地址{unsigned&int&*EEPROM_Address,AAddress&=&StartAEEPROM_Address&=&(unsigned&int&*)AEEPROM_Unlock();*EEPROM_Address&=&0x55;while((FLASH_IAPSR&&&0x04)&==&0);EEPROM_Lock();}
提问者采纳
这个问题我来回答你吧.第一,是你理解错了,手册并没有错,DUL为1时解锁.看程序:do{
FLASH_DUKR = 0x56;
FLASH_DUKR = 0xAE;}while((FLASH_IAPSR & 0x08) == 0);//等待解锁成功那个While的意思:如果FLASH_IAPSR 的BIT3位为0,那么,FLASH_IAPSR & 0x08 就会等于0,这个时候,((FLASH_IAPSR & 0x08) == 0)这个条件就成立,那么就会循环.相反,如果FLASH_IAPSR 的BIT3位为1,那么,FLASH_IAPSR & 0x08 就会等于0x08,这个时候,((FLASH_IAPSR & 0x08) == 0)这个条件就不会成立,那么就会退出循环.所以,DUL位为1才表示解锁,是你自己理解错了. 第二个问题,所有的单片机存储方式分两种,一种是大端,另一种是小端,举例来说: unsigned short * P = (unsigned short *)0x0000;unsigned long *Q = (unsigned long *)0x0004;*P = 0x1234;*Q = 0x那么,如果是小端存储,各个地址存储的内容应该如下:地址 00
0x12 小端比较好理解,如果是大端,各内容应该如下:地址 00
0x78 相信我这样举例子你应该明白了吧?STM8是大端方式, 你向 unsigned int 类型的地址里写 0x55,那么被扩展成 0x0055如果是小端方式 0x00放在高半段,也就是地址 0x4001上,而0x4000上放0x55但是STM8是大端方式,所以 把低半段0x55放在高地址0x4001,而把高半段0x00放在低地址0x4000上. 如果你想把0x55放在0x4000上,改一下函数:void EEPROM_WriteByte(unsigned int StartAddress)
//写一个字节到EEPROM地址{unsigned int *EEPROM_Address,AAddress = StartAEEPROM_Address = (unsigned int *)AEEPROM_Unlock();*EEPROM_Address = 0x55;while((FLASH_IAPSR & 0x04) == 0);EEPROM_Lock();}把那个里面所有的 unsigned int 修改成 unsigned char
提问者评价
太好了,非常感谢你!!!
来自团队:
其他类似问题
为您推荐:
stm8的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁21ic官方微信
后使用快捷导航没有帐号?
查看: 861|回复: 6
STM8L152 ADC_DMA读出数有移动
&&已结帖(20)
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
#define ADC1_DR_ADDRESS& && &&&((uint16_t)0x5344)
#define BUFFER_SIZE& && && && &((uint8_t) 0x08)
#define BUFFER_ADDRESS& && && &((uint16_t)(&Buffer))
signed int Buffer[BUFFER_SIZE]&&= {0,0,0,0,0,0,0,0};
void ADC_DMAInit(void)
& &&&ADC_DeInit(ADC1);
& &&&DMA_GlobalDeInit();
& &&&CLK_PeripheralClockConfig(CLK_Peripheral_ADC1,ENABLE);
& &&&CLK_PeripheralClockConfig(CLK_Peripheral_DMA1,ENABLE);
& &&&ADC_Init(ADC1,ADC_ConversionMode_Continuous,ADC_Resolution_12Bit,ADC_Prescaler_2);
& &&&ADC_SamplingTimeConfig(ADC1,ADC_Group_SlowChannels,ADC_SamplingTime_384Cycles);
& &&&ADC_SamplingTimeConfig(ADC1, ADC_Group_FastChannels, ADC_SamplingTime_384Cycles);
& &&&ADC_Cmd(ADC1, ENABLE);& &&&
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_2,ENABLE);//电位器4
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_8,ENABLE);//电位器3
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_9,ENABLE);//电位器2
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_10,ENABLE);//电位器1
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_18,ENABLE);
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_19,ENABLE);
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_20,ENABLE);
& &&&ADC_ChannelCmd(ADC1,ADC_Channel_21,ENABLE);
& &&&SYSCFG_REMAPDMAChannelConfig(REMAP_DMA1Channel_ADC1ToChannel0);
& &&&DMA_Init(
& && && && && &DMA1_Channel0,
& && && && && &BUFFER_ADDRESS,
& && && && && &ADC1_DR_ADDRESS,
& && && && && &BUFFER_SIZE,
& && && && && &DMA_DIR_PeripheralToMemory,
& && && && && &DMA_Mode_Circular,
& && && && && &DMA_MemoryIncMode_Inc,
& && && && && &DMA_Priority_High,
& && && && && &DMA_MemoryDataSize_HalfWord);
& &&&DMA_Cmd(DMA1_Channel0, ENABLE);
& &&&DMA_ITConfig(DMA1_Channel0,DMA_ITx_TC,ENABLE);
& & DMA_GlobalCmd(ENABLE);
& & ADC_DMACmd(ADC1, ENABLE);
& & ADC_SoftwareStartConv(ADC1);
& &ADC_ExternalTrigConfig(ADC1, ADC_ExtEventSelection_Trigger2,
& && && && && && && && &ADC_ExtTRGSensitivity_Falling);
程序是参照官方例程写的,中断里没有进行操作,只是程序里对读数Buffer数组里的数进行操作,上电运行刚开始正常,但过一些时间后出现读出来的Buffer[]与设置好的AD口不对应,如Buffer[0]可能是电位器2的读数,也可能电位器3等其他读数,请大神帮忙解决下
满意回复+8
这两部分程序有没有操作同一块内存?会不会是这里的问题。
有移动?电平不稳定呀
#define ADC1_DR_Address
//ADC1 Peripheral address
#define DMA_BUF_SIZE 4
unsigned int
DMA_Bufer[DMA_BUF_SIZE] = {0};
/*ADC init*/
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
void EepromWrite(int RunTime,int Adress)& & //写Eeprom
& & int *p;
& & p = (int *)A
& && &FLASH-&DUKR = 0
& && &FLASH-&DUKR = 0x56;
& & while((FLASH-&IAPSR & 0x08) == 0);
& & *p = RunT& && && && && && && &//写入时间
& & while((FLASH-&IAPSR & 0x04) == 0); //等待写操作成功
发现了这个问题不是ADC_DMA初始运行出错的问题,是写这个内部e2prom有冲突导致,只要这个一执行,DMA读ADC的数据顺序就出错,具体为何,如果处理作为菜鸟我不清楚
主题帖子积分
助理工程师, 积分 1614, 距离下一级还需 386 积分
助理工程师, 积分 1614, 距离下一级还需 386 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
助理工程师, 积分 1614, 距离下一级还需 386 积分
助理工程师, 积分 1614, 距离下一级还需 386 积分
这两部分程序有没有操作同一块内存?会不会是这里的问题。
主题帖子积分
实习生, 积分 27, 距离下一级还需 23 积分
实习生, 积分 27, 距离下一级还需 23 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
实习生, 积分 27, 距离下一级还需 23 积分
实习生, 积分 27, 距离下一级还需 23 积分
#define ADC1_DR_Address& &0x5344& && &&&//ADC1 Peripheral address
#define DMA_BUF_SIZE 4
unsigned int&&DMA_Bufer[DMA_BUF_SIZE] = {0};
/*ADC init*/
ADC_DeInit(ADC1);
ADC_Cmd(ADC1, ENABLE);& && && & //enable adc1
ADC_DMACmd(ADC1, ENABLE);& && & //enable the DMA transfer
ADC_Init(ADC1,
& && && &ADC_ConversionMode_Continuous,
& && && &ADC_Resolution_12Bit,
& && && &ADC_Prescaler_1);& &// 12 clk= system clk
ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_384Cycles);& && &&&//sample time setting
ADC_ChannelCmd(ADC1, ADC_Channel_19, ENABLE);& & //channel setting
ADC_ChannelCmd(ADC1, ADC_Channel_20, ENABLE);& & //channel setting
ADC_ChannelCmd(ADC1, ADC_Channel_21, ENABLE);& & //channel setting
ADC_ChannelCmd(ADC1, ADC_Channel_22, ENABLE);& & //channel setting
SYSCFG_REMAPDMAChannelConfig(REMAP_DMA1Channel_ADC1ToChannel0);
/*DMA Init*/
DMA_Init(DMA1_Channel0,
& && && &(uint32_t)DMA_Bufer,
& && && &ADC1_DR_Address,
& && && &DMA_BUF_SIZE,
& && && &DMA_DIR_PeripheralToMemory,
& && && &DMA_Mode_Circular,
& && && &DMA_MemoryIncMode_Inc,
& && && &DMA_Priority_High,
& && && &DMA_MemoryDataSize_HalfWord);
DMA_SetCurrDataCounter(DMA1_Channel0,DMA_BUF_SIZE);
DMA_ITConfig(DMA1_Channel0, DMA_ITx_TC, ENABLE);
DMA_ITConfig(DMA1_Channel0, DMA_ITx_HT, DISABLE);
DMA_Cmd(DMA1_Channel0, ENABLE);
在DMA中断中我将一个标志位置1,然后再main的while(1)里面检测该标志位,为1时通过串口输出,也出现和楼主一样的问题,而且ADC_SamplingTime_384Cycles这个不同时,DMA读到的数据顺序也会出现不一样,不知道是哪儿的问题,希望斑竹能帮忙解释一下。
主题帖子积分
实习生, 积分 39, 距离下一级还需 11 积分
实习生, 积分 39, 距离下一级还需 11 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 39, 距离下一级还需 11 积分
实习生, 积分 39, 距离下一级还需 11 积分
有移动?电平不稳定呀
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
这两部分程序有没有操作同一块内存?会不会是这里的问题。
有,但EEPROM写前只是对AD读数的读取,理论上不影响
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
有移动?电平不稳定呀
听某大神说写内部eeprom时,会拉其他外设的电压,我用写完EEPROM后再对AD初始化回避这个问题了,但这样浪费资源
技术新星奖章
人才类勋章查看: 3610|回复: 9
STM8S 片内EEPROM 数据写不进去
主题帖子精华
新手上路, 积分 31, 距离下一级还需 19 积分
在线时间0 小时
用的是IAR编译器,碰到了一个奇怪的问题 EEPROM的地址范围是0xff
向0x4000 写数据是可以的 eeprom_write_bytes(0x",4);
但向0x4100写数据就不可以eeprom_write_bytes(0x",4),通过STVP查看存储区,没有数据写入
下面是代码,麻烦给指点下,谢谢!
void eeprom_write(unsigned long addr,unsigned char num)
&FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);& //确保前面的操作完成
&FLASH_Unlock(FLASH_MEMTYPE_DATA); //解锁写保护
&FLASH_ProgramByte(addr,num);
&FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);& //等待操作完成
&FLASH_Lock(FLASH_MEMTYPE_DATA); //写保护
void eeprom_write_bytes(unsigned long addr,unsigned char *pbuf,unsigned char len)
&for(i=0;i&i++)
&&eeprom_write(addr+i,*pbuf++);
主题帖子精华
在线时间254 小时
主题帖子精华
中级会员, 积分 236, 距离下一级还需 264 积分
在线时间0 小时
是因为STM8S&有的版本只有128字节?
目前在玩STM32,BBB,RPi
主题帖子精华
高级会员, 积分 917, 距离下一级还需 83 积分
在线时间28 小时
用过STM8S105c6的EEPROM,按照datasheet推荐步骤操作,没发现什么问题啊,挺好用的
把看到的有意义的例子进行扩充,并将其切实的运用到自己的设计中。
应用确实不容易,水平是在不断的实践中完善和发展的。
主题帖子精华
初级会员, 积分 68, 距离下一级还需 132 积分
在线时间1 小时
SRM8S103配的芯片我用了。。不可以。。是芯片问题估计
主题帖子精华
初级会员, 积分 126, 距离下一级还需 74 积分
在线时间2 小时
你八成用的是stm8s003吧
主题帖子精华
新手上路, 积分 24, 距离下一级还需 26 积分
在线时间0 小时
stm8s003最大到0x407f
主题帖子精华
新手上路, 积分 21, 距离下一级还需 29 积分
在线时间0 小时
楼主您好&&&请问这个问题你解决了没?就是0x4100以上的地址无法存储&&&写的时候地址是对的&&但是一写就写到4000-40FF里面去了
主题帖子精华
初级会员, 积分 117, 距离下一级还需 83 积分
在线时间4 小时
帮顶&.......
做人要出于情,做事要出于心!
主题帖子精华
初级会员, 积分 98, 距离下一级还需 102 积分
在线时间8 小时
学习 学习 现在正在弄保存数据。
Powered by6776人阅读
嵌入式软件(16)
&&& STM8L带有片上EEPROM,常用来保存参数,事实上STM8L整个程序存储区都可以用于作为EEPROM,只是默认情况下被闭了。
&&& 不同型号的STM8L器件其内部默认划分的EEPROM区域都是从0x1000地址开始,以下为STM8LXX的EEPROM读写例:
#define EEPROM_STARTADDR 0x1000
&&&& //EEPROM读数据方法
uint8 EEPROM_Read(uint16 Addr,uint8 *RxBuffer,uint8 Length)
uint16 T=0;
uint8 *EEP;
EEP=(uint8 *)(EEPROM_STARTADDR+Addr);
FLASH_DUKR=0xAE;
FLASH_DUKR=0x56;
FLASH_CR2=0x00;
while((!(FLASH_IAPSR&S3))&(T&0xFFFF))T++;
if(T==0xFFFF)return 0;
while(Length--){
*RxBuffer++=*EEP++;
&&& //EEPROM读数据方法
uint8 EEPROM_Write(uint16 Addr,uint8 *RxBuffer,uint8 Lenth)
uint16 T=0;
uint8 *EEP;
EEP=(uint8 *)(EEPROM_STARTADDR+Addr);
FLASH_DUKR=0xAE;
FLASH_DUKR=0x56;
FLASH_CR2=0x00;
while((!(FLASH_IAPSR&S3))&(T&0xFFFF))T++;
if(T==0xFFFF)return 0;
while(Lenth--){
*EEP++=*RxBuffer++;
while((!(FLASH_IAPSR&S2))&(T&0xFFFF))T++;
if(T==0xFFFF)return 0;
FLASH_IAPSR&=~S3;
&&& STM8LXX核对数据,程序存储器进行统一编址,所以可以直接对EEPROM进行读写,之间需要进行解锁操作,通过FLASH_DUKR完成,写入特定序列的密码即可,由于EEPROM的写入速度较慢,所以需要进行等待,判断其上一步工作是否已完成。实测发现,当CPU主频变化时,其等待时间差别较大,使用时应注意,并且需要加入等待超时处理。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:143901次
积分:1758
积分:1758
排名:第15719名
原创:31篇
转载:11篇
评论:60条
(1)(2)(4)(2)(2)(1)(1)(5)(4)(1)(1)(2)(1)(1)(3)(4)(7)

我要回帖

更多关于 stm8l eeprom读写 的文章

 

随机推荐