胃寒吃什么中成药| 什么里什么间| tony是什么意思| 昏昏欲睡是什么意思| 时隔是什么意思| sanag是什么牌子| 男人脚肿是什么病的前兆| 阴差阳错代表什么生肖| 1940年中国发生了什么| 嘴苦嘴臭什么原因| 下眼袋发青是什么原因| 舌头麻是什么原因| 广角是什么| 藏青色是什么颜色| 人工荨麻疹是什么原因引起的| 于文华朱之文什么关系| 1922年属什么生肖| 迪赛尼斯属于什么档次| 吃什么都是苦的是怎么回事| 手脚发麻是什么病征兆| 吃雪燕有什么好处| 什么蛇可以吃| 三叉神经痛吃什么药效果最好| 高密度脂蛋白是什么| 一个人自言自语的说话是什么病| 稼穑是什么意思| 肠炎吃什么药好得快| 经血是什么血| 踏雪寻梅什么意思| 痛风不能吃什么蔬菜| 煎牛排用什么锅最好| 睡不着有什么好办法吗| 吃布洛芬不能吃什么| 怕老婆的男人说明什么| 梦见彩虹是什么征兆| 荔枝不能和什么同吃| 办护照需要准备什么材料| 六十岁是什么之年| 高血压需要注意些什么| ur是什么| 生酮饮食是什么意思| 鸡蛋饼用什么面粉| 娘娘的意思是什么| 6月15日什么星座| 钟点房是什么意思| none是什么意思| ibm是什么| 嘴角有痣代表什么| 什么天什么什么| blm是什么意思| 眉毛少是什么原因| 补肾壮阳吃什么药好| 万加一笔是什么字| 起死回生是什么生肖| 华为最新款手机是什么型号| 1是什么| 老年人脚肿是什么原因| 青葱岁月是什么意思| 吃糖醋蒜有什么好处和坏处| 牙齿贴面是什么意思| 梦到掉牙齿是什么预兆| 梦到分手了是什么征兆| 手指关节疼痛看什么科| 狰狞什么意思| 1月11日什么星座| 心脏跳的快吃什么药| 夏天都有什么花| 人生的意义到底是什么| 屁股流血是什么原因| 汽车拉缸有什么现象| 意外流产有什么症状| 不时之需是什么意思| 抽脂有什么风险和后遗症| bug是什么意思网络用语| 挖矿是什么| cip是什么意思| 茶寿为什么是108岁| 青鱼吃什么| 面部痉挛是什么原因引起的| 毛主席的女儿为什么姓李| 胃肠镜检查挂什么科| 佛珠什么材质的最好| 单纯疱疹病毒是什么病| 无以回报是什么意思| 虚岁29岁属什么生肖| 月经前长痘痘是什么原因| 喜结连理是什么意思| 脖子上长小肉粒是什么| 只出不进什么意思| 左肾结石的症状是什么| 小肠镜什么情况下需要做| 低钾血症有什么症状| 拔了牙吃什么消炎药| 血小板计数偏高是什么意思| 十二指肠溃疡是什么原因引起的| 耳道炎用什么药最有效| 人流后吃什么补身体| 血滴子是什么| 梦见很多小蛇是什么意思| x58主板配什么cpu| 脸上涂什么可以美白| 什么不什么什么| 孕妇适合喝什么茶| 内心的os是什么意思| 失眠吃什么食物最有效| 什么样的人死后还会出现| 松字五行属什么| 兴奋是什么意思| 经常喝藕粉有什么好处| 吉人自有天相什么意思| 妈妈的姐妹叫什么| 什么是糖皮质激素| 肾最怕什么食物| 化痰止咳吃什么药最好| 吃了避孕药有什么副作用| 空气净化器什么牌子好| 子代表什么意思| 乳糖是什么糖| 什么洗发水去屑好| 慢性胃炎可以吃什么水果| 什么是虚岁| 为什么肚子总是胀胀的| 柿子什么季节成熟| t波改变什么意思| 月经量少吃什么调理最好方法| 哮喘是什么原因引起的| 硬不起来是什么原因| 什么样的莲蓬| 庶子是什么意思| 风林火山是什么意思| 口苦尿黄是什么原因| 青岛为什么叫青岛| 生灵涂炭是什么意思| 猴的守护神是什么菩萨| 菊花有什么颜色| 仙是什么意思| 臭氧有什么作用| hummel是什么牌子| 扎巴依是什么意思| 玉仁玫白膏有什么功效| 痔疮是什么原因| 肠系膜淋巴结炎吃什么药最有效| 地心引力是什么意思| 白球比例偏高说明什么| 红枣有什么功效| pbo是什么| 乳腺增生1类什么意思| 乙丑是什么生肖| 做梦梦见别人怀孕是什么意思| 胸椎退行性变什么意思| 备皮什么意思| 溶媒是什么| 长智齿牙龈肿痛吃什么药| 8月14日是什么星座| 初级会计考什么科目| 大力出奇迹什么意思| 看见蜈蚣有什么预兆| 恩字五行属什么| 降肝火喝什么茶| prada是什么档次| 女人喜欢什么姿势| cm代表什么单位| 中药用什么锅熬效果最佳| 茄子有什么营养| 申属于五行属什么| 前列腺用什么药| 狗哭了代表什么预兆| 长一智的上一句是什么| 转氨酶偏高是什么意思| 一夫一妻制产生于什么时期| 急性肠胃炎吃什么食物| 减肥期间可以喝什么饮料| 炎症是什么意思| 什么是幽门螺杆菌感染| 周围神经病是什么症状| 男生第一次什么感觉| 春天的雨是什么| chanel什么牌子| o型血和ab型血生的孩子是什么血型| 去香港自由行要办什么手续| 鹦鹉能吃什么水果| 肾衰透析病人吃什么好| 低频是什么意思| 什么是假性抑郁症| 咽口水喉咙痛吃什么药| sca是什么意思| 麦冬不能和什么一起吃| 薏苡仁是什么| 吃杏仁有什么好处| 文员是什么| 雅号是什么意思| 作壁上观是什么生肖| 舌尖发麻是什么原因引起的| 舌头短是什么原因| 乜贴是什么意思| 刷牙时牙酸是什么原因| 脑溢血是什么原因引起的| 儿童办理护照需要什么材料| doro什么意思| 什么样的升旗仪式| 萌是什么意思| 煮毛豆放什么调料好吃| 梦到认识的人死了是什么意思| 小葱拌豆腐的下一句是什么| 取什么网名好听| 995是什么意思| 巴宝莉是什么牌子| 早上起来腰疼是什么原因| 什么人生病不看医生| 南京为什么叫金陵| 什么去甲醛最快有效| 罕见是什么意思| 空调开什么模式最凉快| 腰间盘挂什么科| 土中金是什么生肖| 碳水化合物是什么东西| 1月12号是什么星座| 野趣是什么意思| 挂科什么意思| 预警是什么意思| 日本为什么侵略中国| 专案组是什么意思| 农历七月初五是什么星座| 男人为什么喜欢吸奶| 交接是什么意思| 水痘疫苗叫什么| 半夜呕吐是什么原因| 糖尿病吃什么水果比较好| 附件炎吃什么药最好| 梅子是什么水果| 927是什么意思| 彼岸花代表什么星座| 胃胀是什么原因| 0是什么意思网络语言| 叶酸是什么维生素| 姜为什么不能晚上吃| 什么叫人| 红参和人参有什么区别| 心血虚吃什么中成药| 联票是什么意思| 鸡爪烧什么好吃| 血压低吃什么补得最快| 梦见喝酒是什么意思| 皮肤过敏挂什么科| 医院附近适合做什么生意| 弱碱水是什么水| 右眼皮跳是什么预兆女| 离岸人民币什么意思| her什么意思| 三月是什么季节| 蓝色加红色等于什么颜色| 小米是什么| 皮实是什么意思| 什么原因引起耳鸣| 爱做梦是什么原因| 福尔马林是什么味道| 蝴蝶兰什么时候开花| jealousy是什么意思| 蒙古族信仰什么教| 小孩有点咳嗽吃什么药| 胃发炎吃什么药好得快| 什么眉什么目| as是什么病| 什么是红斑狼疮病| 百度
打印
[其他ST产品]

