通过对stm32内部的flash的读写可以实现对stm32的编程操作。
stm32 的内置可编程Flash在许多场合具有十分重要的意义。如其支持ICP特性使得开发人员对stm32可以警醒调试开发,可以通过JTAG和SWD接口对stm32进行程序烧写;支持IAP特性使得开发人员可以在stm32运行程序的时候对其内部程序进行更新操作。对一些对数据安全有要求的场合,可编程FLASH可以结合stm32内部唯一的身份标识实现各种各样的防破解方案。并且stm32的FLASH在一些轻量级的防掉电存储方案中也有立足之地。
stm32的FLASH分为主存储块和信息块。主存储块用于保存具体的程序代码和用户数据,信息块用于负责由stm32出厂是放置2KB的启动程序(Bootloader)和512B的用户配置信息区。
主存储块是以页为单位划分的,一页大小为1KB。范围为从地址0x08000000开始的128KB内。
对Flash 的写入操作要 “先擦除后写入”的原则;
stm32的内置flash 编程操作都是以页为单位写入的,而写入的操作必须要以16位半字宽度数据位单位,允许跨页写,写入非16位数据时将导致stm32内部总线错误。
进行内置flash读写时,必须要打开内部Rc振荡器。
main.c:
001 | #include "stm32f10x.h" |
002 | #include "stdio.h" |
003 |
004 | #define PRINTF_ON 1 |
005 |
006 | void RCC_Configuration(void); |
007 | void GPIO_Configuration(void); |
008 | void USART_Configuration(void); |
009 |
010 | u32 count=0; |
011 |
012 | u16 data[5]={0x0001,0x0002,0x0003,0x0004,0x0005}; |
013 |
014 | int main(void) |
015 | { |
016 | RCC_Configuration(); |
017 | GPIO_Configuration(); |
018 | USART_Configuration(); |
019 |
020 | RCC_HSICmd(ENABLE); |
021 |
022 | FLASH_Unlock(); |
023 |
024 | FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR); |
025 |
026 | FLASH_ErasePage(0x8002000); |
027 |
028 | while(count < 5) |
029 | { |
030 | FLASH_ProgramHalfWord((0x8002000 +count*2),data[count]); //flash 为一个字节存储,16位数据必须地址加2 |
031 |
032 | count++; |
033 |
034 | } |
035 |
036 | FLASH_Lock(); |
037 |
038 | count = 0; |
039 |
040 | printf("\r\n The Five Data Is : \r\n"); |
041 |
042 | while(count < 5) |
043 | { |
044 |
045 | printf("\r %d \r",*(u8 *)(0x8002000 + count*2)); //读取方法 |
046 |
047 | count++; |
048 |
049 |
050 | } |
051 |
052 | while(1); |
053 |
054 | } |
055 |
056 | void GPIO_Configuration(void) |
057 | { |
058 | GPIO_InitTypeDef GPIO_InitStructure; |
059 |
060 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
061 |
062 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; |
063 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
064 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
065 |
066 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; |
067 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
068 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
069 | } |
070 |
071 | void RCC_Configuration(void) |
072 | { |
073 | /* 定义枚举类型变量 HSEStartUpStatus */ |
074 | ErrorStatus HSEStartUpStatus; |
075 |
076 | /* 复位系统时钟设置*/ |
077 | RCC_DeInit(); |
078 | /* 开启HSE*/ |
079 | RCC_HSEConfig(RCC_HSE_ON); |
080 | /* 等待HSE起振并稳定*/ |
081 | HSEStartUpStatus = RCC_WaitForHSEStartUp(); |
082 | /* 判断HSE起是否振成功,是则进入if()内部 */ |
083 | if(HSEStartUpStatus == SUCCESS) |
084 | { |
085 | /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */ |
086 | RCC_HCLKConfig(RCC_SYSCLK_Div1); |
087 | /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */ |
088 | RCC_PCLK2Config(RCC_HCLK_Div1); |
089 | /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */ |
090 | RCC_PCLK1Config(RCC_HCLK_Div2); |
091 | /* 设置FLASH延时周期数为2 */ |
092 | FLASH_SetLatency(FLASH_Latency_2); |
093 | /* 使能FLASH预取缓存 */ |
094 | FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); |
095 | /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */ |
096 | RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); |
097 | /* 使能PLL */ |
098 | RCC_PLLCmd(ENABLE); |
099 | /* 等待PLL输出稳定 */ |
100 | while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); |
101 | /* 选择SYSCLK时钟源为PLL */ |
102 | RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); |
103 | /* 等待PLL成为SYSCLK时钟源 */ |
104 | while(RCC_GetSYSCLKSource() != 0x08); |
105 | } |
106 | /* 打开APB2总线上的GPIOA时钟*/ |
107 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); |
108 |
109 | //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); |
110 |
111 | //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); |
112 | //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE); |
113 |
114 | } |
115 |
116 |
117 | void USART_Configuration(void) |
118 | { |
119 | USART_InitTypeDef USART_InitStructure; |
120 | USART_ClockInitTypeDef USART_ClockInitStructure; |
121 |
122 | USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; |
123 | USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; |
124 | USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; |
125 | USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; |
126 | USART_ClockInit(USART1 , &USART_ClockInitStructure); |
127 |
128 | USART_InitStructure.USART_BaudRate = 9600; |
129 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; |
130 | USART_InitStructure.USART_StopBits = USART_StopBits_1; |
131 | USART_InitStructure.USART_Parity = USART_Parity_No; |
132 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |
133 | USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; |
134 | USART_Init(USART1,&USART_InitStructure); |
135 |
136 | USART_Cmd(USART1,ENABLE); |
137 | } |
138 |
139 | #if PRINTF_ON |
140 |
141 | int fputc(int ch,FILE *f) |
142 | { |
143 | USART_SendData(USART1,(u8) ch); |
144 | while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); |
145 | return ch; |
146 | } |
147 |
148 | #endif |
上一篇:STM32学习笔记(6):LCD的显示
下一篇:keil软件的安装和破解(STM32和C51都可使用)
推荐阅读
史海拾趣
随着产品线的不断丰富和技术实力的提升,ATOP Technologies开始将目光投向更广阔的市场。公司积极参与国内外各类行业展会和交流活动,加强与同行和客户的交流与合作。同时,ATOP Technologies还积极开展国际合作,与多个国家的知名企业建立了战略合作关系,共同推动工业自动化领域的发展。
随着电子行业的快速发展,许多电子产品型号逐渐停产或变得稀缺。ASI敏锐地捕捉到了这一市场变化,并开始专注于生产停产及稀缺元器件的替代或新设计。其RF功率晶体管生产线主要提供Motorola、Philips及SGS Thomson公司的替代型号,而微波二极管生产线则主要提供HP、M/A-COM、Alpha及Loral/Frequency sources公司的替代型号。这一策略不仅满足了市场的需求,还进一步巩固了ASI在行业中的地位。
随着集成电路技术的快速发展,对先进IC供电的需求日益增长。为了应对这一挑战,CUI Inc.推出了90A数字负载点模块系列。这些模块采用先进的封装技术和设计,具有高电流输出和优异的性能表现。它们的推出不仅满足了客户对高效、可靠供电的需求,还进一步提升了CUI在电源领域的竞争力。
在追求持续增长的道路上,CUI Inc.采取了一项重要举措——收购加拿大电源制造商Tectrol Inc.。这次收购为CUI带来了丰富的产品线和技术资源,尤其是Tectrol在标准和定制电源解决方案方面的领先设计能力和制造能力。通过整合Tectrol的技术和资源,CUI进一步巩固了其在电源设计领域的领先地位,并为其未来的发展奠定了坚实的基础。
CUI Inc.一直坚信,与客户的紧密合作是其成功的关键。因此,公司始终致力于与客户发展协作性伙伴关系。通过深入了解客户的需求和反馈,CUI不断优化其产品和服务,以满足客户的期望。这种以客户为中心的经营理念不仅赢得了客户的忠诚和支持,还为CUI带来了持续的业务增长和市场份额的扩大。
这些故事只是CUI Inc.在电子行业中发展起来的一部分可能情况。实际上,CUI的发展可能涉及更多的战略决策、市场变化和技术突破。如果需要更具体、详细的故事,建议查阅相关的行业报告、公司年报或新闻资讯。
CUI Inc.一直坚信,与客户的紧密合作是其成功的关键。因此,公司始终致力于与客户发展协作性伙伴关系。通过深入了解客户的需求和反馈,CUI不断优化其产品和服务,以满足客户的期望。这种以客户为中心的经营理念不仅赢得了客户的忠诚和支持,还为CUI带来了持续的业务增长和市场份额的扩大。
这些故事只是CUI Inc.在电子行业中发展起来的一部分可能情况。实际上,CUI的发展可能涉及更多的战略决策、市场变化和技术突破。如果需要更具体、详细的故事,建议查阅相关的行业报告、公司年报或新闻资讯。
从8位/16位单片机发展到以ARM CPU核为代表的32位嵌入式处理器,嵌入式操作系统将替代传统的由手工编制的监控程序或调度程序,成为重要的基础组件。更重要的是嵌入式操作系统对应用程序可以起到屏蔽的作用,使应用程序员面向操作系统级开发应用软件 ...… 查看全部问答∨ |
1 SmartBits600仪表使用... 5 1.1 仪表概述.. 5 1.2 Smartbits600 面板介绍.. 5 1.2.1 Smartbits600前视图.. 5 1.2.2 Smartibits600后视图.. 6 1.3 Smartbits600基本操作.. 6 1.3.1 SmartBits的IP地址配置方法.. 6 1.3 ...… 查看全部问答∨ |
该系列文章讲述了电源部分去耦和旁路电容的设计原则。文中涉及了电容的选取,布局布线和仿真。本文为第一部分,讲述了电压调整器供电部分和旁路电容的交感,另外,还对电路总的阻抗,包括集成电路芯片、电容、PCB布线和电压调整器的阻抗进行了评估 ...… 查看全部问答∨ |
也是看了坛子里David_Lee的帖子: https://bbs.eeworld.com.cn/thread-95249-1-1.html 感慨颇多,当自己啥都半懂不懂的时候,就莽莽撞撞地做了第一个电子制作,也许,这个制作并不像想象中那么完美,也许,这个制作工作一天之后就被你扔到了物料堆 ...… 查看全部问答∨ |
#include"reg51.h" #include"absacc.h" #define ad_run XBYTE[0x7fff] #define ad_read XBYTE[0xbfff] #define uchar unsigned char uchar ad[5]; uchar A; uchar i; bit error; main() { ...… 查看全部问答∨ |
TI 德州仪器 白光LED驱动器 TPS60250 具有 I2C 接口的用于 7 个 WLED 的1.2A 高功率高效充电泵TPS60251 具有 I2C 接口的用于 7 个 WLED 的1.2A 高功率高效充电泵TPS60252 ...… 查看全部问答∨ |
搞死了,ZE的FSMC接8位TFT屏,信号都有了,屏幕就是不显示。 在SRAM_TEST的基础上修改的,FSMC_SRAM.C 与 LCD的基本函数如下,求救。。/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************* File Name &n ...… 查看全部问答∨ |
|
怎么在ccs中看某段代码的运行时间?我在网上找到一个ccs的教程说有个工具栏的时钟按钮可以用来查看代码执行时间,但是我一直没找到。 不知哪位高手知道怎么查看代码执行时间?… 查看全部问答∨ |
RT,这个官方下载的LCD Drive程序的作用是什么?怎么我写进开发板后,LCD屏幕一直闪烁,是这个效果么?另外,我写入demo程序后,屏幕一直白屏。前两天还好好的,昨天突然就无法显示了,直接白屏,是硬件上出了问题吗?… 查看全部问答∨ |