找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3607|回复: 24
收起左侧

单片机+aip650做一个孵化器的温控,按键响应不知怎么搞求助

[复制链接]
ID:680729 发表于 2022-11-2 21:05 | 显示全部楼层 |阅读模式
aip650做一个孵化器的温控,温度显示搞定了,按键响应不知怎么搞。有会的吗?请高手指点下。

单片机源程序如下:
  1. #include <absacc.h>
  2. #include <intrins.h>
  3. #include <STC89C5xRC.H>


  4. //定义常量
  5. #define true  1
  6. #define false 0


  7. #define  uchar unsigned char
  8. #define  uint  unsigned int




  9. //定义变量
  10. uchar  Display_Code[12] ={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf7,0xd7,0x08,0x02}; //段码
  11.                                  //0,    1,   2 ,  3,  4,    5,   6,   7,   8,    9,  . ,  -
  12. uchar  Dig_Bit_Code[4]={0x6a,0x6e,0x6c,0x68};//位码
  13. uchar   Light_Level_Code[8]={0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01 };//亮度调节






  14. uint     h; //温度使用
  15. uint     temp;//温度
  16. //**************温度小数部分用查表法***********//
  17. uchar  ditab[16]=
  18. {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
  19. uchar  temp_data[2]={0x00,0x00};             //读出温度暂放
  20. uchar  display[5]={0x00,0x00,0x00,0x00,0x00};     //显示单元数据,共4个数据和一个运算暂用
  21.                                                    
  22. //定义IO口
  23. sbit        SDA=P3^6;
  24. sbit        SCL=P3^7;              




  25. sbit     DQ=P1^0;                               //温度输入口
  26. sbit     DIN=P1^1;                              //LED小数点控制
  27. //函数声名
  28. /*温度使用*/
  29. void delay(uint t);
  30. void work_temp(uint tem);
  31. read_temp();
  32. void xiashiwendu(uint tem1);
  33. uchar read_byte(void);
  34. void write_byte(uchar val);
  35. void ow_reset(void);






  36. /*I2C相关*/
  37. void I2CWait(void);
  38. bit  I2CStart(void);
  39. void I2CStop(void);
  40. void I2CSendAck(void);
  41. void I2CSendNoAck(void);
  42. bit  I2CWaitAck(void);
  43. unsigned char AipReadKey();
  44. void I2CSendByte(unsigned char demand,bit order);
  45. unsigned char I2CReceiveByte(void);
  46. //void Delay(unsigned int nn);
  47. void AiP650_CLR();
  48. void AiP650_DisPlay(unsigned char Dig_Bit,unsigned char Display_num);
  49. void AiP650_Set(unsigned char add,unsigned char dat);//数码管显示
  50. void Delay(unsigned int nn);
  51. void Light_Level_Set(unsigned char level);
  52. void xianshijianzhi(uint key);
  53. /*******************************************************
  54. 功能:主函数
  55. 描述:初始化、读温度显示,读键值处理
  56. 参数:无
  57. 返回:无
  58. ********************************************************/
  59. main()
  60. {unsigned char keyvalue;
  61.                
  62.         P3=0xFF;
  63.         
  64.         while(1)
  65.         {
  66.                  uint wendu;//温度变量
  67.                 uint maxwd=40.0;//停止温度
  68.                 uint minwd=30.0;//开始温度
  69.                
  70.                 //AiP650_CLR();
  71.                 wendu=read_temp();
  72.                 xiashiwendu(wendu);
  73.                  
  74.                 keyvalue=AipReadKey();
  75.                 //if(keyvalue==0x44)
  76.    // xianshijianzhi(keyvalue);
  77.                 //if(keyvalue!=0x2e)
  78.                 //{ delay(2000);
  79.                 //if(keyvalue!=0x2e)
  80.      switch(keyvalue)
  81.                          {case 0x47:
  82.                                  Light_Level_Set(4);
  83.                                  AiP650_DisPlay(1,1);
  84.                   
  85.                                           case  0x57:
  86.                                                  Light_Level_Set(4);
  87.                                          AiP650_DisPlay(1,2);
  88.                  
  89.                                          case 0x5f:                           
  90.                                                 Light_Level_Set(4);
  91.                                          AiP650_DisPlay(1,3);
  92.                
  93.                                           case 0x67:  
  94.                                                 Light_Level_Set(4);
  95.                                          AiP650_DisPlay(1,4);
  96.                   
  97.                                           case 0x6f:
  98.                                                  Light_Level_Set(4);
  99.                                          AiP650_DisPlay(1,5);
  100.                    case 0x6c:
  101.                  Light_Level_Set(4);
  102.                          AiP650_DisPlay(1,6);
  103.                           
  104.                          case 0x77:  
  105.                  Light_Level_Set(4);
  106.                          AiP650_DisPlay(1,7);
  107.                   case 0x6e:  
  108.                                 Light_Level_Set(4);
  109.                         AiP650_DisPlay(1,8);
  110.                   
  111.                                                                   
  112.                          break;
  113.                  
  114.                         
  115.                         
  116.                         
  117.                          ; }                        
  118.                 }
  119.                
  120.         /*        unsigned char i;for(i=0;i<12;i++)
  121.                 {
  122.                         AiP650_DisPlay(1,i);
  123.                 AiP650_DisPlay(2,i);
  124.                         AiP650_DisPlay(3,i);
  125.                         Light_Level_Set(4);*/
  126.                  //此处添加显示程序,可参考5、6、7章
  127.    // delay(500);}     
  128.          
  129.    }


  130. /*******************************************************
  131. 功能:I2CWait
  132. 描述:I2C延时
  133. 参数:无
  134. 返回:无
  135. ********************************************************/
  136. void I2CWait(void)
  137. {        
  138.         _nop_();_nop_();_nop_();_nop_();
  139. }




  140. /*******************************************************
  141. 功能:I2CStart
  142. 描述:开启SD2000的I2C总线
  143. 参数:无
  144. 返回:位变量I2CStart,1=I2C总线可用,0=I2C总线不可用
  145. ********************************************************/
  146. bit I2CStart(void)
  147. {
  148.         SDA=1;
  149.         SCL=1;
  150.         I2CWait();
  151.         if(!SDA)return false;//SDA线为低电平则总线忙,退出
  152.         SDA=0;
  153.         I2CWait();
  154.         while(SDA)return false;//SDA线为高电平则总线出错,退出
  155.         SCL=0;
  156.         I2CWait();
  157.         return true;
  158. }


  159. /*******************************************************
  160. 功能:I2CStop
  161. 描述:关闭SD2000的I2C总线
  162. 参数:无
  163. 返回:无
  164. ********************************************************/
  165. void I2CStop(void)
  166. {
  167.         SDA=0;
  168.         SCL=0;
  169.         I2CWait();
  170.         SCL=1;
  171.         I2CWait();
  172.         SDA=1;
  173. }


  174. /*******************************************************
  175. 功能:I2CSendAck
  176. 描述:发送 ACK
  177. 参数:无
  178. 返回:无
  179. ********************************************************/
  180. void I2CSendAck(void)
  181. {        
  182.         SDA=0;
  183.         SCL=0;
  184.         I2CWait();
  185.         SCL=1;
  186.         I2CWait();
  187.         SCL=0;
  188. }


  189. /*******************************************************
  190. 功能:I2CSendNoAck
  191. 描述:发送NO ACK
  192. 参数:无
  193. 返回:无
  194. ********************************************************/
  195. void I2CSendNoAck(void)
  196. {        
  197.         SDA=1;
  198.         SCL=0;
  199.         I2CWait();
  200.         SCL=1;
  201.         I2CWait();
  202.         SCL=0;
  203. }


  204. /*******************************************************
  205. 功能:I2CWaitAck
  206. 描述:读取ACK信号
  207. 参数:无
  208. 返回:位变量I2CWaitAck,返回为:1=有ACK,0=无ACK
  209. ********************************************************/
  210. bit I2CWaitAck(void)  
  211. {
  212.         unsigned char errtime=255;
  213.         SCL=0;
  214.         SDA=1;
  215.         I2CWait();
  216.         SCL=1;
  217.         I2CWait();
  218.         while(SDA)
  219.         {
  220.                 errtime--;
  221.                 if(!errtime)
  222.                 SCL=0;
  223.                 return false;
  224.         }
  225.         SCL=0;
  226.         return true;
  227. }


  228. /*******************************************************
  229. 功能:I2CSendByte
  230. 描述:向SD2000发送一个字节
  231. 参数:待发送字节demand,发送顺序指示order
  232.       order=1,从HI-->LO发送8bit数据
  233.       order=0,从LO-->HI发送8bit数据
  234. 返回:无
  235. ********************************************************/
  236. void I2CSendByte(unsigned char demand,bit order)
  237. {
  238.         unsigned char i=8;                       
  239.                                        
  240.         if(order)
  241.         {
  242.                 while(i--)
  243.                 {
  244.                         SCL=0;
  245.                         _nop_();
  246.                         SDA=(bit)(demand&0x80);
  247.                         demand<<=1;
  248.                         I2CWait();
  249.                         SCL=1;
  250.                         I2CWait();
  251.                 }
  252.                 SCL=0;
  253.         }
  254.      else
  255.         {
  256.                 while(i--)
  257.                  {
  258.                         SCL=0;
  259.                         _nop_();
  260.                         SDA=(bit)(demand&0x01);
  261.                         demand>>=1;
  262.                         I2CWait();
  263.                         SCL=1;
  264.                         I2CWait();
  265.                  }
  266.                  SCL=0;
  267.         }
  268. }


  269. /*******************************************************
  270. 功能:I2CReceiveByte
  271. 描述:从SD2000读入一字节
  272. 参数:无
  273. 返回:读取的字节I2CReceiveByte
  274. ********************************************************/
  275. unsigned char I2CReceiveByte(void)
  276. {
  277.         unsigned char i=8;
  278.         unsigned char ddata=0;
  279.         SDA=1;
  280.         while(i--)
  281.         {
  282.                 ddata>>=1;          //数据从低位开始读取
  283.                 SCL=0;
  284.                 I2CWait();
  285.                 SCL=1;
  286.                 I2CWait();           //从低位开始 ddata|=SDA;ddata>>=1
  287.    if(SDA)
  288.                 {
  289.                         ddata|=0x80;
  290.                 }
  291.         }
  292.    SCL=0;
  293.         return ddata;
  294. }
  295. /*******************************************************
  296. 功能:读键值
  297. 描述:
  298. 参数:
  299. 返回:键值
  300. ********************************************************/
  301. ///*
  302. unsigned char AipReadKey()
  303. {
  304.         unsigned char key;
  305.   AiP650_Set(0x4f,0x00);
  306.         if(I2CWaitAck())
  307.   {I2CStart();
  308.         key=I2CReceiveByte();
  309.                
  310.   I2CStop();}
  311. return key;}//*/


  312. /*******************************************************
  313. 功能:发送地址,数据, 数码管显示
  314. 描述:
  315. 参数:
  316. 返回:
  317. ********************************************************/
  318. void AiP650_Set(unsigned char add,unsigned char dat) //数码管显示
  319. {
  320.         //写显存必须从高地址开始写
  321.         I2CStart();
  322.         I2CSendByte(add,1); //第一个显存地址
  323.         I2CSendAck();
  324.         I2CSendByte(dat,1);
  325.         I2CSendAck();
  326.         I2CStop();
  327. }




  328. /*******************************************************
  329. 功能:驱动数码管显示数字
  330. 描述:显示数字
  331. 参数:
  332. 返回:
  333. ********************************************************/
  334. void AiP650_DisPlay(unsigned char Dig_Bit,unsigned char Display_num)                //显示一位数字
  335. {
  336.         AiP650_Set(Dig_Bit_Code[Dig_Bit-1],Display_Code[Display_num]);
  337. }


  338. /*******************************************************
  339. 功能:清屏
  340. 描述:
  341. 参数:
  342. 返回:
  343. ********************************************************/


  344. void AiP650_CLR()                                                                   //清屏
  345. {
  346.         unsigned char i;
  347.         for(i=0;i<4;i++)
  348.         {
  349.                 AiP650_Set(Dig_Bit_Code[i],0x00);                [/i][i]
  350.         }
  351. }
  352. /*******************************************************
  353. 功能:设置显示亮度
  354. 描述:
  355. 参数:
  356. 返回:
  357. ********************************************************/
  358. void Light_Level_Set(unsigned char level)
  359. {AiP650_Set(0x48,Light_Level_Code[level-1]);}
  360. /*******************************************************
  361. 功能:Delay
  362. 描述:延时子程序
  363. 参数:延时长度nn
  364. 返回:无
  365. ********************************************************/
  366. /*void Delay(unsigned int nn)
  367. {
  368.    while(nn--);
  369.    }
  370. */
  371. //
  372. /*****************11us延时函数*************************/
  373. //
  374. void delay(uint t)
  375. {
  376.   for (;t>0;t--);
  377. }
  378. //


  379. //
  380. /****************DS18B20复位函数************************/
  381. void ow_reset(void)
  382. {
  383. char presence=1;
  384. while(presence)
  385. {
  386.   while(presence)
  387.    {
  388.     DQ=1;_nop_();_nop_();//从高拉倒低
  389. DQ=0;                                       
  390. delay(50);           //550 us
  391. DQ=1;                                       
  392. delay(6);            //66 us
  393. presence=DQ;         //presence=0 复位成功,继续下一步
  394.    }
  395.    delay(45);            //延时500 us
  396.    presence=~DQ;         
  397. }
  398. DQ=1;                   //拉高电平
  399. }
  400. //
  401. //
  402. /****************DS18B20写命令函数************************/
  403. //向1-WIRE 总线上写1个字节
  404. void write_byte(uchar val)
  405. {
  406.   uchar i;
  407.   for(i=8;i>0;i--)
  408.   {
  409.    DQ=1;_nop_();_nop_();                  //从高拉倒低
  410.    DQ=0;_nop_();_nop_();_nop_();_nop_();  //5 us
  411.    DQ=val&0x01;                           //最低位移出
  412.    delay(6);                              //66 us
  413.    val=val/2;                             //右移1位
  414.    }
  415.    DQ=1;
  416.    delay(1);
  417. }
  418. //
  419. /****************DS18B20读1字节函数************************/
  420. //从总线上取1个字节
  421. uchar read_byte(void)
  422. {
  423. uchar i;
  424. uchar value=0;
  425. for(i=8;i>0;i--)
  426. {
  427.   DQ=1;_nop_();_nop_();
  428.   value>>=1;
  429.   DQ=0;_nop_();_nop_();_nop_();_nop_();         //4 us
  430.   DQ=1;_nop_();_nop_();_nop_();_nop_();         //4 us
  431.   if(DQ)value|=0x80;
  432.   delay(6);                                     //66 us
  433. }
  434. DQ=1;
  435. return(value);
  436. }
  437. //
  438. /****************读出温度函数************************/
  439. //
  440. read_temp()
  441. {
  442.   ow_reset();                  //总线复位
  443.   delay(200);
  444.   write_byte(0xcc);            //发命令
  445.   write_byte(0x44);            //发转换命令
  446.   ow_reset();
  447.   delay(1);
  448.   write_byte(0xcc);            //发命令
  449.   write_byte(0xbe);
  450.   temp_data[0]=read_byte();    //读温度值的第字节
  451.   temp_data[1]=read_byte();    //读温度值的高字节
  452.   temp=temp_data[1];
  453.   temp<<=8;                                               
  454.   temp=temp|temp_data[0];      // 两字节合成一个整型变量。
  455.   return temp;                 //返回温度值
  456. }
  457. //
  458. /****************温度数据处理函数************************/


  459. //二进制高字节的低半字节和低字节的高半字节组成一字节,这个
  460. //字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩
  461. //下的低字节的低半字节转化成十进制后,就是温度值的小数部分


  462. /********************************************************/
  463. void work_temp(uint tem)
  464. {
  465. uchar n=0;
  466. if(tem>6348)                        // 温度值正负判断
  467.      {tem=65536-tem;n=1;}            // 负温度求补码,标志位置1
  468.       display[4]=tem&0x0f;           // 取小数部分的值
  469.   display[0]=ditab[display[4]];  // 存入小数部分显示值
  470.       display[4]=tem>>4;             // 取中间八位,即整数部分的值
  471.   display[3]=display[4]/100;     // 取百位数据暂存
  472.   display[1]=display[4]%100;     // 取后两位数据暂存
  473.   display[2]=display[1]/10;      // 取十位数据暂存
  474.   display[1]=display[1]%10;  
  475. /******************符号位显示判断**************************/
  476.   if(!display[3])
  477.   {
  478.     display[3]=0x0a;           //最高位为0时不显示
  479.     if(!display[2])
  480. {
  481.    display[2]=0x0a;        //次高位为0时不显示
  482. }
  483.   }
  484.   if(n){display[3]=0x0b;}      //负温度时最高位显示"-"
  485. }
  486. //
  487. //
  488. /*************************************************************
  489. 显示温度
  490. 功能:温度数值处理,发送650显示


  491. ***********************************************************/
  492. void xiashiwendu(uint tem1)
  493. {
  494.    work_temp(tem1);
  495.                 AiP650_CLR();
  496.                         Light_Level_Set(4);
  497.                 AiP650_DisPlay(2,10);//显示小数点
  498.                 AiP650_DisPlay(3,display[2]);//百位
  499.                 AiP650_DisPlay(2,display[1]);//显示个位
  500.                 AiP650_DisPlay(1,display[0]);//小数






  501. }
  502. /******************显示键值*************************************
  503. 功能:将键值发送650显示




  504. ****************************************************************/
  505. void xianshijianzhi(uint key)
  506. {key=key&0x0a;
  507.         
  508.                   Light_Level_Set(4);
  509.          
  510.          AiP650_DisPlay(2,key);
  511. }
复制代码
回复

使用道具 举报

ID:123289 发表于 2022-11-3 09:15 | 显示全部楼层
1、先编个【按键】程序,识别到XX键被按下了。
2、再编个【响应】程序,即按键后,你想干的活。
3、列个EXCEL表,列出XX键、或组合键分别要干的活。
4、运行【按键】程序,识别按键,再分别调用列表中的【响应】。
回复

使用道具 举报

ID:680729 发表于 2022-11-3 11:16 | 显示全部楼层
有aip650按键程序的例子吗?
回复

使用道具 举报

ID:161164 发表于 2022-11-3 12:01 | 显示全部楼层
jzcjz 发表于 2022-11-3 11:16
有aip650按键程序的例子吗?

这样改看看
2022-11-03_120120.png


回复

使用道具 举报

ID:680729 发表于 2022-11-3 16:28 | 显示全部楼层
不是读按键,是按键响应的。它那个按键的码表好像不对啊。
回复

使用道具 举报

ID:883242 发表于 2022-11-3 19:18 | 显示全部楼层
按键和温度是完全不相关的两件事,不存在“aip650按键程序的例子”,楼主还是先静下心来,想想你需要你几个按键,每个按键是干什么用的。你的项目需要哪些功能,这些按键是否能够全部满足。
回复

使用道具 举报

ID:213173 发表于 2022-11-3 21:12 | 显示全部楼层
jzcjz 发表于 2022-11-3 16:28
不是读按键,是按键响应的。它那个按键的码表好像不对啊。

无标题.jpg
最多28个键
void key_service()
{

        num=AipReadKey();
        switch(num)
        {
                case 0x44: /*任务 1*/ break;
                case 0x4c: /*任务 2*/ break;
                case 0x54: /*任务 3*/ break;
                case 0x5c: /*任务 4*/ break;
                ......     /*任务 n*/ break;
                case 0x77: /*任务28*/ break;
        }

}
回复

使用道具 举报

ID:680729 发表于 2022-11-3 22:07 | 显示全部楼层
按键没反应,键值都试了一遍。
keyvalue=AipReadKey();
     switch(keyvalue)
                         {case 0x45:
                                 Light_Level_Set(4);
                                 AiP650_DisPlay(2,1);
                  break;
                                          case  0x55:
                                                 Light_Level_Set(4);
                                         AiP650_DisPlay(2,2);
                 break;
                                         case 0x5d:                           
                                                Light_Level_Set(4);
                                         AiP650_DisPlay(2,3);
                break;
                                          case 0x65:  
                                                Light_Level_Set(4);
                                         AiP650_DisPlay(2,4);
                  break;
                                          case 0x6d:
                                                 Light_Level_Set(4);
                                         AiP650_DisPlay(2,5);
                                         break;
                   case 0x75:
                 Light_Level_Set(4);
                         AiP650_DisPlay(2,6);
                                
                                                           
                         break;
                 
                       
                         
                         
                         ; }                         
                }