杨秀萍秘书长会见澳特区政府新闻局代理局长黄乐宜

[复制链接]
2451|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
第二十章 NOR Flash实验

本章将介绍如何使用Kendryte K210SPI功能,并实现对外部Flash读写并把结果显示在TFTLCD模块上。通过学习本章内容,读者将掌握利用SDK编程技术实现外部Flash的读写方法。
本章分为如下几个小节:
20.1SPI和NOR Flash芯片简介
20.2 硬件设计
20.3 程序设计
20.4 运行验证


20.1 SPINOR Flash简介
20.1.1 SPI简介
有关Kendryte K210的SPI模块介绍,请见第16.1.1小节《SPI简介》。
20.1.2 NOR Flash简介20.1.2.1 Flash简介
Flash是常见的用于存储数据的半导器件它具有容量、可重复擦写、按“扇区/块”擦除、掉电后数据继续保存的特性。常见的Flash主要有NOR FlashNand Flash两种类型,它们的特性如表20.1.2.1.1所。NORNAND两种数门电路,可以简单地认为Flash内部存储单元使哪种门作存储单元就是哪类型的FlashU盘,SSDeMMC等为NAND型NOR Flash则根据设计需要灵活应用于各类PCBBIOS手机等。
特性
NOR FLASH
NAND FLASH
容量
同容量存储器成本
较贵
较便宜
擦除单元
“扇区/”擦除
“扇区/”擦除
读写单元
可以基于字节读写
必须以“块”为单位读写
读取速度
较高
较低
写入速度
较低
较高
集成度
较低
较高
介质类型
随机存储
连续存储
地址线和数据线
独立分开
共用
坏块
较少
较多
是否支持XIP
支持
不支持
表20.1.2.1.1 NOR FlashNAND Flash特性对比
NORNAND在数据写入前都需要有擦除操作,但实际上NOR Flash的一个bit可以从1变成0,而要从01就要擦除后再写入NAND Flash这两种情况都需要擦除。擦除操作的最小单位“扇区/块”,这意着有时候即使只一字节的数据,这个“扇区/块”上之前的数据都可能会被擦除
NOR的地址线和数据线分开,它可以按“字节”读写数据,符合CPU的指令译码执行要求,所以假如NOR上存储了代码指令,CPUNOR一个地址,NOR就能向CPU返回一个数据让CPU执行,中间不需要额外的处理操作,这体现于表20.1.2.1.1中的支持XIP特性(eXecute In Place)。因此可以用NOR Flash直接作为嵌入式MCU程序存储空间。
NAND的数据和地址线共用,只能按“块”来读写数据,假如NAND上存储了代码指令,CPUNAND地址后,它无法直接返回该地址的数据,所以不符合指令译码要求。
若代码存储在NAND上,可以把它先加载到RAM存储器上,再由CPU执行。所以在功能上可以认为NOR是一种断电后数据不丢失的RAM,但它的擦除单位与RAM有区别,且读写速度比RAM要慢得多。
Flash有对应的缺点,我使用过程中需要尽量去规避这些问题:Flash使用寿命,一个是可能的位反转。
使用寿命体现在读写上是Flash的擦除次数都是有限的(NOR Flash普遍是10万次左右),当它的使用接近寿命的时候,可能会出现写操作失败。由于NAND通常是整块擦写,块内有一位失效整个块就会失效,这被称为坏块。使NAND Flash最好通过算法扫描介质找出坏块并标为不可用,因为坏块上的数据是不准确的。
反转是数据位写入1但经过一定时间的环境变化后可能实际变为0情况亦然。位反转的原因很多,可能是器件特性也可能与环境干扰有关,由于位反转问题可能存在,所以FLASH存储器需要“探测/错误更正(EDC/ECC)”算法来确保数据的正确性。
FLASH芯片有很多种芯片型号,比如有:W25Q128BY25Q128NM25Q128,它们是来自不同的厂商的同种规格的NOR Flash芯片,内存空间都是128M字,即16M字节。它们的很多参数、操作都是一样的。
下面我们以W25Q128为例,认识一下具体NOR Flash的特性。
W25Q128是一款大容量SPI Flash产品,其容量为16M。它将16M字节的容量分为256个块(Block),每个块大小为64K字节,每个块又分为16个扇区(Sector),每一个扇区16页,每页256个字节,即每个扇区4K个字节。W25Q128的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。这样我们需要给W25Q128开辟一个至少4K的缓存区,这样对SRAM要求比较高,要求芯片必须有4K以上SRAM才能很好的操作。
W25Q128的擦写周期多达10W次,具有20年的数据保存期限,支持电压为2.7~3.6VW25Q128支持标准的SPI,还支持双输出/四输出的SPI,最大SPI时钟可以到104Mhz(双输出时相当于208Mhz,四输出时相当于280M)。
下面我们看一下W25Q128芯片的管脚图,如图20.1.2.1.1所示。
20.1.2.1.1 W25Q128芯片引脚图
芯片引脚连接如下:CS即片选信号输入,低电平有效;DO是MISO引脚,CLK管脚的下降沿输出数据WP是写保护管脚,高电平可读可写,低电平仅仅可读DIMOSI引脚,主机发送的数据、地址和命令从SI引脚输入到芯片内部,在CLK管脚的上升沿捕获数据CLK是串行时钟引脚,为输入输出提供时钟脉冲;HOLD是保持管脚,低电平有效
Kendryte K210通过SPI总线连接到W25Q128对应的引脚即可启动数据传输。
20.1.2.2 NOR Flash工作时序
前面对于W25Q128的介绍中也提及其存储的体系,W25Q128有写入、读取还有擦除的功能,下面就对这三种操作的时序进行分析,在后面通过代码的形式驱动它。
下面先让我们看一下读操作时序,如图20.1.2.2.1所示:
图20.1.2.2.1 W25Q128读操作时序图
从上图可知读数据指令是03H,可以读出一个字节或者多个字节。发起读操作时,先把CS片选管脚拉低,然后通过MOSI引脚把03H发送芯片,之后再发送要读取的24位地址,这些数据在CLK上升沿时采样。芯片接收完24位地址之后,就会把相对应地址的数据在CLK引脚下降沿从MISO引脚发送出去。从图中可以看出只要CLK一直在工作,那么通过一条读指令就可以把整个芯片存储区的数据读出来。当主机把CS引脚拉高,数据传输停止。
接着我们看一下写时序,这里我们先看页写时序,如图20.1.2.2.2所示:
图20.1.2.2.2 W25Q128页写时序
在发送页写指令之前,需要先发送“写使能”指令。然后主机拉低CS引脚,然后通过MOSI引脚把02H发送到芯片,接着发送24位地址,最后你就可以发送你需要写的字节数据到芯片。完成数据写入之后,需要拉高CS引脚,停止数据传输。
下面介绍一下扇区擦除时序,如图20.1.2.2.3所示:
图20.1.2.2.3 扇区擦除时序图
扇区擦除指的是将一个扇区擦除,通过前面的介绍也知道,W25Q128的扇区大小是4K字节。擦除扇区后,扇区的位全置1,即扇区字节为FFh。同样的,在执行扇区擦除之前,需要先执行写使能指令。这里需要注意的是当前SPI总线的状态,假如总线状态是BUSY,那么这个扇区擦除是无效的,所以在拉低CS引脚准备发送数据前,需要先要确定SPI总线的状态,这就需要执行读状态寄存器指令,读取状态寄存器的BUSY位,需要等待BUSY位为0,才可以执行擦除工作。
接着按时序图分析,主机先拉低CS引脚,然后通过MOSI引脚发送指令代码20h到芯片,然后接着把24位扇区地址发送到芯片,然后需要拉高CS引脚,通过读取寄存器状态等待扇区擦除操作完成。
此外还有对整个芯片进行擦除的操作,时序比扇区擦除更加简单,不用发送24bit地址,只需要发送指令代码C7h到芯片即可实现芯片的擦除。
在W25Q128手册中还有许多种方式的读//擦除操作,我们这里只分析本实验用到的,其他大家可以参考W25Q128手册,存放路径Aà硬件资料à芯片资料。
20.2 硬件设计
20.2.1 例程功能
1. 通过KEY1按键来控制NOR Flash的写入,通过按键KEY0来控制NOR Flash的读取。并在LCD模块上显示相关信息。
20.2.2 硬件资源
1. 独立按键
        KEY0按键 - IO18
        KEY1按键 - IO19
        KEY2按键 - IO16
