找回密码
 立即注册
查看: 535|回复: 1

基于8G单片机的手机蓝牙温控程序

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:302
  • 最近打卡:2025-05-02 05:18:21
已绑定手机

3

主题

17

回帖

972

积分

高级会员

积分
972
发表于 2025-1-16 22:09:43 | 显示全部楼层 |阅读模式
基于8G单片机的手机蓝牙温控程序
   手机(安卓版)通过蓝牙与单片机通信,1秒钟读取1次温度数据与运行参数,也可以
设置参数,单片机程序中参考了国芯抡坛上的STC8G系列-串口相关程序,的一个例程,串口1中断收发-C语言-MODBUS协议,原贴链接(https://www.stcaimcu.com/forum.p ... &extra=page%3D1)硬件电路如下:
原理图.png

实物图1 .png


实物图2 .png

实物图如上,温度传感器置于冰箱冷冻室内,蓝牙串口模块型号是大厦龙雀的BT-04E
,模块资料可在大厦龙雀官网上下载。单片机主时钟22.1184M,串口波特率96008位数据位,1个停止位,无校验。
手机APP界面如下图:

手机界面1.png


手机界面2.png
用C#做了个串口操作工具,可以用电脑串口来直接读写数据,运行界面如下:
电脑串口界面1.png

电脑串口界面2.png

部分程序源码如下:
  1. voidmain()                                //程序开始运行的入口
  2. {
  3.        u8   i;
  4.        u16  crc;
  5.        u8 LED_Data = 0XFE;   
  6.        u8 num=0;
  7.        u8 LED_DataTab[8] = { 0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};  
  8.   int TempVal,TempValb;        //TempVal大于0的温度, TempValb小于0的温度
  9.    sys_init();         //IO口初始化
  10.     P1M0 = 0x00;       //设置P1.0为ADC口
  11.     P1M1 = 0x01;
  12.     ydsx=-250;
  13.         ydxx=150;
  14.         ydjz=0;
  15.     P_SW2|=0x80;
  16.     ADCTIM=0x3f;//设置ADC内部程序
  17.     P_SW2&=0x7f;
  18.     ADCCFG=0x2f;//设置ADC时钟为系统时钟/2/16
  19.     ADC_CONTR=0x80;//使能ADC选P10为ADC通道
  20.     //EEPROM读操作,读取第0扇区,10 12 14字节-------------------
  21.         ydsx=IapRead(SECTOR0 + 10); //从EEPROM第0扇区10字节取温度上限值
  22.     ydxx=IapRead(SECTOR0 + 12); //从EEPROM第0扇区12字节取温度下限值
  23.         ydjz=IapRead(SECTOR0 + 14); //从EEPROM第0扇区14字节取温度校准值
  24.     modbus_reg[0]= ydsx;
  25.     modbus_reg[1]= ydxx;
  26.         modbus_reg[2]= ydjz;
  27.         Timer0_Config(0, MAIN_Fosc / 20000);   //t=0:reload值是主时钟周期数, (中断频率, 20000次/秒)
  28.       UART1_config(9600UL,1, 0);       // brt: 通信波特率,  timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特
  29.         BEEP = 0;             //上电蜂鸣响一声
  30.         delay_ms(10);       //延时10ms
  31.         BEEP = 1;             //关闭蜂鸣响
  32.     tm1650_start();
  33.     write_byte(0x48);  //数码显示模式
  34.     tm1650_ack();
  35.     write_byte(0x31);  //3级亮度,开显示。这里的指令数据 详情参阅TM1650的datasheet
  36.     tm1650_ack();
  37.     tm1650_end();
  38.     tm1650_start();
  39.     write_byte(0x68);
  40.     tm1650_ack();
  41.     write_byte(Num_Buff[1]);//数码管千位上电显示1
  42.     tm1650_ack();
  43.     tm1650_end();
  44.     tm1650_start();
  45.     write_byte(0x6a);
  46.     tm1650_ack();
  47.     write_byte(Num_Buff[8]);//数码管百位上电显示8
  48.     tm1650_ack();
  49.     tm1650_end();
  50.     tm1650_start();
  51.     write_byte(0x6c);
  52.     tm1650_ack();
  53.     write_byte(Num_Buff[8]);  //数码管十位上电显示8
  54.     tm1650_ack();
  55.     tm1650_end();
  56.     tm1650_start();
  57.     write_byte(0x6e);
  58.     tm1650_ack();
  59.     write_byte(Num_Buff[8]);  //数码管个位上电显示8
  60.     tm1650_ack();
  61.     tm1650_end();
  62.         Timer0_Config(0, MAIN_Fosc / 20000);   //t=0:reload值是主时钟周期数, (中断频率, 20000次/秒)
  63.         UART1_config(9600UL, 1, 0);   //brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值:使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1,  =1: 切换到P3.6 P3.7, =2:切换到P1.6 P1.7, =3: 切换到P4.3 P4.4.
  64.     EA = 1;
  65.         while(1)                     //无限循环
  66.          {
  67.      if(B_RX1_OK && !B_TX1_Busy)  //收到数据, 进行MODBUS-RTU协议解析
  68.           {
  69.                       if(MODBUS_CRC16(RX1_Buffer, RX1_cnt) == 0)      //首先判断CRC16是否正确, 不正确则忽略, 不处理也不返回信息
  70.                       {
  71.                             if((RX1_Buffer[0] ==0x00) || (RX1_Buffer[0] == SL_ADDR))     //然后判断站号地址是否正确, 或者是否广播地址(不返回信息)
  72.                             {
  73.                                    if(RX1_cnt> 2) RX1_cnt -= 2;      //去掉CRC16校验字节
  74.                                    i =MODBUS_RTU();      //MODBUS-RTU协议解析
  75.                                    if(i != 0)  //错误处理
  76.                                    {
  77.                                           TX1_Buffer[0]= SL_ADDR;   //站号地址
  78.                                           TX1_Buffer[1]= i;                //错误代码
  79.                                           crc =MODBUS_CRC16(TX1_Buffer, 2);
  80.                                           TX1_Buffer[2]= (u8)crc;       //CRC是小端模式, 先发低字节,后发高字节。
  81.                                           TX1_Buffer[3]= (u8)(crc>>8);
  82.                                           B_TX1_Busy= 1;           //标志发送忙
  83.                                           TX1_cnt    = 0;           //发送字节计数
  84.                                           TX1_number= 4;         //要发送的字节数
  85.                                           TI =1;                          //启动发送
  86.                                    }
  87.                             }
  88.                      }
  89.                        ydsx= modbus_reg[0];
  90.         ydxx=modbus_reg[1];
  91.             ydjz=modbus_reg[2];
  92.                      RX1_cnt = 0;
  93.                      B_RX1_OK = 0;
  94.               }
  95.         Test();          //按键查询处理
  96.     // delay_ms(500);    //延时300ms
  97.               if(TIM_Flag)//TIME0中断10000次(1秒)读一次温度
  98.               {
  99.                  ADC_CONTR|=0x40; //启动AD
  100.         _nop_();
  101.         _nop_();
  102.         while(!(ADC_CONTR&0x20)) ;     //查询ADC完成标志
  103.         ADC_CONTR &= ~0x20;           //清完成标志
  104.         //ADCCFG = 0x00;                  //设置结果左对齐(会出问题原因不详)
  105.                 ADCCFG = 0x20;                  //设置结果右对齐
  106.         Temp=(ADC_RES << 8) |ADC_RESL;     //读取ADC结果
  107.             TempVal = Temp_Cal(Temp)+ydjz; //ADC结果计算成温度值并加上校准值
  108.                  //TempVal = Temp_Cal(Temp);   //ADC结果计算成温度值
  109.                  modbus_reg[3]= TempVal;  //温度值写入xdata1003
  110.                  //TempVal = Temp;      //ADC结果计算成温度值
  111.             if(Run_Flag==0)   //如果是制冷模式
  112.             {   
  113.                     if(TempVal<= ydxx)//实际温度低于温度下限
  114.                 {
  115.                         Relay=1;       //关闭继电器(关闭制冷)
  116.                  }
  117.               if(TempVal>= ydsx) //实际温度高于温度上限
  118.                 {
  119.                          Relay=0;        //打开继电器(启动制冷)
  120.                  }
  121.              }
  122.           else                     //否则是制热模式
  123.            {
  124.                if(TempVal<= ydxx)    //实际温度低于温度下限
  125.                  {
  126.                           Relay=0;         //打开继电器(启动加热)
  127.                  }
  128.                if(TempVal>= ydsx)    //实际温度高于温度上限
  129.                    {  
  130.                          Relay=1;      //关闭继电器(关闭加热)
  131.                    }      
  132.             }
  133.                                      modbus_reg[4]= Relay;     ////////继电器状态写入xdata1004                                          
  134.            if(TempVal>= 0) //温度在0度以上
  135.             {
  136.                    SEG0 = TempVal/1000%10;     //温度千位
  137.                               if (SEG0==0)
  138.                                 SEG0=23;              //千位为0时,消隐不显        
  139.                       SEG1 = TempVal/100%10;      //温度百位
  140.                       SEG2 = TempVal/10%10;       //温度十位
  141.                       SEG3 = TempVal/1%10;        //温度个位
  142.                       DspTemp();                 //显示温度     
  143.                 }
  144.            else            //温度在0度以下
  145.              {   
  146.                      TempValb=abs(TempVal); //取温度绝对值
  147.                      SEG0 = 22;                   //千位显示“-”
  148.                      SEG1 = TempValb/100%10;          //温度百位  
  149.                      SEG2 = TempValb/10%10;       //温度十位
  150.                      SEG3 = TempValb/1%10;        //温度个位
  151.                      DspTemp();
  152.                }
  153.                                    TIM_Flag=0;
  154.        }
  155.         }
  156. }
  157. //==========================================================
  158. // 函数: void UART1_ISR (void) interrupt UART1_VECTOR
  159. // 描述: 串口1中断函数
  160. // 参数: none.
  161. // 返回: none.
  162. // 版本: VER1.0
  163. // 日期: 2018-4-2
  164. // 备注:
  165. //==========================================================
  166. voidUART1_ISR (void) interrupt UART1_VECTOR
  167. {
  168.        if(RI)
  169.        {
  170.               RI = 0;
  171.               if(!B_RX1_OK) //接收缓冲空闲
  172.               {
  173.                      if(RX1_cnt >=RX1_Length)  RX1_cnt = 0;
  174.                      RX1_Buffer[RX1_cnt++] =SBUF;
  175.                      RX1_TimeOut = 36;      //接收超时计时器, 35个位时间
  176.               }
  177.        }
  178.        if(TI)
  179.        {
  180.               TI = 0;
  181.               if(TX1_number != 0)     //有数据要发
  182.               {
  183.                      SBUF =TX1_Buffer[TX1_cnt++];
  184.                      TX1_number--;
  185.               }
  186.               else B_TX1_Busy = 0;
  187.        }
  188. }
  189. voidDspTemp()
  190. {
  191.         write_byte(0x48);  //数码显示模式
  192.     tm1650_ack();
  193.     write_byte(0x11);  //1级亮度,开显示。这里的指令数据 详情参阅TM1650的datasheet
  194.     tm1650_ack();
  195.     tm1650_end();
  196.     tm1650_start();
  197.     write_byte(0x68);
  198.     tm1650_ack();
  199.     write_byte(Num_Buff[ SEG0]);//显示千位
  200.     tm1650_ack();
  201.     tm1650_end();
  202.     tm1650_start();
  203.     write_byte(0x6a);
  204.     tm1650_ack();
  205.     write_byte(Num_Buff[ SEG1]);//显示百位
  206.     tm1650_ack();
  207.     tm1650_end();
  208.     tm1650_start();
  209.     write_byte(0x6c);
  210.     tm1650_ack();
  211.     write_byte(Num_Buff[ SEG2]+0x80);//显示十位加小数点
  212.     tm1650_ack();
  213.     tm1650_end();
  214.     tm1650_start();
  215.     write_byte(0x6e);
  216.     tm1650_ack();
  217.     write_byte(Num_Buff[ SEG3]);  //显示个位
  218.     tm1650_ack();
  219.     tm1650_end();        
  220. }
复制代码

实物图2 .png

基于STC8G单片机的手机蓝牙温控程序.7z

23.02 KB, 下载次数: 41

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:424
  • 最近打卡:2025-05-03 00:02:01
已绑定手机

19

主题

3191

回帖

4876

积分

论坛元老

积分
4876
发表于 2025-1-16 23:40:25 | 显示全部楼层
大夏龙雀的蓝牙模块
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 01:02 , Processed in 0.115879 second(s), 55 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表