回复

使用道具 举报

ID:213173 发表于 2022-11-4 06:27 | 显示全部楼层
jzcjz 发表于 2022-11-3 22:07
按键没反应,键值都试了一遍。
keyvalue=AipReadKey();
     switch(keyvalue)

要按照厂家推荐的硬件电路,DIG端串接2K电阻,否则无法正常读取键值。你的数码管已经能正常显示数字,可以用来显示键值,以判断读键是否正确。TM1650分新旧版本,键码不同,AIP650是不是也有新旧版本不得而知。
回复

使用道具 举报

ID:220661 发表于 2022-11-4 07:43 | 显示全部楼层
另外,现在的51单片机速度有点快,IIC速度太快了扩展芯片跟不上。表现为显示正常按键读不到,别问我怎么知道的。
回复

使用道具 举报

ID:680729 发表于 2022-11-4 15:17 | 显示全部楼层
一时搞不定,试了好多方法,心累啊。水平有限,现丑现丑。
回复

使用道具 举报

ID:680729 发表于 2022-11-5 09:14 | 显示全部楼层
看了蕊片,是FDZY650,它与aip650不同?没有资料。引脚和aip650是一样的,就不知按键代码是不是一样。
回复

使用道具 举报

ID:680729 发表于 2022-11-5 20:56 | 显示全部楼层
uchar  Display_16code[16]={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf7,0xd7,0xbf,0xbe,0xf8,0x3f,0xfa,0xba};
/******************显示键值*************************************
功能:将键值发送650显示


****************************************************************/
void xianshijianzhi(uchar key1)
{uchar a,b;
         a=key1&0x0f;
    AiP650_CLR();   
                  Light_Level_Set(4);
         
         AiP650_DisPlay(2,Display_16code[a-1]);
        b=key1>>4;
         b=b&0x0f;
          
          Light_Level_Set(4);
         
         AiP650_DisPlay(1,Display_16code[b-1]);
         
}