2. NOR Flash
        CS - F_CS
        SO - F_D1
        WP - F_D2
SI - F_D0
        CLK - F_CLK
        HOLP - F_D3
3. LCD
        LCD_RD - IO34
        LCD_BL - IO35
        LCD_CS - IO36
        LCD_RST - IO37
        LCD_RS - IO38
        LCD_WR - IO39
        LCD_D0~LCD_D7 - SPI0_D0~SPI0_D7
20.2.3 原理图
本章实验内容,需要使用到板载的W25Q128,正点原子DNK210开发板上的NOR Flash连接原理图,如下图所示:
20.2.3.1 ATK-MC2640 NOR Flash接口原理图
20.3 程序设计
20.3.1 NOR Flash驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。NOR Flash驱动源码包括四个文件:w25qxx.c、w25qxx.h、norflash.cnorflash.h。这四个文件可以做个简单的区分,w25qxx.cw25qxx.h文件来源于官方的SDK裸机编程DEMO,用于NOR Flash的底层驱动,norflash.cnorflash.h文件是由正点原子团队为了符合我们的代码规范而编写,提供函数接口方便外部FLASH的读写和擦除等。我们这里主要介绍norflash.cnorflash.h文件的函数。
下面介绍norflash.c文件几个重要的函数,首先是NOR Flash初始化函数,其定义如下:
/**
* @brief       初始化NOR FLASH
* @param      
* @retval      0:成功  1:失败
*/
void norflash_init(void)
{
    uint8_t manuf_id, device_id;
    uint8_t spi_index = 3, spi_ss = 0;
    w25qxx_init(spi_index, spi_ss);
    w25qxx_enable_quad_mode();   /* flash 四倍模式开启*/
    /* 读取flashID */
    norflash_read_id(&manuf_id, &device_id);
    printf("manuf_id:0x%02x, device_id:0x%02x\r\n", manuf_id, device_id);
    if ((manuf_id != 0xEF && manuf_id != 0xC8) || (device_id != 0x17 && device_id != 0x16))
    {
        /* flash初始化失败 */
        printf("w25qxx_read_id error\n");
        printf("manuf_id:0x%02x, device_id:0x%02x\r\n", manuf_id, device_id);
        return 0;
    }
    else
    {
        return 1;
    }
}
在初始化函数中,首先定义变量manuf_id和device_id,分别用于存放NOR Flash的厂家ID和芯片ID,然后选择SPI总线和设备号初始化W25Q128,使能SPI四线模式,最后调用norflash_read_id函数读取厂家ID和设备ID判断W25Q128是否初始化成功,W25Q128的厂家ID0XEF,设备ID0X17,读取成功函数返回0
下面介绍一下FLASH读取函数,其定义如下:
/**
* @brief       读取SPI FLASH
*   @NOTE      在指定地址开始读取指定长度的数据
* @param       pbuf    : 数据存储区
* @param       addr    : 开始读取的地址
* @param       datalen : 要读取的字节数
* @retval      
*/
void norflash_read(uint8_t *pbuf, uint32_t addr, uint32_t datalen)
{
    /* norflash读取数据 */
    w25qxx_read_data(addr, pbuf, datalen, W25QXX_QUAD_FAST);
}
该函数直接调用w25qxx_read_data函数实现,大家可以访问到w25qxx.c文件的_w25qxx_read_data函数,这里可以根据前面的时序图对照理解。
有读函数,那肯定就有写函数,接下来我们介绍一下NOR FLASH写函数,其定义如下:
/**
* @brief       SPI FLASH
*   @note      在指定地址开始写入指定长度的数据 , 该函数带擦除操作!
*              SPI FLASH 一般是: 256个字节为一个Page, 4Kbytes为一个Sector, 16个扇区为1Block
*              擦除的最小单位为Sector.
*
* @param       pbuf    : 数据存储区
* @param       addr    : 开始写入的地址
* @param       datalen : 要写入的字节数
* @retval      
*/
void norflash_write(uint8_t *pbuf, uint32_t addr, uint32_t datalen)
{
    w25qxx_write_data(addr, pbuf, datalen);
}
该函数直接调用w25qxx_write_data函数实现,我们在w25qxx.c文件找到w25qxx_write_data函数,其代码如下所示。
w25qxx_status_t w25qxx_write_data(uint32_t addr, uint8_t *data_buf, uint32_t length)
{
    uint32_t sector_addr = 0;
    uint32_t sector_offset = 0;
    uint32_t sector_remain = 0;
    uint32_t write_len = 0;
    uint32_t index = 0;
    uint8_t *pread = NULL;
    uint8_t *pwrite = NULL;
    uint8_t swap_buf[w25qxx_FLASH_SECTOR_SIZE] = {0};
    while (length)
    {
        sector_addr = addr & (~(w25qxx_FLASH_SECTOR_SIZE - 1));
        sector_offset = addr & (w25qxx_FLASH_SECTOR_SIZE - 1);
        sector_remain = w25qxx_FLASH_SECTOR_SIZE - sector_offset;
        write_len = ((length < sector_remain) ? length : sector_remain);
        w25qxx_read_data(sector_addr, swap_buf, w25qxx_FLASH_SECTOR_SIZE);
        pread = swap_buf + sector_offset;
        pwrite = data_buf;
        for (index = 0; index < write_len; index++)
        {
            if ((*pwrite) != ((*pwrite) & (*pread)))
            {
                w25qxx_sector_erase(sector_addr);
                while (w25qxx_is_busy() == W25QXX_BUSY)
                    ;
                break;
            }
            pwrite++;
            pread++;
        }
        if (write_len == w25qxx_FLASH_SECTOR_SIZE)
        {
            w25qxx_sector_program(sector_addr, data_buf);
        }
        else
        {
            pread = swap_buf + sector_offset;
            pwrite = data_buf;
            for (index = 0; index < write_len; index++)
                *pread++ = *pwrite++;
            w25qxx_sector_program(sector_addr, swap_buf);
        }
        length -= write_len;
        addr += write_len;
        data_buf += write_len;
    }
    return W25QXX_OK;
}
该函数可以在NOR Flash的任意地址开始写入任意长度(必须不超过NOR Flash的容量)的数据。我们这里简单介绍一下思路:先获得首地址(addr)所在的扇区,并计算在扇区内的偏移,然后判断要写入的数据长度是否超过本扇区所剩下的长度,如果不超过,则读出整个扇区,在偏移处开始写入指定长度的数据,然后擦除这个扇区,再一次性写入。当所需要写入的数据长度超过一个扇区的长度的时候,我们先按照前面的步骤把扇区剩余部分写完,再在新扇区内执行同样的操作,如此循环,直到写入结束。这里我们还定义了一个swap_buf的数组,用于擦除时缓存扇区内的数据。
下面简单介绍一下擦除函数,前面工作时序中也有对此描述,现在就来看一下代码:
/**
* @brief       擦除整个芯片
*   @note      等待时间超长...
* @param      
* @retval      
*/
void norflash_erase_chip(void)
{
    w25qxx_chip_erase();
}
/**
* @brief       擦除一个扇区
*   @note      注意,这里是扇区地址,不是字节地址!!
*
* @param       saddr : 扇区地址 根据实际容量设置
* @retval      
*/
void norflash_erase_sector(uint32_t saddr)
{
    //printf("fe:%x\r\n", saddr);   /* 监视falsh擦除情况,测试用 */
    w25qxx_sector_erase(saddr);
}
该代码也是老套路,直接调用对应的函数实现擦除功能,norflash_erase_chip函数是整片擦除,所需时间较长,norflash_erase_sector函数是按扇区擦除。需要注意的是假如调用了norflash_erase_chip函数将会对整个NOR Flash进行擦除,一般情况不建议对整个NOR Flash进行擦除,因为Kendryte K210的程序存储在NOR Flash上,整片擦除会导致程序全部丢失
20.3.2 main.c代码
main.c中的代码如下所示:
/* 要写入到FLASH的字符串数组 */
const uint8_t g_text_buf[] = {"NORFLASH TEST"};
#define LCD_SPI_CLK_RATE 15000000
#define TEXT_SIZE   sizeof(g_text_buf) + 4      /* TEXT字符串长度 */
#define DATA_ADDRESS 0xB00000                   /* 读写地址 */
int main(void)
{
    uint8_t key;
    uint8_t i = 0;
    uint8_t datatemp[TEXT_SIZE];
    sysctl_pll_set_freq(SYSCTL_PLL0, 800000000);
    sysctl_pll_set_freq(SYSCTL_PLL1, 400000000);
    sysctl_pll_set_freq(SYSCTL_PLL2, 45158400);
    sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
    sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18);
    sysctl_set_spi0_dvp_data(1);
    lcd_init();                             /* 初始化LCD */
    lcd_set_direction(DIR_YX_LRUD);
    key_init();                             /* 初始化按键 */
    norflash_init();                        /* 初始化NORFLASH */
    lcd_draw_string(10, 10, "KEY1:Write  KEY0:Read", RED); /* 显示提示信息 */
    lcd_draw_string(10, 30, "SPI FLASH Ready!", BLUE);
    while (1)
    {
        key = key_scan(0);
        if (key == KEY1_PRES)   /* KEY1按下,写入 */
        {
            lcd_draw_fill_rectangle(0, 50, 319, 90, WHITE);         /* 清除显示 */
            lcd_draw_string(10, 50, "Start Write FLASH.", BLUE);
            sprintf((char *)datatemp, "%s%d", (char *)g_text_buf, i);
            norflash_write((uint8_t *)datatemp, DATA_ADDRESS, TEXT_SIZE);
            lcd_draw_fill_rectangle(10, 50, 319, 70, WHITE);        /* 清除显示 */
            lcd_draw_string(10, 50, "FLASH Write Finished!", BLUE);
        }
        else if (key == KEY0_PRES)   /* KEY0按下,读取字符串并显示 */
        {
            lcd_draw_fill_rectangle(10, 50, 319, 90, WHITE);     /* 清除显示 */
            lcd_draw_string(10, 50, "Start Read FLASH.", BLUE);
            norflash_read(datatemp, DATA_ADDRESS, TEXT_SIZE);      
            lcd_draw_fill_rectangle(10, 50, 319, 70, WHITE);       /* 清除显示 */
            lcd_draw_string(10, 50, "The Data Readed Is:   ", BLUE);
            lcd_draw_string(10, 70, (char *)datatemp, BLUE);   
        }
        i++;
        if (i > 200)
        {
            i = 0;
        }
        
        msleep(10);
    }
}
main函数前面,我们定义了g_text_buf数组,用于存放要写入到FLASH的字符串。main函数代码具体流程大致是:首先完成系统级和按键、LCD、NOR Flash初始化工作,然后提醒交互信息,最后通过KEY0去读取地址DATA_ADDRESS处开始的数据并把数据显示在LCD上;另外还可以通过KEY1在地址DATA_ADDRESS处写入g_text_buf数据并在LCD界面中显示传输中,完成后并显示“FLASH Write Finished!”。
20.4 运行验证
DNK210开发板连接到电脑主机,通过VSCode将固件烧录到开发板中,可以看到LCD显示信息,LCD显示的内容如图20.4.1所示:
图20.4.1 SPI实验程序运行效果图
通过先按下KEY1写入数据,然后再按KEY0读取数据,得到如图20.4.2所示:
图20.4.2 操作后的显示效果图

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

