当前位置: 首页 > news >正文

十六届蓝桥杯嵌入式省赛直播基本外设驱动

前言

本文是准备2025年4月123日嵌入式蓝桥杯直播内容准备的一篇文章

1.创建工程

选择芯片

开启烧录引脚

 

 开启高速时钟

主频设置成80回车

工程名称(不能有中文,包括路径)

考试的时候最下面哪一行取消勾选USE 然后选择这个文件夹打开

勾选几个

创建并且打开工程

编译无误后烧录器选择DAP

然后基本烧录无误

创建一个文件夹,专门用来存放自己的那个.c和.h文件

创建完成后添加路径

在DSP文件夹下创建基本的.c.h文件框架

在主函数中添加头文件

希望下载后直接运行,把reset run 勾选

2.LCD显示屏和LED等

1.LCD的基本配置

根据原理图

可以发现LCD和LED的引脚是共用的

考试的时候会给资源包,根据这个路径获取文件

需要三个文件

首先是把这两个.h复制到自己的文件

.c也放到里面

添加完后添加头文件编译

编写初始化代码驱动LCD显示屏

  LCD_Init();
  LCD_Clear(Black);
  LCD_SetTextColor(White);
  LCD_SetBackColor(Black);
  
  
  char ss[20]="hello world!";
  LCD_DisplayStringLine(Line0,(uint8_t *)ss);

成功亮起

接下来是LED

因为LCD和LED共用引脚

要处理他们互不干涉

2.处理LCD和LED互不干涉

PD2

锁存器要打开

处理这两个函数

IIC分别是写和读

分别对这两个函数的ODR输出寄存器记录状态

使用完恢复状态

这样修改后灯的状态就不会受到LCD显示屏的影响

烧录后灯不会乱两灭

3.LED的亮灭函数封装

根据原理图可以知道灯是PC8到PC15

void led_show(uint8_t number,uint8_t cmd)
{
    static uint8_t led[8]={0};
    
    switch (cmd)
    {
        case 0://假设给某个引脚低电平   亮
            led[number-1]=1;break;
        case 1://给高电平    灭
            led[number-1]=0;break;
        case 2://翻转某个引脚的电平
            if(led[number-1])
                led[number-1]=0;
            else
                led[number-1]=1;
    }
    
    for(uint8_t i=0;i<8;i++)
    if(led[i])
        HAL_GPIO_WritePin(GPIOC,1<<(8+i),0);
    else
        HAL_GPIO_WritePin(GPIOC,1<<(8+i),1);

    HAL_GPIO_WritePin(GPIOD,1<<2,1);//打开锁存器
    HAL_GPIO_WritePin(GPIOD,1<<2,0);//关闭锁存器
}

调用这个函数,第一个参数是第几个灯

第二个参数是对应的功能,0是亮

1是灭

2是翻转

2.非阻塞式按键

考试的题目,一般要求按下的时候,其他程序正常进行,所以要使用非阻塞

实现非阻塞的方法是定时器配合按键使用

因为一般的消抖时间为20ms,所以配置一个20msd的定时器中断

使能定时器        

 HAL_TIM_Base_Start_IT(&htim4);

 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
 {
    if(htim==&htim4)
    {
        key_check();
    
    
    }
 }

void key_check()
{
    static uint8_t flag[4]={0};
    uint8_t numebr;
    
    numebr=0;
    switch (flag[numebr])
    {
        case 0:if(!HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=1;
        }break;
        case 1:if(HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=2;
        }break;
        case 2:
        {
          key1();  
        flag[numebr]=0;
        }
    }
    
        numebr=1;
    switch (flag[numebr])
    {
        case 0:if(!HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=1;
        }break;
        case 1:if(HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=2;
        }break;
        case 2:
        {
          key2();  
        flag[numebr]=0;
        }
    }
    
        numebr=2;
    switch (flag[numebr])
    {
        case 0:if(!HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=1;
        }break;
        case 1:if(HAL_GPIO_ReadPin(GPIOB,1<<numebr))
        {
        flag[numebr]=2;
        }break;
        case 2:
        {
          key3();  
        flag[numebr]=0;
        }
    }
    
        numebr=3;
    switch (flag[numebr])
    {
        case 0:if(!HAL_GPIO_ReadPin(GPIOA,1<<0))
        {
        flag[numebr]=1;
        }break;
        case 1:if(HAL_GPIO_ReadPin(GPIOA,1<<0))
        {
        flag[numebr]=2;
        }break;
        case 2:
        {
          key4();  
        flag[numebr]=0;
        }
    }
}


void key1()
{
    led_show(1,2);
}

void key2()
{
 led_show(2,2);
}

void key3()
{
 led_show(3,2);
}

void key4()
{
 led_show(4,2);
}

3.串口的不定时长接受以及接收后如何判断

先配置引脚,在打开串口,一把考试用的是9600

同时打开中断

串口重定向

把use micro打开

添加标准库头文件

int fputc(int ch,FILE* f)
{
    HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
    return ch;
}

成功显示

不定时长代码

