久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2165|回復: 8
打印 上一主題 下一主題
收起左側

求大神幫忙看看51單片機數碼管顯示溫度出現殘影閃爍的問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:1045483 發表于 2022-9-21 23:47 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
在時鐘顯示狀態下沒有什么問題,按k4按鍵會進入溫度顯示狀態,松開則取消。但是顯示溫度時數碼管會一直出現閃爍的殘影,就是正常的溫度夾雜閃爍的殘影,好像在不停掃描一樣,有沒有大佬幫忙看看哪里有問題?時鐘顯示正常,不會有閃爍的殘影。代碼放下面了。


單片機源程序如下:
  1. #include <REGX52.H>
  2. unsigned char KeyNum,MODE1=-1,MODE2=-1,TimeSetSelect=-1,TimeSetFlashFlag,alarmSetSelect=-1,alarmSetSelectflash,Clocklock=0,alarmlock=0,Tlock=0;
  3. char Hour=12,Min=00,Sec=02;
  4. int T;

  5. void Nixie(unsigned char Location,Number);
  6. void TimeShow(void)//時間顯示功能
  7. {if(Clocklock==1){
  8.                 DS1302_ReadTime();//讀取時間
  9.                 Nixie(1,DS1302_Time[0]/10);
  10.                 Nixie(2,DS1302_Time[0]%10);
  11.                 Nixie(4,DS1302_Time[1]/10);
  12.                 Nixie(5,DS1302_Time[1]%10);
  13.                 Nixie(7,DS1302_Time[2]/10);
  14.                 Nixie(8,DS1302_Time[2]%10);
  15.                 Nixie(3,17);
  16.                 Nixie(6,17);
  17. }
  18. }
  19.                

  20. void TimeSet(void)//時間設置功能
  21. {if(Clocklock==1){
  22.         if(KeyNum==1)//按鍵2按下
  23.         {
  24.                 TimeSetSelect++;//設置選擇位加1
  25.                 TimeSetSelect%=3;//越界清零
  26.         }
  27.         if(KeyNum==3)//按鍵3按下
  28.         {
  29.                 DS1302_Time[TimeSetSelect]++;//時間設置位數值加1
  30.                 if(DS1302_Time[0]>23){DS1302_Time[0]=0;}//時越界判斷
  31.                 if(DS1302_Time[1]>59){DS1302_Time[1]=0;}//分越界判斷
  32.                 if(DS1302_Time[2]>59){DS1302_Time[2]=0;}//秒越界判斷
  33.         }
  34.         if(KeyNum==4)//按鍵4按下
  35.         {
  36.                 DS1302_Time[TimeSetSelect]--;//時間設置位數值減1
  37.                 if(DS1302_Time[0]<0){DS1302_Time[0]=23;}//時越界判斷
  38.                 if(DS1302_Time[1]<0){DS1302_Time[1]=59;}//分越界判斷
  39.                 if(DS1302_Time[2]<0){DS1302_Time[2]=59;}//秒越界判斷
  40.         }
  41.         //更新顯示,根據TimeSetSelect和TimeSetFlashFlag判斷可完成閃爍功能
  42.         if(TimeSetSelect==0 && TimeSetFlashFlag==1){Nixie(1,16);Nixie(2,16);Nixie(3,17);Nixie(6,17);}
  43.         else {Nixie(1,DS1302_Time[0]/10);Nixie(2,DS1302_Time[0]%10);Nixie(3,17);Nixie(6,17);}
  44.         if(TimeSetSelect==1 && TimeSetFlashFlag==1){Nixie(4,16);Nixie(5,16);Nixie(3,17);Nixie(6,17);}
  45.         else {Nixie(4,DS1302_Time[1]/10);Nixie(5,DS1302_Time[1]%10);Nixie(3,17);Nixie(6,17);}
  46.         if(TimeSetSelect==2 && TimeSetFlashFlag==1){Nixie(7,16);Nixie(8,16);Nixie(3,17);Nixie(6,17);}
  47.         else {Nixie(7,DS1302_Time[2]/10);Nixie(8,DS1302_Time[2]%10);Nixie(3,17);Nixie(6,17);}
  48. }
  49. }


  50. void alarmshow(void){//時間顯示功能
  51. if(alarmlock==1){
  52.                 Nixie(1,Hour/10);
  53.                 Nixie(2,Hour%10);
  54.                 Nixie(4,Min/10);
  55.                 Nixie(5,Min%10);
  56.                 Nixie(7,Sec/10);
  57.                 Nixie(8,Sec%10);
  58.                 Nixie(3,17);
  59.                 Nixie(6,17);
  60. }
  61. }
  62. void alarmset(){
  63.         if(alarmlock==1){
  64.                 if(KeyNum==2)//按鍵2按下
  65.                 {
  66.                         alarmSetSelect++;//設置選擇位加1
  67.                         alarmSetSelect%=3;//越界清零
  68.                 }
  69.                 if(KeyNum==3)//按鍵3按下
  70.                 {
  71.                                 if(alarmSetSelect==0){
  72.                                         Hour++;
  73.                                         if(Hour>23){Hour=0;};
  74.                         }else if(alarmSetSelect==1){
  75.                                                         Min++;
  76.                                        if(Min>23){Min=0;};
  77.                         }else{
  78.                                                 Sec++;
  79.                                                 if(Sec>23){Sec=0;};
  80.                         }
  81.                 }
  82.                 if(KeyNum==4)//按鍵4按下
  83.                 {
  84.                         switch(alarmSetSelect){
  85.                                 case 0:Hour--;
  86.                                        if(Hour<0){Hour=23;}
  87.                                                          break;
  88.                                 case 1:Min--;
  89.                                        if(Min<0){Min=59;}
  90.                                                          break;        
  91.                                 case 2:Sec--;
  92.                                        if(Sec<0){Sec=59;}
  93.                                                          break;                                                         
  94.                         }
  95.                 }
  96.                 if(alarmSetSelect==0 && alarmSetSelectflash==1){Nixie(1,16);Nixie(2,16);Nixie(3,17);Nixie(6,17);}
  97.                 else {Nixie(1,Hour/10);Nixie(2,Hour%10);Nixie(3,17);Nixie(6,17);}
  98.                 if(alarmSetSelect==1 && alarmSetSelectflash==1){Nixie(4,16);Nixie(5,16);Nixie(3,17);Nixie(6,17);}
  99.                 else {Nixie(4,Min/10);Nixie(5,Min%10);Nixie(3,17);Nixie(6,17);}
  100.                 if(alarmSetSelect==2 && alarmSetSelectflash==1){Nixie(7,16);Nixie(8,16);Nixie(3,17);Nixie(6,17);}
  101.                 else {Nixie(7,Sec/10);Nixie(8,Sec%10);Nixie(3,17);Nixie(6,17);}
  102. }
  103. }

  104. void TShow(){                                                
  105.                 if(Tlock==1){
  106.                                 DS18B20_ConvertT();        //轉換溫度
  107.                                 T=DS18B20_ReadT();        //讀取溫度
  108.                                 Nixie(6,T/10);
  109.                                 Nixie(7,T%10);
  110.                                 Nixie(8,12);
  111.                 }
  112.                                                                

  113. }



  114. void main()
  115. {
  116.         DS1302_Init();
  117.         Timer0Init();
  118.         DS1302_SetTime();//設置時間

  119.         
  120.         while(1)
  121.         {
  122.                 KeyNum=Key();//讀取鍵碼
  123.                 if(KeyNum==1)//按鍵1按下
  124.                 {
  125.                         MODE1++;
  126.                         Clocklock=1;
  127.                         alarmlock=0;
  128.                         Tlock=0;
  129.                 }
  130.                 switch(MODE1)//根據不同的功能執行不同的函數
  131.                 {
  132.                         case 0:TimeShow();
  133.                                                  if(P3_3==0){
  134.                                                          while(P3_3==0){
  135.                                                                                 Clocklock=0;
  136.                                                                           Tlock=1;
  137.                                                                           TShow();
  138.                                                          }
  139.                                                          Tlock=0;
  140.                                                 Clocklock=1;
  141.                                                 TimeShow();
  142.                         }
  143.                                                 break;
  144.                         case 1:TimeSet();DS1302_SetTime();break;
  145.                         case 2:TimeSet();DS1302_SetTime();break;
  146.                         case 3:TimeSet();DS1302_SetTime();break;
  147.                         case 4:MODE1=0;break;
  148.                 }
  149.                 if(KeyNum==2)//按鍵2按下
  150.                 {
  151.                         MODE2++;
  152.                         Clocklock=0;
  153.                         Tlock=0;
  154.                         TimeShow();
  155.                         alarmlock=1;
  156.                 }
  157.                 switch(MODE2)//根據不同的功能執行不同的函數
  158.                 {
  159.                         case 0:alarmshow();break;
  160.                         case 1:alarmset();break;
  161.                         case 2:alarmset();break;
  162.                         case 3:alarmset();break;
  163.                         case 4:MODE2=0;break;
  164.                 }
  165.                 if(DS1302_Time[0]==Hour&&DS1302_Time[1]==Min&&DS1302_Time[2]==Sec){
  166.                         int x;
  167.                         for(x=0,P2=0x01;x<25;x++){
  168.                                         P2=!P2;        //1111 1110
  169.                                         Delay(200);
  170.                         }
  171.                
  172.                 }
  173.         }
  174. }



  175. void Timer0_Routine() interrupt 1
  176. {
  177.         static unsigned int T0Count;
  178.         TL0 = 0x18;                //設置定時初值
  179.         TH0 = 0xFC;                //設置定時初值
  180.         T0Count++;
  181.         if(T0Count>=500)//每500ms進入一次
  182.         {
  183.                 T0Count=0;
  184.                 TimeSetFlashFlag=!TimeSetFlashFlag;//閃爍標志位取反
  185.           alarmSetSelectflash=!alarmSetSelectflash;//閃爍標志位取反
  186.         }
  187. }


  188. unsigned char Key()
  189. {
  190.         unsigned char KeyNumber=0;
  191.         
  192.         if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
  193.         if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
  194.         if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
  195.         if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
  196.         
  197.         return KeyNumber;
  198. }


  199. void Timer0Init(void)
  200. {
  201.         TMOD &= 0xF0;                //設置定時器模式
  202.         TMOD |= 0x01;                //設置定時器模式
  203.         TL0 = 0x18;                //設置定時初值
  204.         TH0 = 0xFC;                //設置定時初值
  205.         TF0 = 0;                //清除TF0標志
  206.         TR0 = 1;                //定時器0開始計時
  207.         ET0=1;
  208.         EA=1;
  209.         PT0=0;
  210. }


  211. void Delay(unsigned int xms)
  212. {
  213.         unsigned char i, j;
  214.         while(xms--)
  215.         {
  216.                 i = 2;
  217.                 j = 199;
  218.                 do
  219.                 {
  220.                         while (--j);
  221.                 } while (--i);
  222.         }
  223. }


  224. //引腳定義
  225. sbit DS1302_SCLK=P3^6;
  226. sbit DS1302_IO=P3^4;
  227. sbit DS1302_CE=P3^5;

  228. //寄存器寫入地址/指令定義
  229. #define DS1302_SECOND                0x80
  230. #define DS1302_MINUTE                0x82
  231. #define DS1302_HOUR                        0x84
  232. #define DS1302_WP                        0x8E

  233. //時間數組,索引0~6分別為年、月、日、時、分、秒、星期,設置為有符號的便于<0的判斷
  234. char DS1302_Time[]={12,59,25};

  235. /**
  236.   * @brief  DS1302初始化
  237.   * @param  無
  238.   * @retval 無
  239.   */
  240. void DS1302_Init(void)
  241. {
  242.         DS1302_CE=0;
  243.         DS1302_SCLK=0;
  244. }

  245. /**
  246.   * @brief  DS1302寫一個字節
  247.   * @param  Command 命令字/地址
  248.   * @param  Data 要寫入的數據
  249.   * @retval 無
  250.   */
  251. void DS1302_WriteByte(unsigned char Command,Data)
  252. {
  253.         unsigned char i;
  254.         DS1302_CE=0;
  255.         DS1302_SCLK=0;
  256.                 DS1302_CE=1;
  257.         for(i=0;i<8;i++)
  258.         {
  259.                 DS1302_IO=Command&(0x01<<i);
  260.                 DS1302_SCLK=1;
  261.                 DS1302_SCLK=0;
  262.         }
  263.         for(i=0;i<8;i++)
  264.         {
  265.                 DS1302_IO=Data&(0x01<<i);
  266.                 DS1302_SCLK=1;
  267.                 DS1302_SCLK=0;
  268.         }
  269. //        DS1302_CE=0;
  270. }

  271. /**
  272.   * @brief  DS1302讀一個字節
  273.   * @param  Command 命令字/地址
  274.   * @retval 讀出的數據
  275.   */
  276. unsigned char DS1302_ReadByte(unsigned char Command)
  277. {
  278.         unsigned char i,Data=0x00;
  279.         Command|=0x01;        //將指令轉換為讀指令
  280.         DS1302_CE=0;
  281.         DS1302_SCLK=0;
  282.         DS1302_CE=1;
  283.         for(i=0;i<8;i++)
  284.         {
  285.                 DS1302_IO=Command&(0x01<<i);
  286.                 DS1302_SCLK=0;
  287.                 DS1302_SCLK=1;
  288.         }
  289.         for(i=0;i<8;i++)
  290.         {
  291.                 DS1302_SCLK=1;
  292.                 DS1302_SCLK=0;
  293.                 if(DS1302_IO){Data|=(0x01<<i);}
  294.         }
  295.         DS1302_CE=0;
  296.         DS1302_SCLK=1;
  297.         DS1302_IO=0;        //讀取后將IO設置為0,否則讀出的數據會出錯
  298.         DS1302_IO=1;
  299.         DS1302_CE=1;
  300.         return Data;
  301. }

  302. /**
  303.   * @brief  DS1302設置時間,調用之后,DS1302_Time數組的數字會被設置到DS1302中
  304.   * @param  無
  305.   * @retval 無
  306.   */
  307. void DS1302_SetTime(void)
  308. {
  309.         DS1302_WriteByte(DS1302_WP,0x00);
  310.         DS1302_WriteByte(DS1302_HOUR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);
  311.         DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
  312.         DS1302_WriteByte(DS1302_SECOND,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
  313.         DS1302_WriteByte(DS1302_WP,0x80);
  314. }

  315. /**
  316.   * @brief  DS1302讀取時間,調用之后,DS1302中的數據會被讀取到DS1302_Time數組中
  317.   * @param  無
  318.   * @retval 無
  319.   */
  320. void DS1302_ReadTime(void)
  321. {
  322.         unsigned char Temp1;
  323.         Temp1=DS1302_ReadByte(DS1302_HOUR);
  324.         DS1302_Time[0]=Temp1/16*10+Temp1%16;
  325.         Temp1=DS1302_ReadByte(DS1302_MINUTE);
  326.         DS1302_Time[1]=Temp1/16*10+Temp1%16;
  327.         Temp1=DS1302_ReadByte(DS1302_SECOND);
  328.         DS1302_Time[2]=Temp1/16*10+Temp1%16;

  329. }


  330. unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0X40};

  331. void Nixie(unsigned char Location,Number){
  332.         switch(Location){
  333.                 case 1:P2_4=1;P2_3=1;P2_2=1;break;
  334.                 case 2:P2_4=1;P2_3=1;P2_2=0;break;
  335.                 case 3:P2_4=1;P2_3=0;P2_2=1;break;
  336.                 case 4:P2_4=1;P2_3=0;P2_2=0;break;
  337.                 case 5:P2_4=0;P2_3=1;P2_2=1;break;
  338.                 case 6:P2_4=0;P2_3=1;P2_2=0;break;
  339.                 case 7:P2_4=0;P2_3=0;P2_2=1;break;
  340.                 case 8:P2_4=0;P2_3=0;P2_2=0;break;
  341. }
  342.                 P0=NixieTable[Number];
  343.                         Delay(1);
  344.                         P0=0X00;
  345. }


  346. //引腳定義
  347. sbit OneWire_DQ=P3^7;

  348. /**
  349.   * @brief  單總線初始化
  350.   * @param  無
  351.   * @retval 從機響應位,0為響應,1為未響應
  352.   */
  353.         void Delay5us(){        //Delay 5us
  354. }

  355. void Delay500us()                //Delay 500us
  356. {
  357.         unsigned char i;

  358.         _nop_();
  359.         i = 227;
  360.         while (--i);
  361. }

  362. void Delay70us()                //Delay 70us
  363. {
  364.         unsigned char i;

  365.         _nop_();
  366.         i = 29;
  367.         while (--i);
  368. }

  369. void Delay10us()                //Delay 10us
  370. {
  371.         unsigned char i;

  372.         i = 2;
  373.         while (--i);
  374. }

  375. void Delay50us()                //@11.0592MHz
  376. {
  377.         unsigned char i;

  378.         _nop_();
  379.         i = 20;
  380.         while (--i);
  381. }

  382.         
  383.         
  384.         
  385.         
  386. unsigned char OneWire_Init(void)
  387. {
  388. //        unsigned char i;
  389.         unsigned char AckBit;
  390.         OneWire_DQ=1;
  391.         OneWire_DQ=0;
  392.         Delay500us();                //Delay 500us
  393.         OneWire_DQ=1;
  394.         Delay70us()        ;                //Delay 70us
  395.         AckBit=OneWire_DQ;
  396.         Delay500us()        ;        //Delay 500us
  397.         return AckBit;
  398. }

  399. /**
  400.   * @brief  單總線發送一位
  401.   * @param  Bit 要發送的位
  402.   * @retval 無
  403.   */
  404. void OneWire_SendBit(unsigned char Bit)
  405. {
  406. //        unsigned char i;
  407.         OneWire_DQ=0;
  408.         Delay10us();                        //Delay 10us
  409.         OneWire_DQ=Bit;
  410.         Delay50us();                        //Delay 50us
  411.         OneWire_DQ=1;
  412. }

  413. /**
  414.   * @brief  單總線接收一位
  415.   * @param  無
  416.   * @retval 讀取的位
  417.   */
  418. unsigned char OneWire_ReceiveBit(void)
  419. {
  420. //        unsigned char i;
  421.         unsigned char Bit;
  422.         OneWire_DQ=0;
  423.         Delay5us();                        //Delay 5us
  424.         OneWire_DQ=1;
  425.         Delay5us();                        //Delay 5us
  426.         Bit=OneWire_DQ;
  427.         Delay50us();                        //Delay 50us
  428.         return Bit;
  429. }

  430. /**
  431.   * @brief  單總線發送一個字節
  432.   * @param  Byte 要發送的字節
  433.   * @retval 無
  434.   */
  435. void OneWire_SendByte(unsigned char Byte)
  436. {
  437.         unsigned char i;
  438.         for(i=0;i<8;i++)
  439.         {
  440.                 OneWire_SendBit(Byte&(0x01<<i));
  441.         }
  442. }

  443. /**
  444.   * @brief  單總線接收一個字節
  445.   * @param  無
  446.   * @retval 接收的一個字節
  447.   */
  448. unsigned char OneWire_ReceiveByte(void)
  449. {
  450.         unsigned char i;
  451.         unsigned char Byte=0x00;
  452.         for(i=0;i<8;i++)
  453.         {
  454.                 if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
  455.         }
  456.         return Byte;
  457. }


  458. //DS18B20指令
  459. #define DS18B20_SKIP_ROM                        0xCC
  460. #define DS18B20_CONVERT_T                        0x44
  461. #define DS18B20_READ_SCRATCHPAD         0xBE

  462. /**
  463.   * @brief  DS18B20開始溫度變換
  464.   * @param  無
  465.   * @retval 無
  466.   */
  467. void DS18B20_ConvertT(void)
  468. {
  469.         OneWire_Init();
  470.         OneWire_SendByte(DS18B20_SKIP_ROM);
  471.         OneWire_SendByte(DS18B20_CONVERT_T);
  472. }

  473. /**
  474.   * @brief  DS18B20讀取溫度
  475.   * @param  無
  476.   * @retval 溫度數值
  477.   */
  478. double DS18B20_ReadT(void)
  479. {
  480.         unsigned char TLSB,TMSB;
  481.         float Temp;
  482.         int T;
  483.                 OneWire_Init();
  484.         OneWire_SendByte(DS18B20_SKIP_ROM);
  485.         OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
  486.         TLSB=OneWire_ReceiveByte();
  487.                 TMSB=OneWire_ReceiveByte();
  488.         Temp=(TMSB<<8)|TLSB;
  489.                                                 T=Temp/16.0;
  490.                                                 return T;
  491.                
  492.         

  493.         
  494. }


  495. #include <REGX52.H>

  496. //引腳配置:
  497. sbit LCD_RS=P2^6;
  498. sbit LCD_RW=P2^5;
  499. sbit LCD_EN=P2^7;
  500. #define LCD_DataPort P0

  501. //函數定義:
  502. /**
  503.   * @brief  LCD1602延時函數,12MHz調用可延時1ms
  504.   * @param  無
  505.   * @retval 無
  506.   */
  507. void LCD_Delay()
  508. {
  509.         unsigned char i, j;

  510.         i = 2;
  511.         j = 239;
  512.         do
  513.         {
  514.                 while (--j);
  515.         } while (--i);
  516. }

  517. /**
  518.   * @brief  LCD1602寫命令
  519.   * @param  Command 要寫入的命令
  520.   * @retval 無
  521.   */
  522. void LCD_WriteCommand(unsigned char Command)
  523. {
  524.         LCD_RS=0;
  525.         LCD_RW=0;
  526.         LCD_DataPort=Command;
  527.         LCD_EN=1;
  528.         LCD_Delay();
  529.         LCD_EN=0;
  530.         LCD_Delay();
  531. }

  532. /**
  533.   * @brief  LCD1602寫數據
  534.   * @param  Data 要寫入的數據
  535.   * @retval 無
  536.   */
  537. void LCD_WriteData(unsigned char Data)
  538. {
  539.         LCD_RS=1;
  540.         LCD_RW=0;
  541.         LCD_DataPort=Data;
  542.         LCD_EN=1;
  543.         LCD_Delay();
  544.         LCD_EN=0;
  545.         LCD_Delay();
  546. }

  547. /**
  548.   * @brief  LCD1602設置光標位置
  549.   * @param  Line 行位置,范圍:1~2
  550.   * @param  Column 列位置,范圍:1~16
  551.   * @retval 無
  552.   */
  553. void LCD_SetCursor(unsigned char Line,unsigned char Column)
  554. {
  555.         if(Line==1)
  556.         {
  557.                 LCD_WriteCommand(0x80|(Column-1));
  558.         }
  559.         else if(Line==2)
  560.         {
  561.                 LCD_WriteCommand(0x80|(Column-1+0x40));
  562.         }
  563. }

  564. /**
  565.   * @brief  LCD1602初始化函數
  566.   * @param  無
  567.   * @retval 無
  568.   */
  569. void LCD_Init()
  570. {
  571.         LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣
  572.         LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關
  573.         LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動
  574.         LCD_WriteCommand(0x01);//光標復位,清屏
  575. }

  576. /**
  577.   * @brief  在LCD1602指定位置上顯示一個字符
  578.   * @param  Line 行位置,范圍:1~2
  579.   * @param  Column 列位置,范圍:1~16
  580.   * @param  Char 要顯示的字符
  581.   * @retval 無
  582.   */
  583. void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
  584. {
  585.         LCD_SetCursor(Line,Column);
  586.         LCD_WriteData(Char);
  587. }

  588. /**
  589.   * @brief  在LCD1602指定位置開始顯示所給字符串
  590.   * @param  Line 起始行位置,范圍:1~2
  591.   * @param  Column 起始列位置,范圍:1~16
  592.   * @param  String 要顯示的字符串
  593.   * @retval 無
  594.   */
  595. void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
  596. {
  597.         unsigned char i;
  598.         LCD_SetCursor(Line,Column);
  599.         for(i=0;String[i]!='\0';i++)
  600.         {
  601.                 LCD_WriteData(String[i]);
  602.         }
  603. }

  604. /**
  605.   * @brief  返回值=X的Y次方
  606.   */
  607. int LCD_Pow(int X,int Y)
  608. {
  609.         unsigned char i;
  610.         int Result=1;
  611.         for(i=0;i<Y;i++)
  612.         {
  613.                 Result*=X;
  614.         }
  615.         return Result;
  616. }

  617. /**
  618.   * @brief  在LCD1602指定位置開始顯示所給數字
  619.   * @param  Line 起始行位置,范圍:1~2
  620.   * @param  Column 起始列位置,范圍:1~16
  621.   * @param  Number 要顯示的數字,范圍:0~65535
  622.   * @param  Length 要顯示數字的長度,范圍:1~5
  623.   * @retval 無
  624.   */
  625. void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  626. {
  627.         unsigned char i;
  628.         LCD_SetCursor(Line,Column);
  629.         for(i=Length;i>0;i--)
  630.         {
  631.                 LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
  632.         }
  633. }

  634. /**
  635.   * @brief  在LCD1602指定位置開始以有符號十進制顯示所給數字
  636.   * @param  Line 起始行位置,范圍:1~2
  637.   * @param  Column 起始列位置,范圍:1~16
  638.   * @param  Number 要顯示的數字,范圍:-32768~32767
  639.   * @param  Length 要顯示數字的長度,范圍:1~5
  640.   * @retval 無
  641.   */
  642. void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
  643. {
  644.         unsigned char i;
  645.         unsigned int Number1;
  646.         LCD_SetCursor(Line,Column);
  647.         if(Number>=0)
  648.         {
  649.                 LCD_WriteData('+');
  650.                 Number1=Number;
  651.         }
  652.         else
  653.         {
  654.                 LCD_WriteData('-');
  655.                 Number1=-Number;
  656.         }
  657.         for(i=Length;i>0;i--)
  658.         {
  659.                 LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
  660.         }
  661. }

  662. /**
  663.   * @brief  在LCD1602指定位置開始以十六進制顯示所給數字
  664.   * @param  Line 起始行位置,范圍:1~2
  665.   * @param  Column 起始列位置,范圍:1~16
  666.   * @param  Number 要顯示的數字,范圍:0~0xFFFF
  667.   * @param  Length 要顯示數字的長度,范圍:1~4
  668.   * @retval 無
  669.   */
  670. void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  671. {
  672.         unsigned char i,SingleNumber;
  673.         LCD_SetCursor(Line,Column);
  674.         for(i=Length;i>0;i--)
  675.         {
  676.                 SingleNumber=Number/LCD_Pow(16,i-1)%16;
  677.                 if(SingleNumber<10)
  678.                 {
  679.                         LCD_WriteData(SingleNumber+'0');
  680.                 }
  681.                 else
  682.                 {
  683.                         LCD_WriteData(SingleNumber-10+'A');
  684.                 }
  685.         }
  686. }

  687. /**
  688.   * @brief  在LCD1602指定位置開始以二進制顯示所給數字
  689.   * @param  Line 起始行位置,范圍:1~2
  690.   * @param  Column 起始列位置,范圍:1~16
  691.   * @param  Number 要顯示的數字,范圍:0~1111 1111 1111 1111
  692.   * @param  Length 要顯示數字的長度,范圍:1~16
  693.   * @retval 無
  694.   */
  695. void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  696. {
  697.         unsigned char i;
  698.         LCD_SetCursor(Line,Column);
  699.         for(i=Length;i>0;i--)
  700.         {
  701.                 LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
  702.         }
  703. }
