FLASH应用程序用户数据

python爬取flash页面的返回数据(flex技术、amf格式、charles抓包) flash页面的返回数据,无法从网页源代码中查看到数据,这种页面的爬取需要借助一个工具——charles,通过它来查看amf。 这里用到一个第三方库pyamf,安装方式: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple py3amf 本文以浙江省地表水水质自动监测数据为例,爬取浙江省所有监测点的五项水质信息,讲述这种传统flash页面数据的爬取过程和注意事项。 一、分析网页 浏览器查看 下面是这个网站的页面和源代码(注意圈出来的部分): 浏 阅读详情

本文写的十分草率,许多我自创的函数未做解释。等整个项目完成,我会慢慢整理资料。。。

另外,本文所提供代码已经过改正,经过验证,请放心使用。

建议波特率不要太高,传数据时加上校验,实测1152000的波特率会造成部分乱码

一、大概实现

大致思路:在flash8M内存的高位划分出4k大小的若干块,每个应用程序占有最多4K的数据,在应用启动时读取数据,在应用结束时擦除这4K的flash并重新写入数据。

例如:

注:Fls_Get函数是从flash中读取数据

函数原型:Fls_Get(uint32_t addr, void* buff, uint32_t cnt)

Fls_Set是写入数据

#ifndef DATA_DINO_H
#define DATA_DINO_H



#include "TableAddress.h"
#include "Table.h"



//用户数据
uint8_t historyScore[100];


void dino_loadconf(void)
{
    //读取数据
    Fls_Get(DATA_DINO+0, historyScore, 100)
}


void dino_saveconf(void)
{
    //保存数据
    W25Q64_SectorErase(DATA_DINO)
    Fls_Set(DATA_DINO+0, historyScore, 100)
}


#endif

TableAddress是所有资源文件在flash中的地址索引(当然也包括这4K的用户数据),只有一个变量时当然好办,直接从首地址开读即可,但是有多个变量时还得考虑变量的存储顺序、字节偏移等问题。 于是这个代码可能变成了这样

#ifndef DATA_SYSTEM_H
#define DATA_SYSTEM_H



#include "TableAddress.h"
#include "Table.h"



//用户数据
uint8_t animaionFadeTime = 10;
uint8_t alertMarginTop = 10;
uint8_t alertMarginBottom = 10;
uint8_t alertMarginLeft = 10;
uint8_t alertMarginRight = 10;
uint16_t a = 10;


void system_loadconf(void)
{
    //读取数据
    Fls_Get(DATA_SYSTEM+0, &animaionFadeTime, 1)
    Fls_Get(DATA_SYSTEM+1, &alertMarginTop, 1)
    Fls_Get(DATA_SYSTEM+2, &alertMarginBottom, 1)
    Fls_Get(DATA_SYSTEM+3, &alertMarginLeft, 1)
    Fls_Get(DATA_SYSTEM+4, &alertMarginRight, 1)
    Fls_Get(DATA_SYSTEM+5, &a, 2)
}


void system_saveconf(void)
{
    //保存数据
    W25Q64_SectorErase(DATA_SYSTEM)
    Fls_Set(DATA_SYSTEM+0, &animaionFadeTime, 1)
    Fls_Set(DATA_SYSTEM+1, &alertMarginTop, 1)
    Fls_Set(DATA_SYSTEM+2, &alertMarginBottom, 1)
    Fls_Set(DATA_SYSTEM+3, &alertMarginLeft, 1)
    Fls_Set(DATA_SYSTEM+4, &alertMarginRight, 1)
    Fls_Set(DATA_SYSTEM+5, &a, 2)
}


#endif

于是我们需要手搓编译工具

 二、python工具

输入数据:我们需要定义的变量。直接给个json,例如:

type:变量类型

value:变量初始值

num:变量长度(如果变量不是数组,不管他)

{
    "animaionFadeTime":{
        "type":"uint8_t",
        "value":10
    },
    "alertMarginTop":{
        "type":"uint8_t",
        "value":10
    },
    "alertMarginBottom":{
        "type":"uint8_t",
        "value":10
    },
    "alertMarginLeft":{
        "type":"uint8_t",
        "value":10
    },
    "alertMarginRight":{
        "type":"uint8_t",
        "value":10
    },
    "a":{
        "type":"uint16_t",
        "value":10
    }
}