本版积分规则

125

主题

126

帖子

3

粉丝
复方北豆根氨酚那敏片是什么药 脚心发麻是什么原因引起的 五花肉炒什么配菜好吃 十八层地狱分别叫什么 头晕是什么引起的
chick什么意思 眼睛凹陷是什么原因 软柿子是什么意思 专科警校出来干什么 天蝎女和什么座最配
身首异处是什么意思 opt是什么 月亮杯是什么东西 失心疯是什么意思 什么是基本养老金
眼花是什么原因 三情六欲是什么意思 矿物油是什么 中位生存期什么意思 抗战纪念日为什么是9月3日
现在摆摊卖什么东西最好卖hcv9jop5ns6r.cn 坐月子送什么礼物好hcv9jop1ns2r.cn 91视频是什么hcv8jop0ns1r.cn 脑白质脱髓鞘改变是什么意思hcv9jop5ns2r.cn 残留是什么意思luyiluode.com
不显怀的人有什么特点hcv8jop0ns5r.cn 打飞机是什么shenchushe.com 崽崽是什么意思hcv9jop5ns7r.cn 建档立卡是什么hcv8jop8ns5r.cn 部分导联t波改变是什么意思helloaicloud.com
梅毒通过什么途径传染hcv8jop0ns6r.cn 生地和熟地有什么区别hcv9jop3ns1r.cn 甘油三酯偏高有什么危害hcv8jop3ns0r.cn 茅台酒为什么这么贵dajiketang.com 喝可乐有什么好处hcv8jop9ns6r.cn
结膜充血用什么眼药水hcv9jop5ns1r.cn 淘米水洗脸有什么作用与功效huizhijixie.com 一九六三年属什么生肖hcv7jop6ns2r.cn gsp全称是什么hcv9jop6ns5r.cn 肆无忌惮的意思是什么hcv8jop9ns6r.cn
百度