復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:213173 發表于 2022-9-22 07:23 | 只看該作者
樓主的問題是按鍵掃描函數干擾數碼管動態顯示。參考這個示例修改即可。
DS18B20溫度上下限報警數碼管 1602顯示.rar (183.47 KB, 下載次數: 6)

回復

使用道具 舉報

板凳
ID:123289 發表于 2022-9-22 09:12 | 只看該作者
方案:
1、程序中禁止用DELAY函數。理由:它占用CPU時間,影響其它程序運行。
2、顯示的內容不要直接送LED顯示端口,而是統一送入一個緩沖區,緩沖區字節數與LED數量一樣,一一對應。理由:不同的程序要求的顯示格式、方式可能不同,集中處理,顯示不易出亂。
最后要的是:無論你如何變換顯示內容,都不會拖尾、重影,因為還未送到LED。
3、寫個顯示程序,只從緩沖區中取數顯示就可以了,單一而簡單。
4、掃描顯示注意以下次序:先關所有顯示,再送出緩沖區中的段碼,再打開所有顯示。這樣就無重影了。

寫程序要先規劃好方案。
回復

使用道具 舉報

地板
ID:584814 發表于 2022-9-22 10:44 | 只看該作者
yzwzfyz 發表于 2022-9-22 09:12
方案:
1、程序中禁止用DELAY函數。理由:它占用CPU時間,影響其它程序運行。
2、顯示的內容不要直接送LE ...