键值显示22,按键无变化。不懂意思,难道读不出键值?
回复

使用道具 举报

ID:680729 发表于 2022-11-5 21:46 | 显示全部楼层
按键有反应了。显示值不太对。
uchar  Display_16code[16]={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf7,0xd7,0xbf,0xbe,0xf8,0x3f,0xfa,0xba};
//0,    1,   2 ,  3,  4,    5,   6,   7,   8,    9,  a,  b,c,d,e,f
/*******************************************************
功能:读键值
描述:
参数:
返回:键值
********************************************************/
///*
unsigned char AipReadKey()
{
        unsigned char key;
  //AiP650_Set(0x4f,0x00);

   I2CStart();       
   I2CSendByte(0x4f,1);
        // I2CWaitAck() ;
        //if(I2CWaitAck())
        //I2CSendByte(0x00,1);
        if(I2CWaitAck())
        {key=I2CReceiveByte();
                       
        I2CSendAck();
        //if(I2CWaitAck())       
  //{ I2CSendByte(0x00,1);
       
                                //}
        }
        I2CStop();
return key;}//*/
/******************显示键值*************************************
功能:将键值发送650显示


****************************************************************/
void xianshijianzhi(uchar key1)
{uchar a,b;
         a=key1&0x0f;
    AiP650_CLR();   
                  Light_Level_Set(4);
         
         AiP650_DisPlay(1,a);
        b=key1>>4;
         b=b&0x0f;
          
          Light_Level_Set(4);
         
         AiP650_DisPlay(2,b);
         
}
回复

