找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6535|回复: 3
收起左侧

为啥数码管0x14那一行显示代表0-9?

[复制链接]
ID:321008 发表于 2018-5-4 11:13 | 显示全部楼层 |阅读模式
数码管驱动电路.png

  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. #include <intrins.
  5. //数码管段选定义 0     1    2    3           4           5        6         7          8           9        
  6. uchar code smg_du[]={0x14,0x77,0x4c,0x45,0x27,0x85,0x84,0x57,0x04,0x05,A        B         C        

  7.   D           E   F        不显示
  8.                                             0x06,0xa4,0x9c,0x64,0x8c,0x8e,0xff};         //断码        
  9. //数码管位选定义
  10. sbit smg_we1 = P2^0;            //数码管位选定义
  11. sbit smg_we2 = P2^2;
  12. sbit smg_we3 = P2^4;
  13. sbit smg_we4 = P2^6;
  14. uchar dis_smg[8] = {0x14,0x77,0x4c,0x45,0x27,0x85,0x84};

  15. sbit SCL=P1^2;                //SCL定义为P1口的第3位脚,连接ADC0832SCL脚
  16. sbit DO=P1^3;                //DO定义为P1口的第4位脚,连接ADC0832DO脚
  17. sbit CS=P1^0;                //CS定义为P1口的第4位脚,连接ADC0832CS脚

  18. uchar shidu;     //湿度等级
  19. uchar s_high = 70,s_low = 25;        //湿度报警参数

  20. sbit dianji = P3^5;     //电机IO定义

  21. /***********************1ms延时函数*****************************/
  22. void delay_1ms(uint q)
  23. {
  24.         uint i,j;
  25.         for(i=0;i<q;i++)
  26.                 for(j=0;j<120;j++);
  27. }


  28. /***********************数码位选函数*****************************/
  29. void smg_we_switch(uchar i)
  30. {
  31.         switch(i)
  32.         {
  33.                 case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  34.                 case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  35.                 case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  36.                 case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  37.         }        
  38. }

  39. uchar flag_200ms ;
  40. uchar key_can;                 //按键值的变量
  41. uchar menu_1;        //菜单设计的变量

  42. /***********************数码显示函数*****************************/
  43. void display()
  44. {
  45.         static uchar i;   
  46.         i++;
  47.         if(i >= 4)
  48.                 i = 0;        
  49.         P0 = 0xff;                         //消隐
  50.         smg_we_switch(i);                 //位选
  51.         P0 = dis_smg[i];                 //段选               
  52. //        delay_1ms(1);
  53. }

  54. /***********读数模转换数据********************************************************/        
  55. //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832

  56. 的串行协议进行的
  57.                                                 //  1  1  0 通道
  58.                                                 //  1  1  1 通道
  59. unsigned char ad0832read(bit SGL,bit ODD)
  60. {
  61.         unsigned char i=0,value=0,value1=0;               
  62.                 SCL=0;
  63.                 DO=1;
  64.                 CS=0;                //开始
  65.                 SCL=1;                //第一个上升沿        
  66.                 SCL=0;
  67.                 DO=SGL;
  68.                 SCL=1;          //第二个上升沿
  69.                 SCL=0;
  70.                 DO=ODD;
  71.                 SCL=1;           //第三个上升沿
  72.                 SCL=0;           //第三个下降沿
  73.                 DO=1;
  74.                 for(i=0;i<8;i++)
  75.                 {
  76.                         SCL=1;
  77.                         SCL=0; //开始从第四个下降沿接收数据
  78.                         value=value<<1;
  79.                         if(DO)
  80.                                 value++;                                                
  81.                 }
  82.                 for(i=0;i<8;i++)
  83.                 {                        //接收校验数据
  84.                         value1>>=1;
  85.                         if(DO)
  86.                                 value1+=0x80;
  87.                         SCL=1;
  88.                         SCL=0;
  89.                 }
  90.                 SCL=1;
  91.                 DO=1;
  92.                 CS=1;        
  93.                 if(value==value1)                                //与校验数据比较,正确就返

  94. 回数据,否则返回0        
  95.                         return value;
  96.         return 0;
  97. }



  98. /********************独立按键程序*****************/
  99. uchar key_can;         //按键值

  100. void key()         //独立按键程序
  101. {
  102.         static uchar key_new;
  103.         key_can = 20;                   //按键值还原
  104.         P1 |= 0xf0;
  105.         if((P1 & 0xf0) != 0xf0)                //按键按下
  106.         {
  107.                 delay_1ms(1);                     //按键消抖动
  108.                 if(((P1 & 0xf0) != 0xf0) && (key_new == 1))
  109.                 {                                                //确认是按键按下
  110.                         key_new = 0;
  111.                         switch(P1 & 0xf0)
  112.                         {
  113.                                 case 0x70: key_can = 1; break;           //得到k2键值
  114.                                 case 0xb0: key_can = 2; break;           //得到k3键值
  115.                                 case 0xd0: key_can = 3; break;           //得到k4键值
  116.                         }                                
  117.                 }                        
  118.         }
  119.         else
  120.                 key_new = 1;        
  121. }

  122. /****************按键处理显示函数***************/
  123. void key_with()
  124. {
  125.         if(menu_1 == 0)
  126.         {
  127.                 if(key_can == 3)   //手动打开电机
  128.                         dianji = 0;     //打开电机
  129.                 if(key_can == 2)
  130.                         dianji = 1;     //关闭电机
  131.                 }

  132.         if(key_can == 1)         //设置键
  133.         {
  134.                 menu_1 ++;
  135.                 if(menu_1 >= 3)
  136.                 {
  137.                         menu_1 = 0;

  138.                 }
  139.         }
  140.         if(menu_1 == 1)                        //设置湿度上限
  141.         {
  142.                 if(key_can == 2)
  143.                 {
  144.                         s_high ++ ;                //湿度上限值加1
  145.                         if(s_high > 99)
  146.                                 s_high = 99;
  147.                 }
  148.                 if(key_can == 3)
  149.                 {
  150.                         s_high -- ;                //湿度上限值减1
  151.                         if(s_high <= s_low)
  152.                                 s_high = s_low + 1 ;
  153.                 }
  154.                 dis_smg[0] = smg_du[s_high % 10];                   //取个位显示
  155.                 dis_smg[1] = smg_du[s_high / 10 % 10];  //取十位显示
  156.                 dis_smg[2] = 0xef;         
  157.                 dis_smg[3] = 0x26;         //H  0010 0110

  158.         }        
  159.         if(menu_1 == 2)                        //设置湿度下限
  160.         {
  161.                 if(key_can == 2)
  162.                 {
  163.                         s_low ++ ;          //湿度下限值加1
  164.                         if(s_low >= s_high)
  165.                                 s_low = s_high - 1;
  166.                 }
  167.                 if(key_can == 3)
  168.                 {
  169.                         s_low --;          //湿度下限值减1
  170.                         if(s_low <= 1)
  171.                                 s_low = 1;
  172.                 }
  173.                 dis_smg[0] = smg_du[s_low % 10];                   //取个位显示
  174.                 dis_smg[1] = smg_du[s_low / 10 % 10];  //取十位显示
  175.                 dis_smg[2] = 0xef;         
  176.                 dis_smg[3] = 0xBC;         //L
  177.         }        
  178. }  

  179. /****************电机控制函数***************/
  180. void dianji_kongzi()
  181. {
  182.         static uchar value,value1;
  183.         if(shidu <= s_low)
  184.         {
  185.                 value ++;
  186.                 if(value >= 2)
  187.                 {
  188.                         value = 10;
  189.                         dianji = 0;       //关机电机
  190.                 }
  191.         }
  192.         else
  193.           value = 0;
  194.         if(shidu >= s_high)
  195.         {
  196.                 value1 ++;
  197.                 if(value1 >= 2)
  198.                 {
  199.                         value1 = 10;
  200.                         dianji = 1;       //打开电机
  201.                 }
  202.         }else
  203.                 value1 = 0;
  204. }

  205. /***************主函数*****************/
  206. void main()
  207. {
  208.         delay_1ms(100);
  209.         P0 = P1 = P2 = P3 = 0xff;   //初始化IO口
  210.         while(1)
  211.         {
  212.                 key();                                        //独立按键程序
  213.                 if(key_can < 10)
  214.                 {
  215.                         key_with();                        //按键按下要执行的程序
  216.                 }
  217.                 flag_200ms ++;
  218.                 if(flag_200ms >= 200)
  219.                 {               
  220.                         flag_200ms = 0;         
  221.                         P0 = 0xff;                         //消隐
  222.                         if(menu_1 == 0)
  223.                         {                                          
  224.                                 shidu = ad0832read(1,0);        //读出湿度
  225.                                 shidu =100-shidu * 99 / 255;
  226.                                 dis_smg[0] = 0xff;         //
  227.                                 dis_smg[1] = smg_du[shidu % 10]; //取湿度的个位显示
  228.                                 dis_smg[2] = smg_du[shidu / 10 % 10] ;//取湿度的十位显示
  229.                                 dis_smg[3] = 0XFF;        //
  230.                                 dianji_kongzi();  //电机控制函数
  231.                         }
  232.                         
  233.                 }
  234.                 display();          //数码管显示函数
  235.                 delay_1ms(1);
  236.         }
  237. }
复制代码
回复

使用道具 举报

ID:318768 发表于 2018-5-4 21:18 | 显示全部楼层
你可以把8段数码管想象成8个小灯,显示0要外圈6个灯亮,P0口要输出00010100,转换成16进制就是0X14.
回复

使用道具 举报

ID:319344 发表于 2018-5-4 21:36 | 显示全部楼层
运行了吗?我觉得这是有错误的,0x14只是表示两个段会亮,不可能显示0,共阳极显示0是0xc0(引脚与IO口相对应的情况下),可以找共阳极数码管笔形码表对应一下
回复

使用道具 举报

ID:213173 发表于 2018-5-5 06:44 | 显示全部楼层
通常数码管的管脚 A~dp按顺序对应接单片机P00~07,这就是常用的共阴极段码0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f或共阳极段码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90。
从你的接线图看不是常见接法,所以使用的段码也不同。要显示0必须使G和dp笔段高电平,其他笔段低电平。对应段码是0x14,二进制码0001 0100。其他数字段码与其同理。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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