1、程序中禁止用DELAY函數。理由:它占用CPU時間,影響其它程序運行。

僅這一條就能把人嚇傻
回復

使用道具 舉報

5#
ID:1007932 發表于 2022-9-22 12:24 | 只看該作者
man1234567 發表于 2022-9-22 10:44
1、程序中禁止用DELAY函數。理由:它占用CPU時間,影響其它程序運行。

僅這一條就能把人嚇傻

確實,51資源太少了,很多情況只能用delay,只能說盡量少用,比如用定時器定時讀取刷新數據,再不然就時分多任務,但要額外占用資源,很多時候還不如用delay。
回復

使用道具 舉報

6#
ID:1007932 發表于 2022-9-22 12:26 | 只看該作者
下一次顯示時,上一次的位碼或斷碼沒有關閉。
回復

使用道具 舉報

7#
ID:1034262 發表于 2022-9-22 14:29 | 只看該作者
掃描更新時,先輸出位控無效,再裝載段碼,再允許位控。
回復

使用道具 舉報

8#
ID:161164 發表于 2022-9-22 16:12 | 只看該作者
DS18B20的掃描時間太短了
每次掃描之間要留最少750ms來溫度轉換
時間不夠,返回值有可能大于99
Nixie(6,T/10);這里T/10有可能大于18
NixieTable[T/10]就溢出了
回復