python把这个json里面的变量按顺序排布就得到了要往flash中写入的数据的内存布局。注意:数据的存储要分大端小端大端与小端_大小端-优快云博客

首先要把数据打包成二进制流,放在最终写入flash的数据流中。装二进制数据用python的bytearray再合适不过了。打包的话用struct.pack

三、把编译后的数据烧录到w25q64中

1、上位机和stm32代码

# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
# ============================================================
# @Date    : 2022/05/16 21:50:12
# @Author  : miles
# @Email   : lishan@st.xatu.edu.cn
# @File    : serial_demo.py
# @IDE     : PyCharm
# @Func    : Describes the function of the file
# @Note    : pip install pyserial
# ============================================================
"""
import time
import serial.tools.list_ports

if __name__ == '__main__':
    from conf import DB, pack
else:
    from .conf import DB, pack
BSIZE = 256

if __name__ == '__main__':
    # 读取串口列表
    ports_list = list(serial.tools.list_ports.comports())
    if len(ports_list) <= 0:
        print("无串口设备")
    else:
        print("可用的串口设备如下: ")
        print("%-10s %-30s %-10s" % ("num", "name", "number"))
        for i in range(len(ports_list)):
            comport = list(ports_list[i])
            comport_number, comport_name = comport[0], comport[1]
            print("%-10s %-30s %-10s" % (i, comport_name, comport_number))

        i = input("Serial Number\n")
        # 打开串口
        port_num = ports_list[int(i)][0]
        print("默认选择串口: %s" % port_num)
        # 串口号: port_num, 波特率: 115200, 数据位: 8, 停止位: 1, 超时时间: 55.5秒
        ser = serial.Serial(port=port_num, baudrate=115200, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE,
                            timeout=50.5)
        ser.set_buffer_size(81920, 81920)
        if not ser.isOpen():
            print("打开串口失败")
        else:
            print("打开串口成功, 串口号: %s" % ser.name)
            

            print("等待启动")
            while True:
                ser_input = ser.read_all()
                if b"!" in ser_input:
                    print(ser_input)
                    break


            with open(DB, 'rb') as fp:
                total = 0
                length = BSIZE
                while length > 0:
                    data = fp.read(BSIZE)
                    length = len(data)
                    if length == 0:
                        break
                    if length < BSIZE:
                        data += b"\0"*(BSIZE-length)
                    length = len(data)
                    # 串口发送字符串数据
                    ser.write(data)
                    print(f"写入字节{length}")
                    while True:
                        ser_input = ser.read_until()
                        if b"Program" in ser_input:
                            print(f"收到回复:{ser_input}")
                        if b"Erase" in ser_input:
                            print(f"收到回复:{ser_input}")
                        if b"busy" in ser_input:
                            print(f"收到回复:{ser_input}")
                        if b"Recieve" in ser_input:
                            total += length
                            print(f"收到回复:{ser_input}, 累计写入字节数:{total}")
                            break
                    
                    
            # 关闭串口
            ser.close()
            if ser.isOpen():
                print("串口未关闭")
            else:
                print("串口已关闭")
#include "usart.h"
#include "W25Q64.h"
#include "../GUI/GUI.h"
#include "Delay.h"

#define DOWNLOAD_B_SIZE 256
#define DOWNLOAD_E_T 16
#define DOWNLOAD_CAPACITY 0x800000

uint8_t Download_Buff[DOWNLOAD_B_SIZE];
uint32_t Dowmload_Counter = 0;
uint8_t Download_Cbid;
uint8_t Download_Etimer = DOWNLOAD_E_T;
uint32_t Download_Address = 0;


void Download_Printf(uint32_t addr)
{
    W25Q64_ReadData(addr, Download_Buff, DOWNLOAD_B_SIZE);
    UsartPrintf(USART1, Download_Buff);
}


void Download_Write(void)
{

    if (Download_Etimer >= DOWNLOAD_E_T)
    {
        UsartPrintf(USART1, "Start Erase!\n");    
        W25Q64_SectorErase(Download_Address);
        Download_Etimer = 0;
        UsartPrintf(USART1, "end Erase!\n");    
    }
    Download_Etimer++;
    UsartPrintf(USART1, "Start Program!\n");    
    W25Q64_PageProgram(Download_Address, Download_Buff, DOWNLOAD_B_SIZE);
    Download_Address += DOWNLOAD_B_SIZE; 
    UsartPrintf(USART1, "Recieved!\n");    

}



void Download_Recieve(char a)
{
        Download_Buff[Dowmload_Counter] = a;
        Dowmload_Counter++;
        if (Dowmload_Counter ==  DOWNLOAD_B_SIZE)
        {
            Download_Write();
            Dowmload_Counter = 0;
        }
}

void Download_Init(void)
{
    uint16_t did;
    uint8_t mid;
    Usart1_Init(1152000);
    W25Q64_Init();
    Download_Cbid = Usart1_AddCallback(Download_Recieve);
    Usart1_SetCallback(Download_Cbid);
    W25Q64_ReadID(&mid, &did);
    UsartPrintf(USART1, "Download Inited, MID: %d DID: %d\n", mid, did);
    UsartPrintf(USART1, "end init!\n");
}

2.注意每次擦除和写入的限制

注意:w25Q64一次擦除4K,一次最多写入256byte,我看错这个256byte的限制,试了三天没结果!!!

改过来以后发现一个灵异事件:每次写入一段时间后会卡住!!!,一开始以为是flash卡在了waitbuzy,开始各种的换芯片,直到做了一个测试后发现是卡在了usart发送!

写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:18432
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:18688
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:18944
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:19200
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:19456
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRec'

我们发现接收到waitbusy之后还收到了Rec,对应到程序上是:

    UsartPrintf(USART1, "Start Program!\n");    

    W25Q64_PageProgram(Download_Address, Download_Buff, DOWNLOAD_B_SIZE);

    Download_Address += DOWNLOAD_B_SIZE;

    UsartPrintf(USART1, "Recieved!\n");    

改大缓冲区

        ser.set_buffer_size(81920, 81920)

3.上位机的坑

但还是会卡

也有可能是进中断卡死了,上个锁验证一下

bool is_Write = false;

void Download_Write(void)

{

    if (is_Write)

    {

        UsartPrintf(USART1, "recursively call\n");

        return;

    }

    is_Write = true;

    if (Download_Etimer >= DOWNLOAD_E_T)

    {

        UsartPrintf(USART1, "Start Erase!\n");    

        W25Q64_SectorErase(Download_Address);

        Download_Etimer = 0;

        UsartPrintf(USART1, "end Erase!\n");    

    }

    Download_Etimer++;

    UsartPrintf(USART1, "Start Program!\n");    

    W25Q64_PageProgram(Download_Address, Download_Buff, DOWNLOAD_B_SIZE);

    Download_Address += DOWNLOAD_B_SIZE;

    UsartPrintf(USART1, "Recieved!\n");    

   

    is_Write = false;

}

这就说明可能是芯片卡死了,也有可能是上位机问题,换芯片尝试

写入字节256
收到回复:b'Start Erase!\n'
收到回复:b'end Erase!\nStart Program!\n'
收到回复:b'end Erase!\nStart Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:20736
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:20992
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:21248
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:21504
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:21760
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRecieved!\n'
收到回复:b'wait busy\nRecieved!\n', 累计写入字节数:22016
写入字节256
收到回复:b'Start Program!\n'
收到回复:b'wait busy\nRe'

 依旧卡死

void USART1_IRQHandler(void)
{

	if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
	{
	    USART_ReceiveData(USART1);
	  USART_ClearFlag(USART1, USART_FLAG_PE);
	}
	
	if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
	{
	    USART_ReceiveData(USART1);
	  USART_ClearFlag(USART1, USART_FLAG_ORE);
	}
	
	if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
	{
	    USART_ReceiveData(USART1);
	   USART_ClearFlag(USART1, USART_FLAG_FE);
	}
	
	if (USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)
	{
	    USART_ReceiveData(USART1);
	   USART_ClearFlag(USART1, USART_FLAG_NE);
	}

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
	{
		if (Usart1_RecieveCallback[Usart1_CurrentCallback] != NULL)
		{
			Usart1_RecieveCallback[Usart1_CurrentCallback](USART_ReceiveData(USART1));
		}
		USART_ClearITPendingBit(USART1, USART_FLAG_RXNE);
	}

}

依旧卡死,降低为128byte,依旧卡死,将为164byte的缓冲区依旧卡死,最后发现是pyserial的问题

我把read_all换成read_until('\n')成功解决!!!

为什么呢?原来是timeout设置大了

最终找到这位大佬的文章:

2. 介绍
本文需要用到的几种方法和属性,大概看看就好,主要看下面的教程如何使用。

方法    功能
serial.read(size)    读取size字节的数据
serial.readline()    读取一行的数据
serial.readlines()    读取多行的数据,将数据保存到数组里
serial.read_all()    读取一个timeout周期内的全部数据(常用方法)
serial.read_all    读取串口所有的参数信息
serial_timeout(参数)    超时属性,下面具体介绍
3. 快速上手
下面的场景我们需要用用COM4串口发送一串字符串"hello world",波特率9600,如何使用python的serial库进行解析串口发送来的数据?

直接上代码

import serial

ser = serial.Serial("COM2", 9600, timeout=0.01)

while True:
    data = ser.read_all()
    if data:
        rec_str = data.decode('utf-8')
        print(rec_str)
这里我创建了两个虚拟的串口进行模拟,COM2向COM1发送了两次hello world,而Python端实现了COM1,监听来自COM2的消息,用read_all()方法读取接收到的数据,接收到的数据类型是bytes类型的,因此我们需要将bytes数组转成字符串print出来,如下图所示。


而初始化的时候这里的timeout是指在设定的timeout时间范围内,如果读取的字节数据是有效的(就是非空)那就直接返回,否则一直会等到这个设定的timeout时间并返回这段时间所读的全部字节数据。

简单来说你可以理解为每timeout秒读一次数据,而如果timeout太小,数据量太大,可能一次发送不完,会数据未读完的状态。

也就是说,如果我的timeout设置为0.01,现在我有一个串口通信的传感器,传感器通过串口使用COM2发送一次数据,传感器如果在0.01秒内将所有数据都传输过来,就保存到缓存buffer中,到了0.01秒后会调用一次read_all()就可以读取到传感器发送到buffer中的数据了;如果传感器在0.01秒内没有将数据发送全的话,buffer中的数据就是不完全的,就会返回不完全的数据;如果传感器在0.01秒内发送了数据的话,buffer也会返回两组合在一起的数据。

注意:timeout的设置至关重要,如果不是特别高频的数据的话,timeout=0.01的100Hz完全够了,当然timeout最小支持多少要看你的波特率。如果我0.3秒发送了一次数据,timeout设置0.01,就可以返回一次完整的数据;如果我0.01秒发送一次数据,timeout设置0.3,那么一次就会返回30次数据,所以这就是timeout的作用。

前面引入了buffer的概念,这里你应该可以知道,你可以直接把buffer理解为一个文件夹,读数据的方式是和file是一样的,只是引入的timeout的概念,使得buffer 内的数据会以 1/timeout 的频率进行刷新。
如果你把buffer当做file理解,那么readline()就是读取buffer中的一行,如果你的数据中存在\n这样的换行,那么用readline()先让不合适,很容易产生漏读的问题,而且如果你在一个timeout周期内没有用readline()处理完所有你想要的数据的话,buffer就刷新了,因此通过笔者的实践和项目经历读数据只推荐用read_all()来读取。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/linZinan_/article/details/114804811

4.pyserial注意事项:

最好使用read_until,然后把超时时间改大,否则超时了,但还没读到‘\n",程序就会卡在while循环中

四、测试

图片&文字

#include "stm32f10x.h"
#include "usart.h"
#include "AD.h"
#include "Delay.h"
#include "Draw.h"
#include "Time.h"
#include "Key.h"
#include "../GUI/GUI.h"
#include "../GUI/Widgets.h"
#include "Download.h"
#include "dino.h"
#include "yuan.h"
#include "../UI/video.h"
#include "Home.h"

void Init_Apps(void)
{
    Home_Register();
    Video_Register();
    Dino_Register();
    Yuan_Register();
}


int main(void)
{
    Usart1_Init(115200);
    Key_Init();
    GUI_Init();
    Time_Init();
    W25Q64_Init();

    GUI_Image img;
    Fls_GetImage(&img, PICTURES_APPICOS_ABOUT);
    GUI_DrawPicture(img.picture, 0, 0, img.size.w, img.size.h, BLIT_NORMAL);
    Fls_FreeImage(&img);
    GUI_DrawText("Hello World!", 0, 0, FONTS_FONT_BAHNSCHRIFT_12, BLIT_NORMAL);
    GUI_DrawText("Hello world", 0, 20, FONTS_FONT_SQUARE_24, BLIT_NORMAL);
    GUI_Update();
    Init_Apps();

    while (1)
    {
        Widget_Update();
    }
}

 预读取器

#include "stm32f10x.h"
#include "usart.h"
#include "AD.h"
#include "Delay.h"
#include "Draw.h"
#include "Time.h"
#include "Key.h"
#include "../GUI/GUI.h"
#include "../GUI/Widgets.h"
#include "Download.h"
#include "dino.h"
#include "yuan.h"
#include "../UI/video.h"
#include "../Storage/pictures_appicos.h"
#include "../Storage/pictures_maze.h"


int main(void)
{
    Usart1_Init(115200);
    Key_Init();
    GUI_Init();
    Time_Init();
    W25Q64_Init();

    GUI_Rect rect = {
        .size.h = 0, 
        .size.w = 0, 
        .topleft.x = 0,
        .topleft.y = 0
    };
    pictures_appicos_load();
    pictures_maze_load();
    rect.size = pictures_appicos_osc.size;
    GUI_DrawImage(&pictures_appicos_osc, rect);
    pictures_appicos_clear();
    pictures_maze_clear();
    GUI_Update();

    while (1)
    {
        Widget_Update();
    }
}


 

STM32串口升级 STM32升级功能分为2部分,一部分是bootloader程序,另一部分是用户应用程序组成(以STM32F103C8为例来说明 ) bootloader工程分析 启动文件的复位部分 ; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] I... 阅读详情

相关推荐

AMF抓取flex页面数据

抓取AMF协议的flex页面,支持模拟登录和页面抓取。

python 爬取全国农产品批发指数网站 charles 抓取 flash 数据包 分析数据包数据

python 爬取全国农产品批发指数网站 charles 抓取 flash 数据包 分析数据包数据 amf 数据请求与返回格式 flash 数据 完整代码下载:https://github.com/tanjunchen/SpiderProject/tree/master/agriculture #!/usr/bin/env python # -*- coding: utf-8 -*- import requests import uuid import pyamf import da..

tanjunchen的博客 1274

Ubuntu HackRF One、GNU Radio、Gqrx相关环境搭建

本文介绍Ubuntu HackRF One、GNU Radio、Gqrx相关环境搭建方法。

无线通信实验室 1万+

【Python】Python爬取复旦大学拟录取硕士名单公示——Adobe Flash Player的内容

1.手动获取:下载fiddler抓包工具:https://www.telerik.com/fiddler安装好后打开fiddler,进入网页:http://www.gsao.fudan.edu.cn/2b/22/c1659a142114/page.htmfiddler获取到一系列http请求,选择result为200的逐个点入查看request headers:将src=后的内容添加到www.gs...

Li_Jiaqian的博客 1811

Origin2018(汉化版)在使用科学计数法的时候如何将坐标刻度的0.0改成0

文章目录1 问题2 解决方法 1 问题 先看下面这张图,当我使用科学计数法时,纵坐标出现了0.0的字样,这样看起来很不美观。有些期刊还会有要求,不能出现0.0的格式。 图1 那么该怎么将它改成0呢?首先让我们尝试着用Origin自带的属性,看看能不能设置。 2 解决方法 解决方法一: step1: 双击坐标轴,打开坐标轴属性设置。 step2: 在刻度线标签选项中设置左轴的显示 图2 会发现,按照图2的方式改好之后,其它的小数位也全没了,如果但是有些数字就被覆盖了,这显然不是我

qq_40077565的博客 2万+

snipersim安装

snipersim安装记录,便于后续使用tip:snipersim需要在python2的环境下编译。

weixin_53507617的博客 917

flash详解

1.2.1. 什么是Flash Flash全名叫做Flash Memory,从名字就能看出,是种数据存储设备,存储设备有很多类,Flash属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory Device)。关于什么是非易失性/易失性,从名字中就可以看出,非易失性就是不容易丢失,数据存储在这类设备中,即使断电了,...

sternlycore的博客 3万+

QT C++ AI棉花智能变量灌溉工上位机(信创完整版)

北斗履带灌溉机器人/田间分区电磁阀基站 → 多层土壤温湿度/盐分EC传感器实时采集墒情 → 双目AI视觉扫描棉田长势、病苗分布 → AI融合**生育期+土壤墒情+盐分+棉株长势**计算变量灌溉定额、水肥配比、灌溉时长 → 分区电磁阀/变频水泵变量供水,病弱苗地块减量、干旱地块增量;墒情、盐分、长势多因子闭环修正灌水量;多层土壤含水率(0–10/20–40/40–80cm)、土壤EC盐分、土壤温度、空气温湿度、蒸发量、北斗地块坐标、管道水压、水肥罐液位、分区流量计、水泵电机负载、滴灌带压力反馈。

寒寒豆豆软件公司的博客 184

Flash 酷站猎手

Flash Cool Site Hunter[Flash 酷站猎手] 是一个用来自动获取最新Flash酷站的应用程序. >>> 点击下载 <<< 最后更新:请点击软件的检查版本按钮 数据由以下权威 Flash 网站评审机构提供: Pages.Think UltraShock-BombShockAwards FWA-FavouriteWebsi...

weixin_30457065的博客 127

华为OD机试真题 新系统2026-04-15 Python&JS 实现【失灵的键盘】

有一个键盘有2个按键失灵了,按下这些键时会连续输出其他键对应的字符两次。具体如下: 1. 按下j键一次,屏幕上显示uu(两个连续的u);  按下b键一次,屏幕上显示t(两个连续的t) 2. u键和t键是好的,按下u键一次时,屏幕只会显示一次u(正常按键);按下t键一次时,屏幕只会显示一次t(正常按键) 3. 假定屏幕上连续显示两个t一定是按了一次b键,而不是两次t键;假定按键t之后不会紧接着按键b,即tttt转义为两个b,而不可能是tb

MISAYAONE的博客 522

基于STM32、HAL库的ADE7880ACPZ-RL电能计量芯片驱动程序设计

@retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)PA6 (MISO) <--> SDO (SPI数据输出)PB0 (CS) <--> /CS (片选,低有效)

corlin6688的博客 668

NAND Flash 和NOR Flash

都看了好几遍,长时间不用,又给忘了......

m0_37732375的博客 814

2025国赛数学建模A题 完整Python代码 烟幕干扰弹的投放策略

常量定义G = 9.8 # 重力加速度 m/s²V_SMOKE_SINK = 3 # 烟幕下沉速度 m/sMISSILE_SPEED = 300 # 导弹速度 m/sEFFECTIVE_RADIUS = 10 # 有效遮蔽半径 mEFFECTIVE_DURATION = 20 # 有效遮蔽时间 sTARGET_POS = np.array([0, 200, 0]) # 目标位置FALSE_TARGET_POS = np.array([0, 0, 0]) # 假目标位置# 初始位置。

YOLO 1105

用FLASH COM做视屏聊天室

MM公司如是说——    1. 创建新一代应用程序    将全新的交互和体验集成到您的 web 内容中。轻松地将诸如聊天、流视频、丰富媒体消息接发和实时协作之类的功能,添加到您的 web 站点和应用程序中。          2. 捕捉 Internet 上最广泛的用户    Macromedia Flash Player 是 web 上部署最广泛的软件,因此,各类用户都能观看您的通信应用,而

杨柳天下 2143

UNet改进(12):融合小波变换与注意力机制的图像分割新方法

本文提出了一种改进的WaveletAttentionUNet架构,通过结合小波变换和注意力机制来增强传统UNet的多尺度特征提取能力。该网络使用分组卷积模拟小波分解,将输入通道扩展为4个子带(LL、LH、HL、HH),并通过通道注意力机制自适应加权各子带特征。网络保留了UNet的编码器-解码器结构,在关键位置集成了WaveletAttention模块。实验证明该方法在医学图像分割等任务中能更好地保持边缘细节和复杂纹理特征,同时保持计算效率。

2501_91516851的博客 758

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【STM32】标准库-读写内部Flash及用户选项字节

默认情况下,FLASH_OPTCR 寄存器中的第 0 位 OPTLOCK 值为 1,它表示选项字节被上锁,需要解锁后才能进行修改,当寄存器的值设置完成后,对 FLASH_OPTCR 寄存器中的第 1 位 OPTSTRT值设置为 1,硬件就会擦除选项字节扇区的内容,并把 FLASH_OPTCR/1 寄存器中包含的值写入到选项字节。修改选项字节的内容可修改各种配置,但是,当应用程序运行时,无法直接通过选项字节的地址改写它们的内容,例如,接使用指针操作地址 0x1FFFC0000 的修改是无效的。........

熠熠L的博客 5577

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

stm32读写内部Flash

stm32内部flash地址架构映射stm32内部flash地址架构映射因为我的stm32f407的内部flash是1M的所以块2不存在,但他的地址仍然存在,只是没有作用,这是stm32的整体框架。主存储器一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 1M FLASH、2M FLASH 都是指这个区域的大小。

weixin_47321452的博客 2168

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

借助基于基于Java的RESTful API支持的Flash Builder的灵活且用户可配置的图表

许多软件公司都有复杂的软件解决方案。 但是,这些解决方案通常缺乏简单而灵活的方式来使用视觉上吸引人的仪表板图表来呈现其数据的全局外观,以呈现数据趋势或将可能的风险情况告知正确的用户。 本文介绍了如何构建一个示例应用程序,该应用程序包含一个门户式主页,该主页包含用户配置的图表,这些图表已连接到基于Java的具有代表性状态传输(REST)的Web应用程序以获取其数据,并执行传入操作以创建,从其页面...

cunfu6353的博客 238

Flash Media Server简介

 介绍Flash Media ServerMacromedia Flash Media Server 2是一个富媒体应用程序的开发框架和部署环境。开发者可以使用Macromedia Flash和FlashMedia Server来编写媒体应用程序,然后使用Flash Media Server来部署这些应用程序。Macromedia Flash Player是终端用户的界面。     Fla

Xiang 1892

Flash Media Server安装

1、什么是Flash Media Server ?简称FMS。服务器是用于用户之间相互通讯的新平台;它集成了Flash多媒体交互的特性;又添加了实时音频和实时数据流等新特色.。使用该平台,你可以通过网络存储录制下来的音频、视频,也可以共享数据对象,并且可以将这些音频、视频和共享数据对象传递给多个客户端,实现实时同步共享。该平台集成了通讯功能和应用程序功能,它通过Flash Player(...

weixin_30699741的博客 89

使用SharedObject在Application间共享数据

<br />在A应用程序里创建一个SharedObject<br />var UserInfo:SharedObject = null; //Session-Save User Informations UserInfo = SharedObject.getLocal("ShareInfo","/"); UserInfo.data.UserRName = L_UserRName.text; UserInfo.data.UserType = L_UserType.text; UserInfo.

cypbkd的专栏 680

nRF52832 DFU升级导致FDS数据丢失的问题

产品使用nRF52832的FDS模块来存储用户数据。产品在使用过程中,发现DFU升级有一定概率导致FDS数据丢失。经过查找相关资料,发现在Bootloader程序中有一个宏,用来指定受保护Flash区的大小。在保护范围之外的,会被Bootloader给擦除。这个宏是: #ifndef DFU_APP_DATA_RESERVED #define DFU_APP_DATA_RESERVE...

fun_tion的博客 3150

bootROM和flash的区别

对比说明Boot ROM和Flash的优缺点。闪存(Flash)是如何实现可擦写的?如何确定设备使用的是哪种类型的存储器?

haoyj2222的博客 670

存储读写之FLASH篇2-本篇内容来自野火文档

在STM32芯片内部,存在一个重要的FLASH存储器,其主要用途是存储应用程序代码。编写完应用程序后,通常需要使用下载工具将已编译的代码文件写入内部FLASH。不可忽视的是,内部FLASH具有非易失性存储的特性,这意味着在断电后存储的数据不会丢失。每次芯片重新上 电并复位后,内核可以从内部FLASH中加载并执行存储的代码。除了使用外部工具(如下载器)来读写内部FLASH之外,STM32芯片在运行时也可以对其自身的内部FLASH进行读写操作。

GuoFengZhuo 1697

flash,AIR的本地存储初步了解

呃,只是今天在做手机上的air程序的存储,所以稍微看了下flash,air的存储本地数据方面的知识。 存储本地数据的方法其实有不少,最简单的就是用shareObject了,的确是最简单的了,基本属于零基础就能用的了。shareObject直译为共享对象(有时称为“Flash cookie”)是一个数据文件,可以将数据存储到用户的本地硬盘上,然后在同一会话期间或以后的会话中调用这些数据。各应用

EooSc的专栏 1481
上一篇: Qt易错总结
下一篇: 尝试JLC四层板
python_use
博客等级 码龄5年 430粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值