设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 987|回复: 0
收起左侧

STC12C5A单片机 硬件SPI驱动3个74HC595级联静态共阴数码管显示范围:-99~999的浮点小数

[复制链接]
发表于 2022-8-17 09:45:54 | 显示全部楼层 |阅读模式
1.png
  1. #include "STC12C5A60S2.h"
  2. #include "intrins.h"
  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long
  6. #define T1ms 0xF830                        //24Mhz 1ms定时器初值

  7. sbit hc595_oe = P1 ^ 3;                //高电平关闭595输出 (低电平打开输出,防止上电瞬间乱码)
  8. sbit hc595_stcp = P1 ^ 4;         //上升沿输出595内部数据                PIN12        (SPI片选,任意IO)
  9. sbit hc595_ds = P1 ^ 5;                 //595被锁存的数据                PIN14        (SPI_MOSI)        P1.5
  10.                                                                 //        (SPI_MISO)        P1.6        (不使用)
  11. sbit hc595_shcp = P1 ^ 7;         //上升沿锁存数据到595内部        PIN11        (SPI_SCL)        P1.7

  12. #define hc595_num 3                        //595级联数量
  13. u8 hc595_data[hc595_num];                //595数据容器

  14. void hc595(bit open) {                //使用硬件SPI操作74HC595 请将数据写入 hc595_data 数组 然后发送 参数:1打开输出 0高阻输出
  15.         u8 k = hc595_num - 1;
  16.         do {
  17.                         SPDAT = hc595_data[k];
  18.                         while(!(SPSTAT & 0x80));
  19.                         SPSTAT = 0xC0;
  20.         } while (k--);
  21.         hc595_oe = !open;
  22.         hc595_stcp=0;
  23.         hc595_stcp=1;
  24. }

  25. void InitTimer0(){
  26.     TMOD = 0x01;
  27.     TH0 = T1ms >> 8;
  28.     TL0 = T1ms;
  29.     EA = 1;
  30.     ET0 = 1;
  31.     TR0 = 1;
  32. }

  33. u8 code nbr[16] = {                //共阴数码管段码16进制
  34.         0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
  35. };

  36. void main() {
  37.         SPCTL = 0xDC;        //开硬件SPI
  38.         WDT_CONTR = 0x27;        //开看门狗
  39.         InitTimer0();                //开1ms定时器中断
  40.         while (1){
  41.                 _nop_();_nop_();
  42.                 WDT_CONTR |= 0x10;                //看门狗喂狗
  43.                 _nop_();_nop_();
  44.         }
  45. }

  46. /*
  47. 浮点小数转3位共阴数码管段码数据 小数范围:-99~999
  48. 正数:
  49. 0.00~9.99         2位小数
  50. 10.0~99.9         1位小数
  51. 100~999         无小数
  52. 负数:
  53. -9.9~-0.1        1位小数
  54. -99~-10                无小数
  55. */
  56. u32 float2seg3(float val){
  57.         u8 i[3];                //3位数码管段码数据
  58.         bit neg = (val < 0);                //是否为负数
  59.         u16 val2;                //小数化整用
  60.         u8 dot = 0;                //小数点位置 0:无 1:百位 2:十位 3:个位
  61.         if(val >= 999){
  62.                 val = 999;
  63.         } else if(val <= -99){
  64.                 val = -99;
  65.         }
  66.         if(neg) val = 0 - val;
  67.         if(val >= 0 && val < 10){
  68.                 val2 = val * 100;
  69.                 dot = 1;
  70.         } else if(val >= 10 && val < 100){
  71.                 val2 = val * 10;
  72.                 dot = 2;
  73.         } else if(val >= 100 && val < 1000){
  74.                 val2 = val;
  75.                 dot = 0;
  76.         }

  77.         if(neg){                //负数
  78.                 if(++dot == 3){
  79.                         dot = 0;
  80.                 }
  81.                 i[0] = 0x40;                //负号
  82.                 i[1] = nbr[(val2/100)%10];
  83.                 i[2] = nbr[(val2/10)%10];

  84.         } else {        //正数
  85.                 i[0] = nbr[(val2/100)%10];
  86.                 i[1] = nbr[(val2/10)%10];
  87.                 i[2] = nbr[val2%10];
  88.         }

  89.         if(dot){
  90.                 i[dot-1] |= 0x80;
  91.         }
  92.         return (u32)(i[0]) | ((u32)(i[1]) << 8) | ((u32)(i[2]) << 16);
  93. }

  94. void Timer0Interrupt() interrupt 1{                //24Mhz 1ms定时器中断
  95.         u32 j;

  96.         static float f = -99.99;
  97.         static bit b = 1;
  98.     TH0 = T1ms >> 8;
  99.     TL0 = T1ms;

  100.         j = float2seg3(f);
  101.         if(b){
  102.                 f += 0.01;
  103.         } else {
  104.                 f -= 0.01;
  105.         }

  106.         if(f >= 999.99 || f <= -99.99){
  107.                 b = !b;
  108.         }

  109.         hc595_data[0]= j & 255;                //74HC595:U1
  110.         hc595_data[1]= j >> 8;                //74HC595:U2
  111.         hc595_data[2]= j >> 16;                //74HC595:U3
  112.         
  113.         hc595(1);               
  114.         
  115.         if(_testbit_(TF0)){
  116.                 hc595(0);
  117.                 while(1);
  118.         }
  119. }
复制代码

相关帖子

您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-19 09:44 , Processed in 0.483028 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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