找回密码
 立即注册
查看: 382|回复: 0

段码LCD驱动代码,简洁版。0.5s增加数字加1

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2024-10-31 08:51:49

5

主题

16

回帖

133

积分

注册会员

积分
133
发表于 2024-11-5 16:03:26 | 显示全部楼层 |阅读模式
本帖最后由 whoyzf 于 2024-11-5 18:10 编辑

显示效果888e.jpg 映射表.png


  1. /*********************************************************/
  2. #define MAIN_Fosc                11059200L        //定义主时钟
  3. #include        "STC8H4K64TL.h"
  4. /*************        功能说明        **************
  5. 888e
  6. 硬件连接及LCD_buff
  7.                                         SEG22        SEG21        SEG20        SEG19        SEG18        SEG17               
  8. 1  2        3         4                10         9         8         7         6         5               
  9.                         COM0                3A        4A        2A        4D        1A        4G                C0SEGV2
  10.                 COM1                        3B        3F        2B        2F        1B        1F                C1SEGV2
  11.         COM2                                3C        3G        2C        2G        1C        1G                C2SEGV2
  12. COM3                                        3D        3E        2D        2E        1D        1E                C1SEGV2
  13. ******************************************/
  14. /*************        本地常量声明        **************/
  15. /*************        本地IO定义        **************/
  16. /*************        本地变量声明        **************/
  17. bit        B_500mS;        // 0.5秒时隙标志
  18. bit        B_20ms;                // 20ms时隙标志
  19. u8        OpTime;                // 此变量非0时, 不睡眠, 连续运行程序(本例串口唤醒后连续运行5秒, 以便正确接收串口数据)
  20. u8 uc0_5sflag=0;
  21. /*************        本地函数声明        **************/
  22. u8                Timer0_Config(u32 reload);        //reload值是主时钟周期数
  23. void        LCD_config(void);
  24. void        ReadKey(void);        //50ms call
  25. unsigned char segmentCodes[10] = {
  26.     0x3F, // 0   - a-g: 00011111
  27.     0x06, // 1   - a-g: 00000110
  28.     0x5B, // 2   - a-g: 01011011
  29.     0x4F, // 3   - a-g: 01001111
  30.     0x66, // 4   - a-g: 01100110
  31.     0x6D, // 5   - a-g: 01101101
  32.     0x7d, // 6   - a-g: 01111101
  33.     0x07, // 7   - a-g: 00000111
  34.     0x7F, // 8   - a-g: 01111111
  35.     0x6f  // 9   - a-g: 01101111
  36. };
  37. /****************** 对第1~5数字装载显示函数 ***************************/
  38. u8 code t_display[]={                                                //标准字库
  39. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  40.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  41. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  42.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};
  43. void displayThreeDigits(unsigned int number) ;
  44. void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units);
  45. // 函数用于显示一个三位数
  46. void displayThreeDigits(unsigned int number) {
  47.     unsigned char hundreds ;        // 百位
  48.     unsigned char tens ;       // 十位
  49.     unsigned char units ;            // 个位
  50.         hundreds = number / 100;        // 百位
  51.         tens = (number / 10) % 10;       // 十位
  52.         units = number % 10;            // 个位
  53.         
  54.     // 初始化寄存器
  55.     C0SEGV2 = 0x00;
  56.     C1SEGV2 = 0x00;
  57.     C2SEGV2 = 0x00;
  58.     C3SEGV2 = 0x00;
  59. updateSegments(hundreds,tens,units);
  60. }
  61. // 函数用于更新段寄存器
  62. void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units) {
  63.         
  64.     // 左起第一位,控制1A到1G位
  65.     if ((segmentCodes[hundreds] & 0x01) == 0) C0SEGV2 &= 0xfb; else C0SEGV2 |= 0x04; // 1A位是0,或者1
  66.     if ((segmentCodes[hundreds] & 0x02) == 0) C1SEGV2 &= 0xfb; else C1SEGV2 |= 0x04; // 1B位是0,或者1
  67.     if ((segmentCodes[hundreds] & 0x04) == 0) C2SEGV2 &= 0xfb; else C2SEGV2 |= 0x04; // 1C位是0,或者1
  68.     if ((segmentCodes[hundreds] & 0x08) == 0) C3SEGV2 &= 0xfb; else C3SEGV2 |= 0x04; // 1D位是0,或者1
  69.     if ((segmentCodes[hundreds] & 0x10) == 0) C3SEGV2 &= 0xfd; else C3SEGV2 |= 0x02; // 1E位是0,或者1
  70.     if ((segmentCodes[hundreds] & 0x20) == 0) C1SEGV2 &= 0xfd; else C1SEGV2 |= 0x02; // 1F位是0,或者1
  71.     if ((segmentCodes[hundreds] & 0x40) == 0) C2SEGV2 &= 0xfd; else C2SEGV2 |= 0x02; // 1G位是0,或者1
  72.     // 左起第二位,控制2A到2G位
  73.     if ((segmentCodes[tens] & 0x01) == 0) C0SEGV2 &= 0xef; else C0SEGV2 |= 0x10;
  74.     if ((segmentCodes[tens] & 0x02) == 0) C1SEGV2 &= 0xef; else C1SEGV2 |= 0x10;
  75.     if ((segmentCodes[tens] & 0x04) == 0) C2SEGV2 &= 0xef; else C2SEGV2 |= 0x10;
  76.     if ((segmentCodes[tens] & 0x08) == 0) C3SEGV2 &= 0xef; else C3SEGV2 |= 0x10;
  77.     if ((segmentCodes[tens] & 0x10) == 0) C3SEGV2 &= 0xf7; else C3SEGV2 |= 0x08;
  78.     if ((segmentCodes[tens] & 0x20) == 0) C1SEGV2 &= 0xf7; else C1SEGV2 |= 0x08;
  79.     if ((segmentCodes[tens] & 0x40) == 0) C2SEGV2 &= 0xf7; else C2SEGV2 |= 0x08;
  80.     // 左起第三位,控制3A到3G位
  81.     if ((segmentCodes[units] & 0x01) == 0) C0SEGV2 &= 0xbf; else C0SEGV2 |= 0x40;
  82.     if ((segmentCodes[units] & 0x02) == 0) C1SEGV2 &= 0xbf; else C1SEGV2 |= 0x40;
  83.     if ((segmentCodes[units] & 0x04) == 0) C2SEGV2 &= 0xbf; else C2SEGV2 |= 0x40;
  84.     if ((segmentCodes[units] & 0x08) == 0) C3SEGV2 &= 0xbf; else C3SEGV2 |= 0x40;
  85.     if ((segmentCodes[units] & 0x10) == 0) C3SEGV2 &= 0xdf; else C3SEGV2 |= 0x20;
  86.     if ((segmentCodes[units] & 0x20) == 0) C1SEGV2 &= 0xdf; else C1SEGV2 |= 0x20;
  87.     if ((segmentCodes[units] & 0x40) == 0) C2SEGV2 &= 0xdf; else C2SEGV2 |= 0x20;
  88.                
  89. }
  90. void main(void)
  91. {
  92.         unsigned char ucshow=0,i=0;
  93.         P0M1 = 0;        P0M0 = 0;
  94.         P1M1 = 0;        P1M0 = 0;
  95.         P2M1 = 0;        P2M0 = 0;
  96.         P3M1 = 0X80;        P3M0 = 0;
  97.         P4M1 = 0;        P4M0 = 0;
  98.         P5M1 = 0;        P5M0 = 0;
  99.         P6M1 = 0;        P6M0 = 0;
  100.         P7M1 = 0;        P7M0 = 0;
  101.         Timer0_Config(MAIN_Fosc / 50);        //reload值是主时钟周期数,  (中断频率, 50次/秒)
  102.         EA = 1;
  103. P37=0;
  104.         
  105. //        OpTime  = 0;
  106. //        DisMode = 0;
  107. //         RTC_config();
  108.         LCD_config();
  109. while(1)
  110. {
  111. if(uc0_5sflag==1)
  112. {
  113. uc0_5sflag=0;
  114.         
  115.   ucshow++;
  116. //        COMLENM=ucshow;
  117. //        COMLENL=(255-ucshow);
  118. //        C0SEGV2=ucshow;
  119. //        C1SEGV2=ucshow;
  120. //        C3SEGV2=ucshow;
  121.   C0SEGV2 = 0x00;        
  122.         C1SEGV2 = 0x00;        
  123.         C2SEGV2 = 0x00;        
  124.         C3SEGV2 = 0x00;        
  125.         // 设置C0SEGV2, C1SEGV2, C2SEGV2, C3SEGV2寄存器
  126. //        C0SEGV2 = segValues[1][0];
  127. //        C1SEGV2 = segValues[1][1];
  128. //        C2SEGV2 = segValues[1][2];
  129. //        C3SEGV2 = segValues[1][3];
  130. //i=8;
  131. /*        
  132. //左起第一位,        
  133. if ((segmentCodes[i] & 0x01) == 0)   C0SEGV2 &= 0xfb; // 1A位是0
  134.           else                             C0SEGV2 |= 0x04; // 1A位是1   
  135. if ((segmentCodes[i] & 0x02) == 0)   C1SEGV2 &= 0xfb; // 1B位是0
  136.           else                             C1SEGV2 |= 0x04; // 1B位是1   
  137. if ((segmentCodes[i] & 0x04) == 0)   C2SEGV2 &= 0xfb; // 1C位是0
  138.           else                             C2SEGV2 |= 0x04; // 1C位是1   
  139. if ((segmentCodes[i] & 0x08) == 0)   C3SEGV2 &= 0xfb; // 1D位是0
  140.           else                             C3SEGV2 |= 0x04; // 1D位是1   
  141.                
  142. if ((segmentCodes[i] & 0x10) == 0)   C3SEGV2 &= 0xfd; // 1E位是0
  143.           else                             C3SEGV2 |= 0x02; // 1E位是1   
  144. if ((segmentCodes[i] & 0x20) == 0)   C1SEGV2 &= 0xfd; // 1F位是0
  145.           else                             C1SEGV2 |= 0x02; // 1F位是1   
  146. if ((segmentCodes[i] & 0x40) == 0)   C2SEGV2 &= 0xfd; // 1G位是0
  147.           else                             C2SEGV2 |= 0x02; // 1G位是1   
  148. //if ((segmentCodes[i] & 0x08) == 0)                    // 1H位是0
  149. //          else                                              // 1H位是1   
  150. //左起第二位,        
  151. if ((segmentCodes[i] & 0x01) == 0)   C0SEGV2 &= 0xef; // 2A位是0
  152.           else                             C0SEGV2 |= 0x10; // 2A位是1   
  153. if ((segmentCodes[i] & 0x02) == 0)   C1SEGV2 &= 0xef; // 2B位是0
  154.           else                             C1SEGV2 |= 0x10; // 2B位是1   
  155. if ((segmentCodes[i] & 0x04) == 0)   C2SEGV2 &= 0xef; // 2C位是0
  156.           else                             C2SEGV2 |= 0x10; // 2C位是1   
  157. if ((segmentCodes[i] & 0x08) == 0)   C3SEGV2 &= 0xef; // 2D位是0
  158.           else                             C3SEGV2 |= 0x10; // 2D位是1   
  159.                                                                                                                                                                                                                                  
  160. if ((segmentCodes[i] & 0x10) == 0)   C3SEGV2 &= 0xf7; // 2E位是0
  161.           else                             C3SEGV2 |= 0x08; // 2E位是1   
  162. if ((segmentCodes[i] & 0x20) == 0)   C1SEGV2 &= 0xf7; // 2F位是0
  163.           else                             C1SEGV2 |= 0x08; // 2F位是1   
  164. if ((segmentCodes[i] & 0x40) == 0)   C2SEGV2 &= 0xf7; // 2G位是0
  165.           else                             C2SEGV2 |= 0x08; // 2G位是1   
  166. //if ((segmentCodes[i] & 0x08) == 0)                    // 1H位是0
  167. //          else     
  168. //左起第二位,        
  169. if ((segmentCodes[i] & 0x01) == 0)   C0SEGV2 &= 0xbf; // 3A位是0
  170.           else                             C0SEGV2 |= 0x40; // 3A位是1   
  171. if ((segmentCodes[i] & 0x02) == 0)   C1SEGV2 &= 0xbf; // 3B位是0
  172.           else                             C1SEGV2 |= 0x40; // 3B位是1   
  173. if ((segmentCodes[i] & 0x04) == 0)   C2SEGV2 &= 0xbf; // 3C位是0
  174.           else                             C2SEGV2 |= 0x40; // 3C位是1   
  175. if ((segmentCodes[i] & 0x08) == 0)   C3SEGV2 &= 0xbf; // 3D位是0
  176.           else                             C3SEGV2 |= 0x40; // 3D位是1   
  177.                                                                                                                                                                                                                                  
  178. if ((segmentCodes[i] & 0x10) == 0)   C3SEGV2 &= 0xdf; // 3E位是0
  179.           else                             C3SEGV2 |= 0x20; // 3E位是1   
  180. if ((segmentCodes[i] & 0x20) == 0)   C1SEGV2 &= 0xdf; // 3F位是0
  181.           else                             C1SEGV2 |= 0x20; // 3F位是1   
  182. if ((segmentCodes[i] & 0x40) == 0)   C2SEGV2 &= 0xdf; // 3G位是0
  183.           else                             C2SEGV2 |= 0x20; // 3G位是1   
  184. //if ((segmentCodes[i] & 0x08) == 0)                    // 1H位是0
  185. //          else     
  186. */
  187. displayThreeDigits(i);
  188.                         
  189.                 i++;        
  190.   if(i>250)i=0;              
  191.         
  192.         
  193.         
  194.         if(ucshow>=0xFF)
  195.         {
  196.            ucshow=0x00;
  197. //                        X32KCR = 0x00;
  198.          }
  199. }
  200. }
  201.         
  202. }
  203. /********************* INT0中断函数 *************************/
  204. void Ext_INT0 (void) interrupt 0
  205. {
  206.         OpTime = 6;
  207. }
  208. /********************** LCD配置函数 *****************************/
  209. void        LCD_config(void)
  210. {
  211. //        u8        i;
  212.         P_SW2 |= 0x80;                // SFR enable
  213.         
  214. //        X32KCR = 0x80 + 0x40;                //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
  215. //  P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
  216. //        P1IE = ~0xc0;                                //P1.6 P1.7关闭数字输入功能
  217. //        X32KCR = 0x80;
  218.         
  219.         LCDCFG  = 0xc0 + 7;        // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
  220. //        LCDCFG|=0x07;
  221.         
  222.         //        X32KCR = 0x80 + 0x40;                //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
  223.   P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
  224.         P1IE = ~0xc0;                                //P1.6 P1.7关闭数字输入功能
  225.         X32KCR = 0x80;
  226.         
  227.         
  228.         
  229.         DBLEN   = 0;                // 设置LCD显示时的死区时间长度, 取值0~7.
  230.         COMLENH        = 0;                // COM时间长度设置 高字节COMLEN[19:16],  一共20bit.
  231.         COMLENM        = 0;                // COM时间长度设置 中字节COMLEN[15:8]        LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
  232.         COMLENL        = 65;                // COM时间长度设置 低字节COMLEN[7:0]        LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
  233.         BLINKRATE = 60;                // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz
  234.         COMON  = 0x0f;                // COM使能寄存器
  235.         SEGON1 = 0x00;                // SEG线使能寄存器1, SEG7~SEG0
  236.         SEGON2 = 0x00;                // SEG线使能寄存器2, SEG15~SEG8
  237.         SEGON3 = 0x7e;                // SEG线使能寄存器3, SEG23~SEG16
  238.         SEGON4 = 0x00;                // SEG线使能寄存器4, SEG31~SEG24
  239.         SEGON5 = 0x00;                // SEG线使能寄存器5, SEG39~SEG32
  240.         
  241. //        P5n_pure_input(0x03);        //P5.0 P5.1 设置为高阻输入        COM0 COM1
  242. //        P3n_pure_input(0x60);        //P3.5 P3.6 设置为高阻输入        COM2 COM3
  243. //    P3M0 = 0x00; P3M1 = 0xFF;
  244. //    P5M0 = 0x00; P5M1 = 0xFF;
  245. //    P3DR = 0x00;
  246. //    P0DR = 0x00;
  247. //        LCDCFG2 = 0x0f;                        // SEG0~3切换到P7.7~7.4
  248. //        P7n_pure_input(0xf0);        //P7.7~P7.4 设置为高阻输入        SEG0~SEG3 (对应P7.7~7.4)
  249. //        P4n_pure_input(0x80);        //P4.7      设置为高阻输入        SEG4
  250. //        P1n_pure_input(0x03);        //P1.1~P1.0 设置为高阻输入        SEG5 SEG6       (对应P1.1 P1.0)
  251. //        P0n_pure_input(0x60);        //P0.7~P0.5 设置为高阻输入        SEG7 SEG8 SEG9  (对应P0.7 P0.6 P0.5)
  252. //        P5n_pure_input(0x0C);        //P5.3 P5.2 设置为高阻输入        SEG10 SEG11     (对应P5.3 P5.2)
  253. //        P0n_pure_input(0x1f);        //P0.4~P0.0 设置为高阻输入        SEG12~SEG16  (对应P0.4 ~ 0.0)
  254. //        P4n_pure_input(0x60);        //P4.6 P4.5 设置为高阻输入        SEG17 SEG18
  255. //        P2n_pure_input(0xF0);        //P2.7~P2.0 设置为高阻输入        SEG19~SEG26  (对应P2.7~2.0)
  256. //    P2M0 = 0x00; P2M1 = 0xFF;
  257. //    P4M0 = 0x00; P4M1 = 0xFF;
  258. //          P2DR = 0x00;
  259. //    P4DR = 0x00;
  260. //        P4n_pure_input(0x1e);        //P4.4~P4.1 设置为高阻输入        SEG27~SEG30  (对应P4.4~4.1)
  261. //        P3n_pure_input(0x80);        //P3.7      设置为高阻输入        SEG31
  262. //        P7n_pure_input(0x0f);        //P7.3~P7.0 设置为高阻输入        SEG32~SEG35  (对应P7.3~7.0)
  263. //        P6n_pure_input(0x0f);        //P6.0~P6.3 设置为高阻输入        SEG36~SEG39  (对应P6.3~6.0)
  264.         
  265.         C0SEGV2 = 0x00;        
  266.         C1SEGV2 = 0x00;        
  267.         C2SEGV2 = 0x00;        
  268.         C3SEGV2 = 0x00;               
  269.         
  270.         LCDCR = (0<<1) + 1;        // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式.  +0:禁止LCD模块,  +1:允许LCD模块.
  271.         
  272. }
  273. //========================================================================
  274. // 函数:u8        Timer0_Config(u32 reload)
  275. // 描述: timer0初始化函数.
  276. // 参数: reload: 重装值.
  277. // 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
  278. // 版本: V1.0, 2018-3-5
  279. //========================================================================
  280. u8        Timer0_Config(u32 reload)        //t=0: reload值是主时钟周期数,  t=1: reload值是时间(单位us)
  281. {
  282.         TR0 = 0;        //停止计数
  283.         if(reload >= (65536UL * 12))        return 1;        //值过大, 返回错误
  284.         if(reload < 65536UL)        AUXR |= 0x80;                //1T mode
  285.         else
  286.         {
  287.                 AUXR &= ~0x80;        //12T mode
  288.                 reload = reload / 12;
  289.         }
  290.         reload = 65536UL - reload;
  291.         TH0 = (u8)(reload >> 8);
  292.         TL0 = (u8)(reload);
  293.         ET0 = 1;        //允许中断
  294.         TMOD = (TMOD & ~0x03) | 0;        //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
  295.         TR0 = 1;                        //开始运行
  296.         return 0;
  297. }
  298. //========================================================================
  299. // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
  300. // 描述:  timer0中断函数.
  301. // 参数: none.
  302. // 返回: none.
  303. // 版本: V1.0, 2016-5-12
  304. //========================================================================
  305. void timer0_ISR (void) interrupt TIMER0_VECTOR
  306. {
  307.         static u8 i;
  308.         
  309.    B_20ms = 1;        //20ms时隙标志
  310.         
  311.         i++;
  312.         if(i>=5)
  313.         {
  314.                 i=0;
  315.     uc0_5sflag=1;
  316. //          P37=!P37;
  317.         }
  318.         
  319. }
复制代码


回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:47 , Processed in 0.102215 second(s), 48 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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