使用道具 舉報

9#
ID:1045483 發表于 2022-9-22 17:26 | 只看該作者
感謝樓上各位大佬,問題已解決,是定時器中斷會影響DS18B20的讀取。在執行OneWire_Init(void)OneWire_SendBit(unsigned char Bit)時把定時器關了,執行完再打開定時器就可以解決殘影閃爍的問題,也不影響其他功能。
再次感謝各位
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久99精品国产99久久6男男 | 国产一二三区免费视频 | 国产真实精品久久二三区 | 欧洲一级毛片 | 曰韩一二三区 | 伊人伊人网 | 在线成人免费av | 在线国产一区 | 91最新视频| 在线播放亚洲 | 亚洲人成人一区二区在线观看 | 精品综合久久久 | 黄色日批视频 | 国产三级在线观看播放 | 精品蜜桃一区二区三区 | 亚洲人在线 | 国产在线精品一区 | a成人| 欧美激情网站 | 夜夜草 | h视频在线免费观看 | 欧美性网站| 欧美日韩三级 | 久久69精品久久久久久久电影好 | 91精品国产一区二区三区动漫 | 一区二区三区视频在线免费观看 | 日韩中文久久 | 欧美日韩毛片 | 日韩欧美三级在线 | 亚洲精品乱码久久久久久黑人 | 国产成人免费视频网站高清观看视频 | 亚洲人成人一区二区在线观看 | 日韩欧美在线视频观看 | 久久骚| 欧美黑人又粗大 | 欧美性区 | 中文字幕成人在线 | 国产av毛片| 中文字幕第一页在线 | 天天综合网天天综合 | 久久久蜜桃 |