char buffer[1],OUT[100];
uint16_t length=0,time=0;

void uart_init()
{
    HAL_UART_Receive_IT(&huart1,(uint8_t*)buffer,1);
   
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  
    if(huart==&huart1)
    {
        OUT[length++]=buffer[0];
        time=0;
         HAL_UART_Receive_IT(&huart1,(uint8_t*)buffer,1);
    }
}

void uart_chanle()
{
      time++;
    if((time>3)&&length)//超过40ms没有接受到字符并且已经接收到字符了
    {
        if(strcmp(OUT,"LED_ON")==0)
        {
            led_show(1,0);
        }
          if(strcmp(OUT,"LED_OFF")==0)
        {
         led_show(1,1);
        }
        
        memset(OUT,'\0',sizeof(OUT));//清空接收区
        length=0;
        time=0; 
    }
}

4.输入捕获获取频率

根据原理图可以知道引脚是PA15和PB4

  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
  __HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE);
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
  __HAL_TIM_ENABLE_IT(&htim3,TIM_IT_UPDATE);

初始化函数

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if(htim==&htim2)
    {
        //r40
        uint16_t count1=TIM2->CCR1;
        TIM2->CNT=0;
        xl555_return(2,80000000/(80*count1));
    }
    
    if(htim==&htim3)
    {
        //r39
        uint16_t count2=TIM3->CCR1;
        TIM3->CNT=0;
        xl555_return(3,80000000/(80*count2));
    }

}
uint16_t xl555_return(uint8_t cmd,uint16_t count)
{
    static uint16_t count1,count2;
    switch (cmd)
    {
        case 0:
            return count1;
        case 1:
            return count2;
        case 2:count1 =count;break;
        case 3:count2=count;break;
    }
}

5.ADC

 

float adc_return(uint8_t number)
{
    float adc;
    switch (number)
    {
        case 0:
           HAL_ADC_Start(&hadc1);
           adc=(float)HAL_ADC_GetValue(&hadc1)/4096*3.3;
            HAL_ADC_Stop(&hadc1);
            return adc;
        case 1:
     HAL_ADC_Start(&hadc2);
           adc=(float)HAL_ADC_GetValue(&hadc2)/4096*3.3;
            HAL_ADC_Stop(&hadc2);
            return adc;
    }
}

5.IIC读写AT24C02

首先打开这个地址把这两个函数放到DSP文件夹

    void eeprom_write(uint8_t address,uint8_t data)
    {
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
        
        I2CSendByte(address);
        I2CWaitAck();

        I2CSendByte(data);
        I2CWaitAck();
        
        
        I2CStop();
        HAL_Delay(500);
    }

    uint8_t eeprom_read(uint8_t address)
    {
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
        
        I2CSendByte(address);
        I2CWaitAck();
        
        I2CStart();
        I2CSendByte(0xa1);
        I2CWaitAck();
        uint8_t data=I2CReceiveByte();
        I2CSendNotAck();

        I2CStop();
        return data;
    }

在后面添加的代码

版本要用5的,要不然IIC会失败

记得加初始化,然后就驱动成功了

相关文章:

  • 设计模式 Day 8:策略模式(Strategy Pattern)完整讲解与实战应用
  • Bartender 5 for Mac 多功能菜单栏管理
  • CSS >子元素选择器和空格
  • 2025年第十六届蓝桥杯省赛C++ A组真题
  • nvm list available 无法查看解决办法
  • GEO优化实战指南:构建生成式AI时代的品牌内容霸权
  • 汇舟问卷:国外问卷调查技巧有哪些,具体该怎么操作
  • Linux-内核驱动-makemenu,make modules,make uImage,杂项
  • AI编程案例拆解|基于机器学习XX评分系统-前端篇
  • DAPP实战篇:使用ethersjs连接智能合约并输入地址查询该地址余额
  • 【愚公系列】《Python网络爬虫从入门到精通》048-验证码识别(滑动拼图验证码)
  • Dify智能体平台源码二次开发笔记(3) - 智能体API的三方验证集成
  • 国网B接口云镜控制接口流程详解以及检索失败原因(电网B接口)
  • leetcode 204. Count Primes
  • 《深入理解生命周期与作用域:以C语言为例》
  • 概念辨析:Redis 多路 I/O 复用和多线程
  • MSCKF及可观性总结
  • Elasticsearch:使用稀疏向量提升相关性
  • 修复 WPS 编译错误:缺少:Sub或Function 且出现两个MathType加载项
  • 生物化学笔记:医学免疫学原理15 超敏反应过敏反应(I型[蚊虫叮咬]+II型[新生儿溶血症、突眼型甲亢]+III型+IV型)
  • 本机做web打开网站无法显示网站/怎么推广app让人去下载
  • 北京网站建设怎么样天/抖音代运营收费详细价格
  • 西安网站建设seo竞价/小学生班级优化大师
  • 网站开发实训周志/百度网站的网址
  • 南阳网站开发公司/seo百度seo排名优化软件
  • 深圳市门户网站建设品牌/免费搭建网站的软件