STM32U575测评 使用这块开发板测试HC-SR04模块的串口通信功能,并尝试移植TinyMaix实现在单片机上的实时手写数字的识别。

  1. 简单介绍与体验请添加图片描述
    STM32U575ZIT6的主频有160Mhz,拥有17个定时器,4个I2C,6个UART,3个SPI以及其他一共22个通信用的外设。这块开发板上集成了ST-LINKv3,因此这个开发板使用起来非常方便,程序的下载速度体验也挺不错。

  2. 工程文件与开发环境的准备
    AltAlt
    在这里插入图片描述
    因为这款单片机由于没有标准库,于是最近一段时间接触了一下STM32CudeMX,然后使用HAL库来开发相应的程序。准备好Keil环境之后,再VScode里面下载Keil Assistant,就可以实现再VScode中编写代码,编译烧录进STM的单片机里了。先写个流水灯程序测试测试。

  3. HC_SR04的串口通信功能的测试
    AltAlt
    先用这个开发板来测试HC-SR04的串口通信,因为我之前在网上找相关的教程,都是关于如何使用GPIO测量高电平时间来测算距离的,看到这个模块上有UART,I2C,和One-Wire,就想找时间试试。于是利用这次评测这个开发板的机会来顺便测试测试这个功能。请添加图片描述
    请添加图片描述
    经过查找资料只要将这个模块红框内的10K电阻补上就能使用串口进行通信了。
    之后再CubeMX里面启动串口,设置好对应设置就行了,其中波特率要设置到9600。
    之后使用HAL_UART_Transmit发送0xA0,再用HAL_UART_Receive接收三个数据就能完成一次测量。
    请添加图片描述
    在Keil的Option中勾选上Use MicroLIB,之后在自动生成的uart.c里面添加一段

    int fputc(int ch, FILE* f)
    {
      if (HAL_UART_Transmit(&huart1, (uint8_t *)&ch, sizeof((uint8_t *)&ch), 1000) != HAL_OK)
      {
        return EOF;
      }
      return ch;
    }
    

    来实现printf打印到串口
    请添加图片描述
    简单完善代码让单片机使用串口读取HC-SR04的数据,并把数据通过USART1发动到电脑。

  4. 使用这块开发板驱动老王家的一款128*128像素4位灰度的OLED屏幕为之后手写数字识别的显示做准备。

    因为老王提供的代码使用了U8G2的库,因为我不太了解,并想着学习学习显示模块的驱动的全流程,于是自己写了一套简陋但能满足我现在功能的驱动。先是用软件SPI驱动屏幕
    Alt
    经过测试,刷新速度也还不错,但考虑到后面要运行一个模型,我还是打算使用硬件SPI+DMA的方法驱动屏幕。因为这款单片机的DMA是GPDMA,所以配置页面和DMA的配置页面有些区别,但总体操作都是差不多的,配置成Circular Mode,选择Request的来源,设置好地址自增,之后就用HAL_SPI_Transmit_DMA来开启搬运就行了。经过测试这款屏幕的驱动芯片SSD1327无法支持40Mhz及以上的SPI,于是用的20Mhz的SPI,经过计算一秒内能刷新2441帧画面,远超这个屏幕一百多Hz的刷新率。

  5. 移植TinyMaix
    根据这个博主使用轻量级AI推理框架TinyMaix实现手写数字识别完成TinyMaix的移植,并将推理部分的Demo的程序进行简单封装,方便外部调用。

    
    void mnist_main_LoadModel(void);
    void mnist_main_ImgProcess(void);
    void mnist_main_UnloadModel(void);
    void mnist_main_GetResule(uint8_t *ID, float *Confidence);
    tm_mdl_t mdl;
    tm_mat_t in_uint8 = {3, 28, 28, 1, {(mtype_t *)mnist_pic}};
    tm_mat_t in = {3, 28, 28, 1, {NULL}};
    tm_mat_t outs[1];
    tm_err_t res;
    void mnist_main_LoadModel(void)
    {
        res = tm_load(&mdl, mdl_data, NULL, layer_cb, &in);
        if (res != TM_OK)
        {
            TM_PRINTF("tm model load err %d\r\n", res);
        }
    }
    
    void mnist_main_ImgProcess(void)
    {
        res = tm_preprocess(&mdl, TMPP_UINT2INT, &in_uint8, &in);
        res = tm_run(&mdl, &in, outs);
    //    parse_output(outs);
    }
    
    void mnist_main_GetResule(uint8_t *ID,float *Confidence)
    {
        float *data = outs[0].dataf;
        float maxp = 0;
        int maxi = -1;
        for (int i = 0; i < 10; i++)
        {
            if (data[i] > maxp)
            {
                maxi = i;
                maxp = data[i];
            }
        }
        *ID = maxi;
        *Confidence = maxp;
    }
    
    void mnist_main_UnloadModel(void)
    {
        tm_unload(&mdl);
    }
    

    程序里面将mnist_pic作为tm_mat_t in_uint8 的数据部分,之后使用tm_preprocess把图片数据的uint转换成int,转化成tm_mat_t in 加载模型后直接将in 作为输入,进行计算,因此改变mnist_pic的原始数据就能改变进行计算的图片的内容。
    Alt测试将mnist_pic的内容映射成4位灰度显示到屏幕上。
    视频流打算使用电脑端处理视频内容,将原始视频转化成28*28的灰度在这里插入图片描述
    然后通过串口发送到单片机内,进行推理。为了让单片机能专注推理,接收图片也采用串口和DMA配合,直接将数据存进mnist_pic数组里面。

  6. 最终结果
    在这里插入图片描述
    这个帧率是用定时器计算的每秒钟主循环循环的次数,也就是说这款单片机每秒可用这个TinyMaix进行400次推理。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我可以为您提供基于stm32f103zet6开发板HC-SR501人体红外感应模块的代码。以下是代码: #include "stm32f10x.h" #include "delay.h" #include "usart.h" #define HC_SR501_GPIO GPIOA #define HC_SR501_PIN GPIO_Pin_ void HC_SR501_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = HC_SR501_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(HC_SR501_GPIO, &GPIO_InitStructure); } int main(void) { USART_Config(); HC_SR501_Init(); while(1) { if(GPIO_ReadInputDataBit(HC_SR501_GPIO, HC_SR501_PIN) == Bit_SET) { printf("Someone is detected!\r\n"); } else { printf("No one is detected.\r\n"); } delay_ms(100); } } 这段代码可以实现基于stm32f103zet6开发板HC-SR501人体红外感应模块的检测功能。当有人经过感应器时,会通过串口输出提示信息。 ### 回答2: 当开发基于STM32F103ZET6开发板HC-SR501人体红外感应模块的代码时,首先需要明确硬件连接的接口和引脚。一般情况下,HC-SR501模块有三个引脚:VCC、OUT和GND,其中VCC接连板子的电源正端,GND接连板子的电源地端,OUT连接板子的GPIO引脚。 以下是一个基于C语言的示例代码,以帮助你编写HC-SR501的人体红外感应模块的代码: ``` #include "stm32f10x.h" #define SENSOR_PIN GPIO_Pin_0 #define SENSOR_PORT GPIOA void GPIO_Configuration(void); void EXTI_Configuration(void); void delay_ms(uint32_t time); int main(void) { GPIO_Configuration(); EXTI_Configuration(); while (1) { // 在此处添加需要执行的代码 } } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = SENSOR_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(SENSOR_PORT, &GPIO_InitStructure); } void EXTI_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 执行红外感应触发后的操作(例如,点亮LED等) EXTI_ClearFlag(EXTI_Line0); } } void delay_ms(uint32_t time) { uint32_t i; for (i = 0; i < ((SystemCoreClock / 18000) * time); i++) { } } ``` 在此示例代码中,我们首先配置了GPIO引脚作为输入,然后使用外部中断来检测HC-SR501感应模块是否触发。当感应模块触发时,会进入外部中断处理程序(EXTI0_IRQHandler),在其中可以添加相应的操作。 需要注意的是,这只是一个基本示例代码,根据具体需求还可以进一步完善和修改。确保你在使用之前对代码进行充分测试,并根据具体情况进行适当调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值