使用道具 举报

ID:213173 发表于 2022-11-5 22:06 | 显示全部楼层
jzcjz 发表于 2022-11-5 21:46
按键有反应了。显示值不太对。
uchar  Display_16code[16]={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf ...

曾经使用TM1650,也不清楚是新旧版本,按键无反应。后用数码管显示键值观察,与手册不一致。但修改按键服务函数与之对应后按键功能正常。
回复

使用道具 举报

ID:680729 发表于 2022-11-5 23:49 | 显示全部楼层
键值摸清楚了,分别是a0,a4,ac,a8,b4,b8. 但是能显示,switch 和显示函数一块儿用就能扫到键,单独switch又不行了。可能真的是650跟不上单片机的速度。怎么解决呢?
回复

使用道具 举报

ID:213173 发表于 2022-11-6 10:28 | 显示全部楼层
jzcjz 发表于 2022-11-5 23:49
键值摸清楚了,分别是a0,a4,ac,a8,b4,b8. 但是能显示,switch 和显示函数一块儿用就能扫到键,单独switch又 ...

不存在650跟不上单片机的速度问题,这是用STC8G1K08驱动TM1650的单键控制时钟设置的局部代码:
  1. //==============TM1650驱动部分=====================
  2. //us延时函数
  3. void Delay_us(unsigned int i)//@12MHz
  4. {
  5.         while(--i)
  6.         {
  7.                 _nop_();
  8.                 _nop_();
  9.         }
  10. }
  11. //开始信号
  12. void Start1650(void)
  13. {
  14.         CLK = 1;
  15.         DIO = 1;
  16.         Delay_us(5);
  17.         DIO = 0;
  18. }
  19. //写一个字节 高位在前低位在后
  20. void WrByte1650(uchar oneByte)
  21. {
  22.         uchar i;
  23.         CLK = 0;
  24.         Delay_us(1);
  25.         for(i=0;i<8;i++)
  26.         {
  27.                 oneByte = oneByte<<1;
  28.                 DIO = CY;
  29.                 CLK = 0;
  30.                 Delay_us(5);
  31.                 CLK = 1;
  32.                 Delay_us(5);
  33.                 CLK = 0;
  34.         }
  35. }
  36. //应答ACK信号
  37. void Ask1650(void)
  38. {
  39.         uchar timeout = 1;
  40.         CLK = 1;
  41.         Delay_us(5);
  42.         CLK = 0;
  43.         while((DIO)&&(timeout<=100))
  44.         {
  45.                 timeout++;
  46.         }
  47.         Delay_us(5);
  48.         CLK = 0;
  49. }
  50. //停止信号
  51. void Stop1650(void)
  52. {
  53.         CLK = 1;
  54.         DIO = 0;
  55.         Delay_us(5);
  56.         DIO = 1;
  57. }
  58. //写显示地址和数据
  59. void Set1650(uchar add,uchar dat)
  60. {                                          
  61.         Start1650();     //开始
  62.         WrByte1650(add); //写地址
  63.         Ask1650();       //应答
  64.         WrByte1650(dat); //写数据
  65.         Ask1650();       //应答
  66.         Stop1650();      //停止
  67. }
  68. //显示命令格式:空位  亮度等级位   7/8段位  空位  开关位
  69. //显示命令格式: 0    1   1   1     1/0     0 0    1/0

  70. //初始化1650
  71. void Init1650()
  72. {
  73.         Set1650(0x48,0x31); //3级亮度 开显示
  74. }
  75. //扫描1650按键
  76. uchar Scan1650_Key()
  77. {  
  78.         uchar i;
  79.         uchar rekey;
  80.         Start1650();     //开始
  81.         WrByte1650(0x49);//读按键命令 0100 1111
  82.         Ask1650();                 //应答
  83.         for(i=0;i<8;i++)
  84.         {
  85.                 CLK = 1;
  86.                 rekey<<=1;
  87.                 if(DIO)rekey++;
  88.                 Delay_us(5);
  89.                 CLK = 0;
  90.         }
  91.         Ask1650();                  //应答
  92.         Stop1650();       //停止
  93.         return rekey;     //返回键值
  94. }
  95. //按键服务函数
  96. void key_service()
  97. {
  98.         static uint time=0;  //计数变量
  99.         temp=Scan1650_Key(); //读取键值
  100.         if(temp==0x4E)       //按键按下
  101.         {
  102.                 time++;
  103.                 if(time>=key_L)  //长按
  104.                 {
  105.                         switch(KeySec)
  106.                         {
  107.                                 case 1: TIME[2]++;if(TIME[2]>23)TIME[2]=0; break;
  108.                                 case 2: TIME[1]++;if(TIME[1]>59)TIME[1]=0; break;
  109.                         }
  110.                         time=key_I;  //连+间隔
  111.                         num=500;     //自复位变量赋值(5秒)
  112.                 }
  113.         }
  114.         else                                //松手
  115.         {
  116.                 if(time>key_S && time<key_I)//短按
  117.                 {
  118.                         num=500;    //自复位变量赋值(5秒)
  119.                         KeySec++;
  120.                         if(KeySec>3)
  121.                         {
  122. //                                KeySec=0;
  123.                                 num=1;
  124.                         }
  125.                 }
  126.                 time=0;
  127.         }
  128. }
复制代码
回复

使用道具 举报

ID:680729 发表于 2022-11-10 21:38 | 显示全部楼层
现在数码管干脆就不亮了,更换蕊片也不行,难道单片机坏了?换一片也不亮,搞什么鬼。跟我过不去啊。
回复

使用道具 举报

ID:680729 发表于 2022-11-11 22:05 | 显示全部楼层
换蕊片,换单片机,查软件,为什么本来是可以点亮的,为什么就不亮了。吐血啊。数码管也是好的。没思路了。嗨。
回复

使用道具 举报

ID:680729 发表于 2022-11-13 08:53 | 显示全部楼层
抓到鬼了。同样的代码,手工输入的运行正常,复制粘贴的,编译无错但刷进去不能运行。

#include <STC89C5xRC.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit   key=P1^3;


void Delay(uint x)
{uchar t;
        while(x--)
        {
        for(t=0;t<120;t++);}
}
/*void delay(uint t)
{
  for (;t>0;t--);
}*/
/*main()
{key=0;
while(1)
{Delay(150);
key=~key;}
}
*/

void main()
{   
                //P3=0xFF;
          key=0;
        while(1);
        {
                Delay(150);
                 
                key=~key;


                         
        };
               
         
   
         
   }
回复

使用道具 举报

ID:161164 发表于 2022-11-13 17:38 | 显示全部楼层
2022-11-13_173805.png
回复

使用道具 举报

ID:680729 发表于 2022-11-15 21:45 | 显示全部楼层
跟这烂芯片杠上了,重新把代码手工输了一遍。但还是不行。请各位高人指点迷津。
  1. /**********************************手工输入********
  2. 名称:aip650的驱动
  3. 时间:2022-11-13
  4. 版本:

  5. **************************************************/
  6. //头文件
  7. #include <STC89X52RC.H>
  8. #include <absacc.h>
  9. #include  <intrins.h>

  10. /*************************************************
  11.              常量、变量定义区


  12. ***************************************************/
  13. //常量定义
  14. #define true 1
  15. #define  false 0
  16. #define  uchar unsigned char
  17. #define  uint unsigned int

  18. //数组定义
  19. uchar Display_Code[13]={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf7,0xd7,0x08,0x02,0x00};
  20.          //共阴数码管段码 0,   1,  2,  3,  4 , 5,   6,  7,  8,  9,  .,   -,  不亮
  21. uchar  Display_16Code[16]={0xf5,0x05,0x73,0x57,0x87,0xd6,0xf6,0x45,0xf7,0xd7,0xe7,0xb6,0xf0,0x37,0xf2,0xe2};
  22. //16进 制段码(用于显示键值)0,   1,   2,  3,  4,  5,   6, 7,  8,   9,  a,   b,   c,   d,   e,   f
  23. uchar Dig_Bit_Code[4]={0x6a,0x6e,0x6c,0x68};//650位码
  24. uchar Light_Level_Code[8]={0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01};//亮度调节

  25. uchar keyvalue;
  26. uint wendu;//用于存储温度值

  27. uint h;//温度计算使用
  28. uint temp;//温度返回值
  29. /***************************温度小数部分用查表法*****************/
  30. uchar ditab[16]=
  31. {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
  32. uchar temp_data[2]={0x00,0x00};//读出温度暂存
  33. uchar display[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算暂用

  34. //定义IO口
  35. sbit   SDA=P3^7;
  36. sbit   SCL=P3^6;

  37. sbit    DQ=P1^0;      //ds18b20温度输入口
  38. sbit    DIN=P1^1;     //LED小数点控制

  39. /**********************************函数定义区************************************/
  40. //I2C相关
  41. /*******************************************************************************
  42. 功能:I2CWait
  43. 描述:I2C延时
  44. 参数:
  45. 返回:
  46. *******************************************************************************/
  47. void I2CWait(void)
  48. {_nop_();_nop_();_nop_();_nop_();
  49. }




  50. /*******************************************************************************
  51. 功能:I2CStart
  52. 描述:开启I2C总线
  53. 参数:
  54. 返回:位变量,1=I2C总线可用,0=不可用
  55. *******************************************************************************/
  56. bit I2CStart(void)
  57. {   
  58.         SDA=1;
  59.         SCL=1;
  60.         I2CWait();
  61. if(!SDA)
  62.         return false;//SDA线为低电平则总线忙,退出
  63.                 SDA=0;
  64.         I2CWait();
  65.         while(SDA)
  66.                 return false;//SDA线为高电平则总线出错,退出
  67.         SCL=0;
  68.         I2CWait();
  69.         return true;

  70. }

  71. /*******************************************************************************
  72. 功能:I2CStop(void)
  73. 描述:关闭I2C总线
  74. 参数:
  75. 返回:
  76. *******************************************************************************/
  77. void I2CStop(void)
  78. {
  79.   SDA=0;
  80.         SCL=0;
  81.         I2CWait();
  82.         SCL=1;
  83.         I2CWait();
  84.         SDA=1;

  85. }


  86. /*******************************************************************************
  87. 功能:I2CSendAck
  88. 描述:发送ACK信号
  89. 参数:
  90. 返回:
  91. *******************************************************************************/
  92. void I2CSendAck(void)
  93. {
  94.         SDA=0;
  95.         SCL=0;
  96.         I2CWait();
  97.         SCL=1;
  98.         I2CWait();
  99.         SCL=0;
  100. }


  101. /*******************************************************************************
  102. 功能:I2CSendNoAck
  103. 描述:发送  No Ack
  104. 参数:
  105. 返回:
  106. *******************************************************************************/
  107. void I2CSendNoAck(void)
  108. {   
  109.         SDA=1;
  110.         SCL=0;
  111.         I2CWait();
  112.         SCL=1;
  113.         I2CWait();
  114.         SCL=0;        
  115.         
  116. }

  117. /*******************************************************************************
  118. 功能:I2CWaitAck
  119. 描述:读取ACK信号
  120. 参数:
  121. 返回:位变量, 1=有ACK,0=无ACK
  122. *******************************************************************************/
  123. bit I2CWaitAck(void)
  124. {
  125.      uchar errtime=255;
  126.         SCL=0;
  127.         SDA=1;
  128.         I2CWait();
  129.         SCL=1;
  130.         I2CWait();
  131.         while(SDA)
  132.         {
  133.                 errtime--;
  134.                 if(!errtime)
  135.                         SCL=0;
  136.                 return false;
  137.         }
  138.         SCL=0;
  139.         return true;
  140.     }

  141. /*******************************************************************************
  142. 功能:I2CSendByte
  143. 描述:向总线发送一个字节
  144. 参数:待发送字节demand,发送顺序指示order
  145.                  order=1,从HI-->LO发送8bit数
  146.                  order=0,从LO-->HI发送8bit数
  147. 返回:
  148. *******************************************************************************/
  149. void I2CSendByte(uchar demand,bit order)
  150.                 {
  151.                         uchar i=8;
  152.                         if(order)
  153.                         {
  154.                                 while(i--)
  155.                                 {
  156.                                         SCL=0;
  157.                                         _nop_();
  158.                                         SDA=(bit)(demand&0x80);
  159.                                         demand<<=1;
  160.                                         I2CWait();
  161.                                         SCL=1;
  162.                                         I2CWait();
  163.                                 }
  164.                                 SCL=0;
  165.                         }
  166.                         else
  167.                         {
  168.                                 while(i--)
  169.                                 {
  170.                                         SCL=0;
  171.                                         _nop_();
  172.                                         SDA=(bit)(demand&0x01);
  173.                                         demand>>=1;
  174.                                         I2CWait();
  175.                                         SCL=1;
  176.                                         I2CWait();
  177.                                 }
  178.                                 SCL=0;
  179.                         }
  180.                 }

  181. /*******************************************************************************
  182. 功能:I2CReceiveByte
  183. 描述:从总线读一个字节
  184. 参数:
  185. 返回:
  186. *******************************************************************************/
  187. uchar I2CReceiveByte(void)
  188. {
  189.         uchar i=8;
  190.         uchar ddata=0;
  191.         SDA=1;
  192.         while(i--)
  193.         {
  194.                 ddata>>=1;//数据从低位开始读取
  195.                 SCL=0;
  196.                 I2CWait();
  197.                 SCL=1;
  198.                 I2CWait();//从低位开始 ddata|=SDA;ddata>>=1
  199.                 if(SDA)
  200.                 {
  201.                                    ddata|=0x80;
  202.                 }
  203.         }
  204.         SCL=0;
  205.              return ddata;
  206. }


  207. /*******************************************************************************
  208. 功能:从650读键值
  209. 描述:
  210. 参数:
  211. 返回:uchar键值
  212. *******************************************************************************/
  213. uchar AipReadKey()
  214. {
  215.                   uchar key;
  216.                      I2CStart();
  217.                      I2CSendByte(0x4f,1);
  218.                  if(I2CWaitAck())
  219.                                          {
  220.                                              key=I2CReceiveByte();
  221.                                                 
  222.                                            I2CSendAck();
  223.                                          }
  224.              I2CStop();
  225.                                          return key;
  226. }

  227. /*******************************************************************************
  228. 功能:向650发送地址,和数据
  229. 描述:
  230. 参数:
  231. 返回:
  232. *******************************************************************************/
  233. void Aip650_Set(uchar add,uchar dat)
  234. {
  235.   //写显存必须从高地址开始写
  236.         I2CStart();
  237.         I2CSendByte(add,1);
  238.         I2CSendAck();
  239.         I2CSendByte(dat,1);
  240.         I2CSendAck();
  241.         I2CStop();

  242. }


  243. /*******************************************************************************
  244. 功能:驱动数码管显示数字
  245. 描述:位码数组中选择对应的位地址,在段码数组中选择对应数字的段码发送给650
  246. 参数:
  247. 返回:
  248. *******************************************************************************/
  249. void Aip650_DisPlay(uchar Dig_Bit,uchar Display_num)
  250. {
  251.         Aip650_Set(Dig_Bit_Code[Dig_Bit-1],Display_Code[Display_num]);

  252.          }



  253. /*******************************************************************************
  254. 功能:驱动数码管显示16进制数的代码
  255. 描述:
  256. 参数:
  257. 返回:
  258. *******************************************************************************/
  259. void Aip650_DisPlay16(uchar Dig_Bit16,uchar Display_num16)
  260. {   
  261.      Aip650_Set(Dig_Bit_Code[Dig_Bit16-1],Display_16Code[Display_num16]);



  262.            }





  263. /*******************************************************************************
  264. 功能:650清屏
  265. 描述:
  266. 参数:
  267. 返回:
  268. *******************************************************************************/
  269. void Aip650_CLR()
  270. {
  271.     uchar i;
  272.         for(i=0;i<4;i++)
  273.         {
  274.         Aip650_Set(Dig_Bit_Code[i],0x00);
  275.         }

  276. }

  277. /*******************************************************************************
  278. 功能:设置显示亮度
  279. 描述:
  280. 参数:
  281. 返回:
  282. *******************************************************************************/
  283. void Light_Level_Set(uchar level)
  284. {
  285.         Aip650_Set(0x48,Light_Level_Code[level-1]);
  286. }


  287. /*******************************************************************************
  288. 功能:delay 延时程序 11us
  289. 描述:
  290. 参数:
  291. 返回:
  292. *******************************************************************************/
  293. void delay(uint t)
  294. {
  295. for(;t>0;t--);
  296. }

  297. /*******************************************************************************
  298. 功能:Ds18b20 复位函数
  299. 描述:
  300. 参数:
  301. 返回:
  302. *******************************************************************************/
  303. void ow_reset(void)
  304. {
  305. uchar presence=1;
  306.         while(presence)
  307.         {while(presence)
  308.                 {
  309.                         DQ=1;
  310.                         _nop_();_nop_();//从高拉到低
  311.                         DQ=0;
  312.                         delay(50);//550us
  313.                         DQ=1;
  314.                         delay(6);//66us
  315.                         presence=DQ;//presence=0复位成功,继续下一步
  316.                 }
  317.                 delay(45);//延时500us
  318.                 presence=~DQ;
  319.         }
  320.         DQ=1;  //拉高电平
  321. }


  322. /*******************************************************************************
  323. 功能:Ds18b20写命令函数
  324. 描述:向总线上写1个字节
  325. 参数:
  326. 返回:
  327. *******************************************************************************/
  328. void write_byte(uchar val)
  329. {
  330. uchar i;
  331.         for(i=8;i>0;i--)
  332.         {DQ=1;_nop_();_nop_();//从高拉低
  333.         DQ=0; _nop_();_nop_();_nop_();_nop_();//5us
  334.                 DQ=val&0x01;// 最低位移出
  335.         delay(6);//66us
  336.         val=val/2;//右移一位}
  337. }
  338. DQ=1;
  339. delay(1);
  340. }


  341. /*******************************************************************************
  342. 功能:从18b20总线上读1字节
  343. 描述:
  344. 参数:
  345. 返回:value
  346. *******************************************************************************/
  347. uchar read_byte(void)
  348. {
  349. uchar i;
  350.         uchar value=0;
  351.         for(i=8;i>0;i--)
  352.         {
  353.                 DQ=1;_nop_();_nop_();
  354.                 value>>=1;
  355.                 DQ=0;_nop_();_nop_();_nop_();_nop_();//4us
  356.                 DQ=1;_nop_();_nop_();_nop_();_nop_();//4us
  357.                 if(DQ)value|=0x80;
  358.                 delay(6);
  359.         }
  360.         
  361.         DQ=1;
  362.         return(value);
  363. }



  364. /*******************************************************************************
  365. 功能:读出温度
  366. 描述:
  367. 参数:
  368. 返回:
  369. *******************************************************************************/
  370. read_temp()
  371. {
  372. ow_reset();
  373.         delay(200);//总线复位
  374.         write_byte(0xcc);//发命令
  375.         write_byte(0x44);//发转换命令
  376.         ow_reset();
  377.         delay(1);
  378.         write_byte(0xcc);//发命令
  379.         write_byte(0xbe);
  380.         temp_data[0]=read_byte();//读温度的低字节
  381.         temp_data[1]=read_byte();//读温度的高字节
  382.         temp=temp_data[1];
  383.         temp<<=8;
  384.         temp=temp|temp_data[0];// 两字节合成一个整型变量
  385.         return temp;
  386. }





  387. /*******************************************************************************
  388. 功能:温度处理
  389. 描述:二进制数的高字节的低半字节和低字节的高半字节组成一个字,这个字节转换为十进制后,
  390. 就是温度的百、十、个位值,而剩下的低字节的低半字节转化成十进制后,就是温度值的小数部分。
  391. 参数:
  392. 返回:
  393. *******************************************************************************/
  394. void work_temp(uint tem)
  395. {
  396.         uchar n=0;
  397.         if(tem>6348)          //温度正负判断
  398.         {tem=65536-tem;n=1;}   //负温度求补码,标志位置1
  399.         display[4]=tem&0x0f;
  400.         display[0]=ditab[display[4]];//存入小数部分的显示值
  401.         display[4]=tem>>4;
  402.         display[3]=display[4]/100;//取百位数据暂存
  403.         display[1]=display[4]%100;//取后两位数据暂存
  404.         display[2]=display[1]/10;//取十位数据暂存
  405.         display[1]=display[1]%10;
  406.         /***********符号位显示判断*************************/
  407.         if(!display[3])
  408.         {
  409.         display[3]=0x0c;     //最高位为0时不显示
  410.           if(!display[2])
  411.         {
  412.         display[2]=0x0c;     //次高位为0时不显示
  413.         }
  414.         if(n)
  415.         {display[3]=0x0b;}    //负温度时最高位显示“-”
  416. }
  417. }

  418. /*******************************************************************************
  419. 功能:显示温度
  420. 描述:处理温度数值,发送650
  421. 参数:
  422. 返回:
  423. *******************************************************************************/
  424. void xianshiwendu(uint tem1)
  425. {
  426.          work_temp(tem1);
  427.           Aip650_CLR();
  428.          Light_Level_Set(4);
  429.          Aip650_DisPlay(2,10);//显示小数点
  430.          Aip650_DisPlay(3,display[2]);//十位
  431.    Aip650_DisPlay(2,display[1]);//个位
  432.    Aip650_DisPlay(1,display[0]);//小数
  433. }


  434. /*******************************************************************************
  435. 功能:显示键值
  436. 描述:将按键的16进制代码送显示
  437. 参数:
  438. 返回:
  439. *******************************************************************************/
  440. void xianshijianzhi(uchar key1)
  441. {uchar a,b;
  442.         a=key1&0x0f;
  443.         Aip650_ClR();
  444.         Light_Level_Set(4);
  445.         Aip650_DisPlay16(1,a);
  446.         b=key1>>4;
  447.         b=b&0x0f;
  448.         Aip650_DisPlay(2,b);
  449. }





  450. /******************************主函数*****************************************
  451. 功能:
  452. 描述:
  453. 参数:
  454. 返回:
  455. *******************************************************************************/
  456. void main()
  457. {
  458.     P3=0xff;
  459.          P1=0xff;
  460.          
  461.          
  462.           while(1)
  463.                 {Aip650_CLR();
  464.           Light_Level_Set(4);
  465.                         Aip650_DisPlay(1,8);
  466.                 Aip650_DisPlay(2,8);        
  467.                 Aip650_DisPlay(3,8);        
  468.                         //keyvalue=AipReadKey();
  469.                         P16=~P16;
  470.                         P17=~P17;
  471.                         delay(150);
  472.                                                 //wendu=read_temp();

  473.                         //xianshiwendu(wendu);
  474.                         //xianshijianzhi(keyvalue);        
  475.   //if(wendu>29)
  476.                 //P13=~P13;
  477.                         }

  478. }
复制代码
回复

使用道具 举报

ID:213173 发表于 2022-11-16 06:32 | 显示全部楼层
jzcjz 发表于 2022-11-15 21:45
跟这烂芯片杠上了,重新把代码手工输了一遍。但还是不行。请各位高人指点迷津。

这么多警告不解决,你还想正常运行?
无标题.jpg

回复

使用道具 举报

ID:680729 发表于 2022-11-16 07:17 | 显示全部楼层
不懂啊,跟棒锤差不了多少。
回复

使用道具 举报

ID:680729 发表于 2022-11-17 10:47 | 显示全部楼层
今天终于把数码管点亮了。真是历经千辛万苦,搞单片机真是折磨人呢。程序没什么大问题。问题应该出在焊接环节。焊直插蕊片用的自制焊台,虽然有接地,但仍然有静电?换两片都不行,难道毁了两个片子?后来干脆重新画图上贴片的用风枪。aip650这个片子,可能对静电很敏感,容易坏。 51hei图片_20221117103722.jpg 51hei图片_20221117103516.jpg
程序和原理图PCB文件:http://www.51hei.com/bbs/dpj-225200-1.html
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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