你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32开发,HAL函数实现LED数码管+红外遥控+IIC读写保存配置

[复制链接]
STMCU小助手 发布时间:2022-5-5 17:42
1 概述
1.1 资源概述

开发板:正点原子STM32F103 Nano开发板
CUBEMX版本:1.3.0
MDK版本:5.23
主控芯片型号:STM32F103RBT6

Y1IMY2@HT@PYT3]NK(XXQG3.png

1.2 实现功能
1 本实验开机进入等待红外触发,如过接收到正确的红外信号,则解码,并在数码管上显示;
2 按键1-7分别控制LED1-LED7,电源按键用来打开所有的LED1-LED7,外星人按键用来关闭所有的LED1-LED7;
3 另外将按键判定从定时器中断中分离出来,放在main函数中;
4 使用vol-,开启和关闭声音;
5 使用开发板上的key1按键用来保存声音的配置,保存的数据写入iic中,这样重新上电或者复位后可以使用;
6 LED0用来指示程序的运行状态。

2 硬件相关知识
2.1电路图

采用38译码器和移位寄存器实现。

E2G90SGFA3VJ{{5A{OF`~31.png

2.2 字符查询
字符查询,极性是共阴,排列顺序是a-dp

9C7K]{LXUFJ4)6J)2CHB))U.png

tips
如果我们要实现小数点,有一个捷径,不用重新生成字符,在原来字符上增加一个或0x01(共阴adp方式)的操作,如H.代码为0x6e|0x01

6Q39BIYBQL_(APHU5LH6I9R.png

3 程序实现
此程序在正点原子的红外实验程序基础上进行修改,增加了IIC程序,用来保存按键声音的配置。通常在工程中,使用EEPROM来保存配置信息,这样掉电就不会消失。最常用的是各种设置信息的保存。还有一些ADC的校准信息,程序版本信息等,都会保存在IIC中。
实现的逻辑思想
1、进入main程序,读取IIC中声音的配置变量;
2、依据声音配置变量,设置按键声音开还是关;
3、扫描远程遥控器按键,并作出对应的操作;
4、扫描本地按键,如果key1被按下,则写IIC,保存声音配置。
在主程序中,使用了字符串赋值函数strcpy,以及字符串比较函数strcmp,因此在头文件中需要包含头文件string.h,由于对按键赋值使用到了true和false,因此使用到了bool型变量,需要包含头文件stdbool.h。
程序进行了改写,将定时器中断中的按键检测挪到了主函数中,中断中不宜进行太多的逻辑操作。
程序中增加了一个250ms翻转一次的LED灯,用来当做“心跳”,当程序卡死或者异常时,此灯的状态会表现异常,这也是一种很常见的工程方法。

参数保存还有优化的空间,最佳的方式是在下电过程中进行保存,而不是人工保存,这样能减少EEPROM的写入次数,延长EEPROM的寿命,通常EEPROM的寿命只有几千次。

1,主程序代码如下

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "smg.h"
  6. #include "remote.h"
  7. #include "timer.h"
  8. #include "beep.h"
  9. #include <stdbool.h>
  10. #include "24cxx.h"
  11. #include "myiic.h"
  12. #include "key.h"
  13. #include <string.h>

  14. // 共阴数字数组
  15. // 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全灭
  16. u8 smg_num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x01,0x00};
  17. u8 keyRemote=0,keyLocal = 0;; //按键值
  18. u8 num=0x00;//数值
  19. u8 num1=0x00;//数值
  20. u8 smg_wei=6;//数码管位选
  21. u8 smg_duan=0;//数码管段选
  22. u8 smg_flag=0;//数码管显示标志 0:正常显示 1:消除鬼影
  23. u8 t=0;
  24. char  TEXT_Buffer[]={"NANO STM32 IIC TEST"};
  25. #define SIZE sizeof(TEXT_Buffer)
  26.         
  27. int main(void)
  28. {
  29.         bool volState = false ;//true为关闭声音,false为打开声音
  30.         char datatemp[SIZE];
  31.         
  32.     HAL_Init();                            //初始化HAL库   
  33.     Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M
  34.     delay_init(72);                 //初始化延时函数
  35.         uart_init(115200);                         //串口初始化为115200
  36.         LED_Init();                                          //初始化与LED连接的硬件接口
  37.         BEEP_Init();                    //蜂鸣器初始化
  38.         LED_Init();                                          //初始化与LED连接的硬件接口
  39.     LED_SMG_Init();                 //数码管初始化
  40.     TIM4_Init(19,7199);             //数码管2ms定时显示
  41.     Remote_Init();                                //红外接收初始化        
  42.         AT24CXX_Init();                        //IIC初始化
  43.         KEY_Init();                                //按键初始化        
  44.         if(AT24CXX_Check())//检测不到24c02
  45.                 {
  46.                         printf("24C02 Check Failed!\r\n");
  47.                         delay_ms(500);
  48.                         printf("Please Check!\r\n");
  49.                         delay_ms(500);
  50.                         LED0=!LED0;//DS0闪烁
  51.                 }
  52.         else
  53.                 printf("24C02 Ready!\r\n");
  54.         printf("WK_UP:save the volume setting!\r\n");//显示提示信息        
  55.         printf("1-7:led1-LED7 switch\r\n");
  56.         printf("power:all led off\r\n");
  57.         printf("alientec:all led on\r\n");
  58.         printf("vol-:sound switch\r\n");
  59.         AT24CXX_Read(0,datatemp,SIZE);
  60.         printf("The Data Readed Is:\r\n");//提示传送完成
  61.         printf("%s\r\n",datatemp);//显示读到的字符串

  62.         if(strcmp(datatemp,"true"))
  63.                 volState = false ;
  64.         else
  65.                 volState = true ;

  66.         
  67.         while(1)
  68.         {
  69.                 keyRemote = Remote_Scan();
  70.                 if(keyRemote)
  71.                  {
  72.                         switch(keyRemote)
  73.                         {
  74.                                 case 104:
  75.                                         num1=0x00; num = smg_num[1]; BEEP=volState;
  76.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1);
  77.                                         break; //按键'1'
  78.                                 case 152:
  79.                                         num1=0x00;num=smg_num[2];BEEP = volState;
  80.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
  81.                                         break;     //按键'2'           
  82.                                 case 176:
  83.                                         num1=0x00;num=smg_num[3];BEEP = volState;
  84.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_3);
  85.                                         break;     //按键'3'            
  86.                                 case 48:
  87.                                         num1=0x00;num=smg_num[4];BEEP = volState;
  88.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4);
  89.                                         break;      //按键'4'                    
  90.                                 case 24:
  91.                                         num1=0x00;num=smg_num[5];BEEP = volState;
  92.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_5);
  93.                                         break;      //按键'5'                    
  94.                                 case 122:
  95.                                         num1=0x00;num=smg_num[6];BEEP = volState;
  96.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);
  97.                                         break;     //按键'6'                  
  98.                                 case 16:
  99.                                         num1=0x00;num=smg_num[7];BEEP = volState;
  100.                                         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_7);                                
  101.                                         break;      //按键'7'                                                                  
  102.                                 case 56:num1=0x00;num=smg_num[8];BEEP = volState;break;      //按键'8'         
  103.                                 case 90:num1=0x00;num=smg_num[9];BEEP = volState;break;      //按键'9'
  104.                                 case 66:num1=0x00;num=smg_num[0];BEEP = volState;break;      //按键'0'
  105.                                 case 82:num1=0x00;num=smg_num[17];BEEP = volState;break;     //按键'DELETE'
  106.                                 case 162:
  107.                                         num1=smg_num[1];num=smg_num[0];BEEP = volState;
  108.                                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
  109.                                         GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_PIN_SET);        //PC0~7置1,灯灭
  110.                                         break;//按键'POWER'                                 
  111.                                 case 98:num1=smg_num[1];num=smg_num[1];BEEP = volState;  break;//按键'UP'
  112.                                 case 226:
  113.                                         num1=smg_num[1];num=smg_num[2];BEEP = volState;
  114.                                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
  115.                                         GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_PIN_RESET);        //PC0~7置0,灯开
  116.                                         break;//按键'ALIENTEK'
  117.                                 case 34:num1=smg_num[1];num=smg_num[3];BEEP = volState;  break;//按键'LEFT'
  118.                                 case 2:num1=smg_num[1];num=smg_num[4];BEEP = volState;   break;//按键'PLAY'
  119.                                 case 194:num1=smg_num[1];num=smg_num[5];BEEP = volState; break;//按键'RIGHT'
  120.                                 case 224:
  121.                                         num1=smg_num[1];num=smg_num[6];BEEP = 0;
  122.                                         volState = !volState;
  123.                                         break;//按键'VOL-'
  124.                                 case 168:num1=smg_num[1];num=smg_num[7];BEEP = volState; break;//按键'DOWN'
  125.                                 case 144:num1=smg_num[1];num=smg_num[8];BEEP = volState; break;//按键'VOL+'
  126.                         }
  127.                  }else
  128.                  {
  129.                         BEEP=1;
  130.                  }

  131.                  if(volState)
  132.                         strcpy(TEXT_Buffer,"true");
  133.                  else
  134.                         strcpy(TEXT_Buffer,"false");
  135.                
  136.                 keyLocal=KEY_Scan(0);
  137.                 if(keyLocal==WKUP_PRES)//WK_UP 按下,写入24C02
  138.                 {
  139.                         printf("\r\nStart Write 24C02....\r\n");
  140.                         AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
  141.                         printf("24C02 Write Finished!\r\n");//提示传送完成
  142.                         printf("\r\nStart Read 24C02....\r\n");
  143.                         AT24CXX_Read(0,datatemp,SIZE);
  144.                         printf("The Data Readed Is:\r\n");//提示传送完成
  145.                         printf("%s\r\n",datatemp);//显示读到的字符串
  146.                 }

  147.                  
  148.                 HAL_Delay(1);
  149.                  t++;
  150.                 if(t==250)//LED0每500MS闪烁
  151.                 {
  152.                         t=0;
  153.                         LED0=!LED0;
  154.                 }
  155.         }  
  156. }


  157. //定时器4中断服务函数调用
  158. void TIM4_IRQHandler(void)
  159. {
  160.                  if(__HAL_TIM_GET_IT_SOURCE(&TIM4_Handler, TIM_IT_UPDATE) !=RESET)
  161.                  {
  162.                          __HAL_TIM_CLEAR_IT(&TIM4_Handler, TIM_IT_UPDATE);

  163.                  }
  164.                  if(smg_wei==6)//数码管位
  165.                  {
  166.                          smg_duan = num1;
  167.                  }
  168.                  else if(smg_wei==7)
  169.                  {
  170.                          smg_duan = num;
  171.                  }
  172.                  if(smg_flag)
  173.                          LED_Write_Data(0x00,smg_wei);//消除鬼影(段码不显示)
  174.                  else           
  175.                          LED_Write_Data(smg_duan,smg_wei);//正常显示
  176.                  LED_Refresh();//数码管数据更新
  177.                  smg_flag=!smg_flag;
  178.                  if(smg_flag==0)//正常显示才更新位码
  179.                  {
  180.                          smg_wei++;
  181.                      if(smg_wei==8) smg_wei=6;
  182.                  }         
  183. }
复制代码

4 实验结果
实验结果如下,所有逻辑操作正确

B5QG_W23{@ZQPT3J301TEOG.png

串口显示信息,声音按键设置可以正常保存,复位或者断电重启后并不会消失。

1OJOS1R`9QVBAU)QW}RF}MF.png

5 额外的TIPS
调整LED亮度的几种方式
1,电路方法:减小限流电阻阻值,从而增大LED的电流,达到增加亮度目的。
2,软件方法:增加LED在单位时间内的总亮时长,方式有两种,增加刷新频率以及增大单个刷新周期内的点亮时间。
3,物理方法:如果LED有透光保护膜,增加透光膜的透明度。


收藏 评论0 发布时间:2022-5-5 17:42

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版