找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3002|回复: 1
收起左侧

1602液晶显示用于产品的LM75A温控制器STC15F104E MCU源码

[复制链接]
ID:358930 发表于 2018-11-24 03:03 | 显示全部楼层 |阅读模式
微型贴片单片机STC15F104E单片机做的LM75A温控制器,带1602液晶显示器,有温度设置。用最小的单片机做最多的功能

制作出来的实物图如下:
20181124_022450.jpg

单片机源码:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit sda=P3^1;
  6. sbit scl=P3^0;

  7. void delay()        //@11.0592MHz  stc12(100us)
  8. {
  9.         unsigned char i, j;

  10.         i = 2;
  11.         j = 15;
  12.         do
  13.         {
  14.                 while (--j);
  15.         } while (--i);
  16. }

  17. void delay1(uint x)//@11.0592MHz  stc12(1ms)
  18. {
  19. unsigned char i, j;

  20.         _nop_();
  21.         i = 11;
  22.         j = 190;
  23.         do
  24.         {
  25.                 while (--j);
  26.         } while (--i);
  27. }
  28. /* ***************************************************** */
  29. // 起别名定义
  30. /* ***************************************************** */
  31. typedef unsigned char uChar8;
  32. typedef unsigned int  uInt16;
  33. typedef enum{FALSE,TRUE} BOOL;
  34. /* ***************************************************** */
  35. // 宏定义
  36. /* ***************************************************** */
  37. #define LM75ADevIDAddr 0x90         
  38. #define IIC_WRITE 0x00
  39. #define IIC_READ  0x01
  40. /* ***************************************************** */
  41. // 位定义
  42. /* ***************************************************** */
  43. sbit SCL = P3^2;//绿色线
  44. sbit SDA = P3^3;//白色线
  45. long int LM75WD;
  46. long int SET=28000; //28.000度  


  47. //sbit led1=P3^0;//温度灯报警
  48. //sbit led2=P3^1;//压力灯报警

  49. sbit OUT=P3^5;//控制器输出

  50. sbit IN=P3^4;//开关输入设置温度
  51. /* ***************************************************** */
  52. // 全局变量定义
  53. /* ***************************************************** */
  54. bit p_bH0L_Flag;                                        // 温度"0"上、下标志位
  55. float p_fLM75ATemp;                                        // 温度值

  56. /* ***************************************************** */
  57. // 函数名称:Delay5US()
  58. // 函数功能:微秒延时
  59. // 入口参数:延时微秒数(ValUS)
  60. // 出口参数:无
  61. /* ***************************************************** */
  62. void Delay5US(void)
  63. {
  64.        unsigned char i;

  65.         _nop_();
  66.         i = 11;
  67.         while (--i);
  68. }
  69. /* ***************************************************** */
  70. // 函数名称:DelayMS()
  71. // 函数功能:毫秒延时
  72. // 入口参数:延时毫秒数(ValMS)
  73. // 出口参数:无
  74. /* ***************************************************** */
  75. void DelayMS(uInt16 ValMS)
  76. {
  77.        unsigned char i, j;

  78.         _nop_();
  79.         _nop_();
  80.         _nop_();
  81.         i = 11;
  82.         j = 190;
  83.         do
  84.         {
  85.                 while (--j);
  86.         } while (--i);
  87. }



  88. /* ***************************************************** */
  89. // 函数名称:IIC_Start()
  90. // 函数功能:IIC起动
  91. // 入口参数:无
  92. // 出口参数:无
  93. /* ***************************************************** */
  94. void IIC_Start(void)
  95. {
  96.         SDA = 1;
  97.         Delay5US();
  98.         SCL = 1;
  99.         Delay5US();
  100.         SDA = 0;
  101.         Delay5US();
  102. }
  103. /* ***************************************************** */
  104. // 函数名称:IIC_Stop()
  105. // 函数功能:IIC停止
  106. // 入口参数:无
  107. // 出口参数:无
  108. /* ***************************************************** */
  109. void IIC_Stop(void)                     
  110. {
  111.         SDA = 0;
  112.         Delay5US();
  113.         SCL = 1;
  114.         Delay5US();
  115.         SDA =1;
  116. }
  117. /* ***************************************************** */
  118. // 函数名称:IIC_Ack()
  119. // 函数功能:IIC应答
  120. // 入口参数:无
  121. // 出口参数:无
  122. /* ***************************************************** */
  123. void IIC_Ack(void)                     
  124. {
  125.         SCL = 0;                                // 为产生脉冲准备
  126.         SDA = 0;                                // 产生应答信号
  127.         Delay5US();                                // 延时你懂得
  128.         SCL = 1;Delay5US();  
  129.         SCL = 0;Delay5US();                // 产生高脉冲
  130.         SDA = 1;                                // 释放总线
  131. }
  132. /* ***************************************************** */
  133. // 函数名称:IIC_RdAck()
  134. // 函数功能:读IIC应答
  135. // 入口参数:无
  136. // 出口参数:是否应答真值
  137. /* ***************************************************** */
  138. BOOL IIC_RdAck(void)                     
  139. {
  140.         BOOL AckFlag;
  141.         uChar8 uiVal = 0;
  142.         SCL = 0;Delay5US();   
  143.         SDA = 1;
  144.         SCL = 1;Delay5US();
  145.         while((1 == SDA) && (uiVal < 255))
  146.         {
  147.                 uiVal ++;
  148.                 AckFlag = SDA;
  149.         }
  150.         SCL = 0;  
  151.         return AckFlag;                // 应答返回:0;不应答返回:1
  152. }
  153. /* ***************************************************** */
  154. // 函数名称:IIC_Nack()
  155. // 函数功能:IIC不应答
  156. // 入口参数:无
  157. // 出口参数:无
  158. /* ***************************************************** */
  159. void IIC_Nack(void)                    
  160. {   
  161.         SDA = 1;
  162.         SCL = 0;Delay5US();      
  163.         SCL = 1;Delay5US();      
  164.         SCL = 0;
  165. }
  166. /* ***************************************************** */
  167. // 函数名称:OutputOneByte()
  168. // 函数功能:从IIC器件中读出一个字节
  169. // 入口参数:无
  170. // 出口参数:读出的一个字节(uByteVal)
  171. /* ***************************************************** */
  172. uChar8 OutputOneByte(void)        
  173. {
  174.         uChar8 uByteVal = 0;
  175.         uChar8 iCount;
  176.         SDA = 1;
  177.         for (iCount = 0;iCount < 8;iCount++)
  178.         {
  179.                 SCL = 0;
  180.                 Delay5US();
  181.                 SCL = 1;
  182.                 Delay5US();
  183.                 uByteVal <<= 1;
  184.                 if(SDA)
  185.                         uByteVal |= 0x01;
  186.         }         
  187.         SCL = 0;
  188.         return(uByteVal);
  189. }
  190. /* ***************************************************** */
  191. // 函数名称:InputOneByte()
  192. // 函数功能:向IIC器件写入一个字节
  193. // 入口参数:待写入的一个字节(uByteVal)
  194. // 出口参数:无
  195. /* ***************************************************** */
  196. void InputOneByte(uChar8 uByteVal)
  197. {
  198.     uChar8 iCount;
  199.     for(iCount = 0;iCount < 8;iCount++)
  200.         {  
  201.                 SCL = 0;
  202.                 Delay5US();                        
  203.                 SDA = (uByteVal & 0x80) >> 7;
  204.                 Delay5US();         
  205.                 SCL = 1;
  206.                 Delay5US();
  207.                 uByteVal <<= 1;
  208.     }
  209.         SCL = 0;            
  210. }
  211. /* ***************************************************** */
  212. // 函数名称:IIC_WrDevAddAndDatAdd()
  213. // 函数功能:向IIC器件写入器件和数据地址
  214. // 入口参数:器件地址(uDevAdd),数据地址(uDatAdd)
  215. // 出口参数:写入是否成功真值
  216. /* ***************************************************** */
  217. BOOL IIC_WrDevAddAndDatAdd(uChar8 uDevAdd,uChar8 uDatAdd)
  218. {
  219.         IIC_Start();                        // 发送开始信号
  220.         InputOneByte(uDevAdd);        // 输入器件地址
  221.         IIC_RdAck();                          // 读应答信号
  222.         InputOneByte(uDatAdd);        // 输入数据地址
  223.         IIC_RdAck();                        // 读应答信号
  224.         return TRUE;         
  225. }
  226. /* ***************************************************** */
  227. // 函数名称:IIC_RdDatFromAdd()
  228. // 函数功能:向IIC器件读数据
  229. // 入口参数:器件ID(uDevID)、数据存储地址(uStaAddVal)
  230. //                         待存数据(*p)、连续存储数据的个数(uiLenVal)
  231. // 出口参数:无
  232. /* ***************************************************** */
  233. void IIC_RdDatFromAdd(uChar8 uDevID, uChar8 uStaAddVal, uChar8 *p, uChar8 uiLenVal)
  234. {                                                   
  235.         uChar8 iCount;
  236.         IIC_WrDevAddAndDatAdd(uDevID | IIC_WRITE,uStaAddVal);  
  237.         IIC_Start();
  238.         InputOneByte(uDevID | IIC_READ);
  239.         // IIC_READ 为写命令后缀符
  240.         IIC_RdAck();     
  241.         for(iCount = 0;iCount < uiLenVal;iCount++)
  242.         {
  243.                 *p++ = OutputOneByte();
  244.                    if(iCount != (uiLenVal - 1))
  245.                         IIC_Ack();                 
  246.         }      
  247.         IIC_Nack();        
  248.         IIC_Stop();         
  249. }
  250. /* ***************************************************** */
  251. // 函数名称:LM75A_ReadReg()
  252. // 函数功能:读LM75A任意寄存器值
  253. // 入口参数:寄存器地址(addr),uLenVal,读出字节的长度
  254. // 出口参数:寄存器内容(*val)
  255. /* ***************************************************** */
  256. void LM75A_ReadReg(uChar8 addr, uChar8 *val, uChar8 uLenVal)
  257. {
  258.         IIC_RdDatFromAdd(LM75ADevIDAddr, addr, val, uLenVal);
  259. }
  260. /* ***************************************************** */
  261. // 函数名称:LM75A_TempConv()
  262. // 函数功能:温度转换
  263. // 入口参数:无
  264. // 出口参数:无
  265. /* ***************************************************** */
  266. void LM75A_TempConv(void)
  267. {
  268.         uChar8 TempML[2]={0};                                                // 临时数值,用于存放Temp的高低字节
  269.         uInt16 uiTemp;                                                                // 用于存放Temp的11位字节数据
  270.         LM75A_ReadReg(0x00,TempML,2);                                // 读出温度,并存于数组TempHL中
  271.         uiTemp = (uInt16)TempML[0];                                        // 将高字节存入变量uiTemp中
  272.         uiTemp = (uiTemp << 8 | TempML[1]) >> 5;        // 接着并入后3位,最后右移5位就是11位补码数(8+3共11位)
  273.         /* ***** 首先判断温度是“0上”还是是“0下” ***** */        
  274.         if(!(TempML[0] & 0x80))                                                // 最高位为“0”则为“0上”
  275.         {
  276.                 p_bH0L_Flag = 0;
  277.                 p_fLM75ATemp = uiTemp * 0.125;        
  278.         }
  279.         else                                                                                // 这时为“0下”(p_fLM75ATemp)℃
  280.         {
  281.                 p_bH0L_Flag = 1;
  282.                 p_fLM75ATemp = (0x800 - uiTemp) * 0.125;// 由于计算机中负数是以补码形式存的,所以有这样的算法。
  283.         }
  284. }

  285. /********************************1602**************************************/
  286. void start() //开始信号
  287. {
  288. sda=1;
  289. delay();
  290. scl=1;
  291. delay();
  292. sda=0;
  293. delay();
  294. }
  295. void stop() //停止
  296. {
  297. sda=0;
  298. delay();
  299. scl=1;
  300. delay();
  301. sda=1;
  302. delay();
  303. }
  304. void respons() //应答
  305. {
  306. uchar i;
  307. scl=1;
  308. delay();
  309. while((sda==1)&&(i<250))i++;
  310. scl=0;
  311. delay();
  312. }
  313. void init()
  314. {
  315. sda=1;
  316. delay();
  317. scl=1;
  318. delay();
  319. }
  320. void write_byte(uchar date)
  321. {
  322. uchar i,temp;
  323. temp=date;
  324. for(i=0;i<8;i++)
  325. {
  326. temp=temp<<1;
  327. scl=0;
  328. delay();
  329. sda=CY;
  330. delay();
  331. scl=1;
  332. delay();
  333. }
  334. scl=0;
  335. delay();
  336. sda=1;
  337. delay();
  338. }

  339. void write_add(uchar date1)
  340. {
  341. start();
  342. write_byte(0x4e); //8574A 地址+写入 (8574 地址+写入0x4e)//0x27+0x27=0x4e//全部空0x3f+0x3f=0x7e
  343. respons();
  344. write_byte(date1);                                                                                                         
  345. respons();
  346. stop();
  347. }                                                                                                                                                                                          
  348. void write_com(uchar com)        //写命令函数
  349. {        uchar com1,com2;
  350. com1=com|0x0f;
  351. write_add(com1&0xfc);
  352. delay1(2);
  353. write_add(com1&0xf8);
  354. com2=com<<4;
  355. com2=com2|0x0f;
  356. write_add(com2&0xfc);
  357. delay1(2);
  358. write_add(com2&0xf8);
  359. }
  360. void write_date(uchar date)        //写数据函数
  361. {
  362. uchar date1,date2;
  363. date1=date|0x0f;
  364. write_add(date1&0xfd);
  365. delay1(2);
  366. write_add(date1&0xf9);
  367. date2=date<<4;
  368. date2=date2|0x0f;
  369. write_add(date2&0xfd);
  370. delay1(2);
  371. write_add(date2&0xf9);
  372. }
  373. void write_zfc(uchar *p)//定义一个带指针的函数?(字符串)
  374. {
  375.         while(*p!=0)//不能用";"
  376.         write_date(*p++);
  377. }
  378. void init_lcd()        //初始化函数
  379. {
  380. write_add(0x08);        //默认开始状态为关使能端,见时序图 选择状态为 写
  381. write_com(0x0f);
  382. write_com(0x28);        //显示模式设置 0x28中高位2,设置4线。
  383. write_add(0x0c);
  384. write_add(0x08);        //使能4线
  385. write_com(0x28);        //显示模式设置,为0x28。
  386. write_com(0x01);        //显示清屏,将上次的内容清除,默认为0x01.
  387. write_com(0x0c);        //显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
  388. write_com(0x06);        //设置光标状态默认0x06,为读一个字符光标加1.
  389. }

  390. void display(long temp)        //显示函数
  391. {

  392. uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
  393.         //temp=12345678;
  394.         dt1 = temp%10;//1位
  395.         dt2 = temp%100/10;//2位
  396.         dt3 = temp%1000/100;//3位
  397.         dt4 = temp%10000/1000;//4位

  398.         dt5 = temp%100000/10000;//5位
  399.         dt6 = temp%1000000/100000;//6位
  400.         dt7 = temp%10000000/1000000;//7位
  401.         dt8 = temp/10000000;//8位             最高位                                                                                                           
  402.         write_com(0xC0); //第1行
  403.         write_zfc("WD:");
  404.         //write_date(dt8+0x30);
  405.         //write_date(dt7+0x30);
  406.         //write_date(dt6+0x30);
  407.         write_date(dt5+0x30);
  408.         write_date(dt4+0x30);
  409.         write_zfc(".");
  410.         write_date(dt3+0x30);
  411.         write_date(dt2+0x30);
  412.         //write_date(dt1+0x30);
  413.         write_zfc("C");
  414.                
  415. }
  416. void display2(long temp)        //显示函数
  417. {

  418. uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
  419.         //temp=12345678;
  420.         dt1 = temp%10;//1位
  421.         dt2 = temp%100/10;//2位
  422.         dt3 = temp%1000/100;//3位
  423.         dt4 = temp%10000/1000;//4位

  424.         dt5 = temp%100000/10000;//5位
  425.         dt6 = temp%1000000/100000;//6位
  426.         dt7 = temp%10000000/1000000;//7位
  427.         dt8 = temp/10000000;//8位             最高位                                                                                                           
  428.         write_com(0xc0+10); //第1行
  429.         write_zfc("SET:");
  430.         //write_date(dt8+0x30);
  431.         //write_date(dt7+0x30);
  432.         //write_date(dt6+0x30);
  433.         write_date(dt5+0x30);
  434.         write_date(dt4+0x30);
  435.         //rite_zfc(".");
  436.         //write_date(dt3+0x30);
  437.         //write_date(dt2+0x30);
  438.         //write_date(dt1+0x30);
  439.         write_zfc("C");
  440.                
  441. }
  442. void main()
  443. {      

  444.     init_lcd();
  445.           OUT=1;//启动时关一下
  446.       
  447.         while(1)
  448.         {
  449.                  
  450.                
  451.                  LM75A_TempConv();//读取温度LM75A  
  452.                  DelayMS(200);                              
  453.                  LM75WD = p_fLM75ATemp * 1000;// 将温度全部转换成整数,以便数码管显示                                       
  454.            init();         //通讯1602
  455.             display(LM75WD); // 显示1602
  456.                  display2(SET); // 显示1602
  457.                  if(IN==0)//设置温度
  458.      {
  459.                          SET=SET+1000;
  460.                         if(SET>99999)//设置温度
  461.                         SET=28000;      
  462.                  }
  463.                  
  464.                
  465.                 if(LM75WD>=SET)// 温度30
  466.      {
  467.                         OUT=0;
  468.                   write_com(0x80); //第1行
  469.                         write_zfc("OUT:OFF");//220V电源关闭               
  470.                           
  471.                  }
  472.                  else{
  473.                         if(LM75WD<=SET-1000)// 温度回落1.000度后再执行,防闪烁
  474.                         {
  475.                  OUT=1;
  476.                  write_com(0x80); //第1行
  477.                  write_zfc("OUT: ON");//220V电源输出                              
  478.                  }
  479.                 else      
  480.                  {
  481.                         OUT=0;
  482.                   write_com(0x80); //第1行
  483.                         write_zfc("OUT:OFF");//220V电源关闭                 
  484.                  }         
  485.          }
  486.          
  487.          
  488.         }
  489. }
复制代码

全部资料51hei下载地址:
1602显串STC15F104E LM75A温度OK3(0x4e).zip (67.22 KB, 下载次数: 48)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1088279 发表于 2023-7-16 09:39 | 显示全部楼层
如果需要将收集的数据传输到电脑上,该如何操作
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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