查看: 1004|回复: 0

[分享] LPC1768 控制8位数码管定时器动态扫描显示

[复制链接]
  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
    发表于 2020-11-7 14:48:43 | 显示全部楼层 |阅读模式
    本帖最后由 胤幻1988 于 2020-11-7 14:51 编辑

    今天写一个数码管显示的程序,数码管在开发板上出现的概率越来越低了,仅在低端的51上还能看见。但是在节约成本的场合还是用的比较频繁的一个器件。论坛有位朋友想要一份数码管的显示程序,我手头整合有旺宝的LCP1768的板子,加一个老的51板上有数码管模块,硬件还算齐全,那么就开干吧。并没有完全切合那位朋友的电路,但流程大致都相同,还是能参考参考的。请只看数码管相关的,其他外设请忽略。这里用的573锁存器,锁存控制引脚高电平时同步数据,低电平时锁存。用138译码器,就控制ABC3个选通端来控制位选,然后在定时器中断程序里面
    一位一位的显示。
    硬件连接:
    数码管电路:
    QQ图片20201107142325.png
    MCU(LPC1768)引脚部分:
    位锁存器控制引脚:
    位码 :A-->1.0  
    段锁存器控制引脚:
    段码 : B-->1.1
    段码对应引脚(PA00~PA07为上图数码管控制引脚标号):
    PA00-->2.0
    PA01-->2.1
    PA02-->2.2
    PA03-->2.3
    PA04-->2.4
    PA05-->2.5
    PA06-->2.6
    PA07-->2.7
    思路:主函数while里面变化显示的变量,在定时器里面刷新数码管的显示:
    smg.c:
    1. #include "smg.h"
    2. #include "timer.h"

    3. // 当前数码管为共阴极数码管
    4. // 显示段码值01234567 +''
    5. unsigned char dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
    6. //分别对应相应的数码管点亮,即位码
    7. unsigned char dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
    8. //当前要显示的数值
    9. uint32_t smgdata=0;
    10. //显示数值分析后的数组
    11. uint8_t showbuf[8]={0};

    12. void SMG_Config(void)
    13. {
    14.   //段码、位码
    15.         Chip_GPIO_Init(LPC_GPIO);//打开GPIO外设时钟
    16.         Chip_IOCON_PinMux(LPC_IOCON, 2, 0, IOCON_MODE_INACT, IOCON_FUNC0);//设置P2.0为GPIO功能
    17.         Chip_IOCON_PinMux(LPC_IOCON, 2, 1, IOCON_MODE_INACT, IOCON_FUNC0);        
    18.         Chip_IOCON_PinMux(LPC_IOCON, 2, 2, IOCON_MODE_INACT, IOCON_FUNC0);
    19.         Chip_IOCON_PinMux(LPC_IOCON, 2, 3, IOCON_MODE_INACT, IOCON_FUNC0);        
    20.         Chip_IOCON_PinMux(LPC_IOCON, 2, 4, IOCON_MODE_INACT, IOCON_FUNC0);
    21.         Chip_IOCON_PinMux(LPC_IOCON, 2, 5, IOCON_MODE_INACT, IOCON_FUNC0);        
    22.         Chip_IOCON_PinMux(LPC_IOCON, 2, 6, IOCON_MODE_INACT, IOCON_FUNC0);
    23.         Chip_IOCON_PinMux(LPC_IOCON, 2, 7, IOCON_MODE_INACT, IOCON_FUNC0);
    24.   Chip_GPIO_SetPinDIR(LPC_GPIO,2, 0, true);//设置输出模式
    25.         Chip_GPIO_SetPinDIR(LPC_GPIO,2, 1, true);//设置输出模式
    26.         Chip_GPIO_SetPinDIR(LPC_GPIO,2, 2, true);//设置输出模式
    27.   Chip_GPIO_SetPinDIR(LPC_GPIO,2, 3, true);//设置输出模式
    28.   Chip_GPIO_SetPinDIR(LPC_GPIO,2, 4, true);//设置输出模式
    29.         Chip_GPIO_SetPinDIR(LPC_GPIO,2, 5, true);//设置输出模式
    30.         Chip_GPIO_SetPinDIR(LPC_GPIO,2, 6, true);//设置输出模式
    31.         Chip_GPIO_SetPinDIR(LPC_GPIO,2, 7, true);//设置输出模式
    32.         Chip_GPIO_SetPortValue(LPC_GPIO,2,0XFFFFFF00);//设置输出低电平 P2.0~P2.7
    33.         //锁存器控制
    34.         Chip_IOCON_PinMux(LPC_IOCON, 1, 0, IOCON_MODE_INACT, IOCON_FUNC0);//设置P1.0为GPIO功能
    35.         Chip_IOCON_PinMux(LPC_IOCON, 1, 1, IOCON_MODE_INACT, IOCON_FUNC0);
    36.         Chip_GPIO_SetPinDIR(LPC_GPIO,1, 0, true);//设置输出模式
    37.         Chip_GPIO_SetPinDIR(LPC_GPIO,1, 1, true);//设置输出模式
    38.         //初始状态
    39.         LAT_W_A(0);
    40.         LAT_D_B(0);

    41. }
    复制代码
    1. void SMG_WRITEONEBIT(uint8_t pos,uint8_t data)
    2. {
    3.         DataPort(dofly_WeiMa[pos]); //取位码

    4.         LAT_W_A(1);     //位锁存
    5.         my_delay(5);
    6.         LAT_W_A(0);
    7.         my_delay(5);

    8.         DataPort(dofly_DuanMa[data]); //取显示数据,段码
    9.         LAT_D_B(1);     //段锁存
    10.         my_delay(5);
    11.         LAT_D_B(0);
    12.         my_delay(5);
    13. }

    14. void SMG_ANALYSISDATA(uint32_t tmpdata)
    15. {
    16.         uint8_t ge=0,shi=0,bai=0,qian=0,wan=0,shiwan=0,baiwan=0,qianwan=0;

    17.         //推荐放在定时器里面
    18.         //分析要显示的数据
    19.         if (tmpdata>=100000000) tmpdata=99999999;
    20.         
    21.         qianwan=tmpdata/10000000;
    22.         baiwan =tmpdata%10000000 /1000000;
    23.         shiwan =tmpdata%1000000  /100000;
    24.         wan    =tmpdata%100000   /10000;
    25.         qian   =tmpdata%10000    /1000;
    26.         bai    =tmpdata%1000     /100;
    27.         shi    =tmpdata%100      /10;
    28.         ge     =tmpdata%10       /1;

    29.         //检测千位位是否为0
    30.         if(qianwan==0)
    31.         {
    32.                 showbuf[0]=11;//段码11对应全黑
    33.         }
    34.         else//千万位不为0
    35.         {
    36.                 //显示千万位
    37.                 showbuf[0]=qianwan;//段码11对应全黑
    38.         }
    39.         //检测百万位
    40.         if(baiwan==0)
    41.         {
    42.                 showbuf[1]=11;//段码11对应全黑
    43.                 //如果前面位有不为0的,就必须显示0
    44.                 if(qianwan!=0)
    45.                   showbuf[1]=0;//段码11对应全黑
    46.         }
    47.         else
    48.         {
    49.                 //显示千万位
    50.                 showbuf[1]=baiwan;
    51.         }
    52.         
    53.         //检测十万位
    54.         if(shiwan==0)
    55.         {
    56.                 showbuf[2]=11;
    57.                 //如果前面位有不为0的,就必须显示0
    58.                 if((qianwan!=0)||(baiwan!=0))
    59.                         showbuf[2]=0;
    60.         }
    61.         else
    62.         {
    63.                 //显示十万位
    64.                 showbuf[2]=shiwan;
    65.         }
    66.         
    67.         //检测万位
    68.         if(wan==0)
    69.         {
    70.                 showbuf[3]=11;
    71.                 //如果前面位有不为0的,就必须显示0
    72.                 if((qianwan!=0)||(baiwan!=0)||(shiwan!=0))
    73.                         showbuf[3]=0;
    74.         }
    75.         else
    76.         {
    77.                 //显示万位
    78.                 showbuf[3]=wan;
    79.         }
    80.         
    81.         //检测千位
    82.         if(qian==0)
    83.         {
    84.                 showbuf[4]=11;
    85.                 //如果前面位有不为0的,就必须显示0
    86.                 if((qianwan!=0)||(baiwan!=0)||(shiwan!=0)||(wan!=0))
    87.                   showbuf[4]=0;
    88.         }
    89.         else
    90.         {
    91.                 //显示千位
    92.                 showbuf[4]=qian;
    93.         }
    94.         
    95.         //检测百位
    96.         if(bai==0)
    97.         {
    98.                 showbuf[5]=11;
    99.                 //如果前面位有不为0的,就必须显示0
    100.                 if((qianwan!=0)||(baiwan!=0)||(shiwan!=0)||(wan!=0)||(qian!=0))
    101.                   showbuf[5]=0;
    102.         }
    103.         else
    104.         {
    105.                 //显示百位
    106.                 showbuf[5]=bai;
    107.         }
    108.         
    109.         //检测十位
    110.         if(shi==0)
    111.         {
    112.                 showbuf[6]=11;
    113.                 //如果前面位有不为0的,就必须显示0
    114.                 if((qianwan!=0)||(baiwan!=0)||(shiwan!=0)||(wan!=0)||(qian!=0)||(bai!=0))
    115.                   showbuf[6]=0;
    116.         }
    117.         else
    118.         {
    119.                 //显示十位
    120.                 showbuf[6]=shi;
    121.         }
    122.         
    123.         //检测个位
    124.         if(ge==0)
    125.         {
    126.                         //最后一位必须显示
    127.                   showbuf[7]=0;
    128.         }
    129.         else
    130.         {
    131.                 //显示十位
    132.                 showbuf[7]=ge;
    133.         }
    134. }
    复制代码
    smg.h:
    1. #ifndef _SMG_H_
    2. #define _SMG_H_

    3. #include "chip.h"

    4. //X的值等于0,GPIO低电平。X的值等于1,GPIO高电平。
    5. //Chip_GPIO_SetPinOutHigh(LPC_GPIO,2,0)  //设置P2.0输出高电平
    6. //Chip_GPIO_SetPinOutLow(LPC_GPIO,2,0)  //设置P2.0输出低电平
    7. //位码 :A-->1.0  段码 : B-->1.1
    8. #define LAT_W_A(x) ((x) ? (Chip_GPIO_SetPinOutHigh(LPC_GPIO,1,0)) :  (Chip_GPIO_SetPinOutLow(LPC_GPIO,1,0)));
    9. #define LAT_D_B(x) ((x) ? (Chip_GPIO_SetPinOutHigh(LPC_GPIO,1,1)) : (Chip_GPIO_SetPinOutLow(LPC_GPIO,1,1)));

    10. //#define DataPort(x)  (Chip_GPIO_SetPortValue(LPC_GPIO,2,0XFFFFFF00&x));//设置输出低电平 P2.0~P2.7

    11. #define DataPort(x)  (Chip_GPIO_SetPortValue(LPC_GPIO,2,0XFFFFFF00|x));//设置输出低电平 P2.0~P2.7

    12. extern unsigned char  dofly_DuanMa[11];
    13. extern unsigned char  dofly_WeiMa[8];

    14. extern uint32_t smgdata;
    15. extern uint8_t showbuf[8];
    16. //        
    17. void SMG_Config(void);
    18. void SMG_WRITEONEBIT(uint8_t pos,uint8_t data);
    19. void SMG_ANALYSISDATA(uint32_t tmpdata);

    20. #endif
    复制代码
    timer.h
    1. #ifndef __TIMER_H_
    2. #define __TIMER_H_
    3. #include <stdint.h>

    4. extern uint32_t cnt;


    5. void Time_Init( uint32_t arr, uint32_t psc) ;
    6. void my_delay(uint32_t delay);

    7. #endif
    复制代码
    timer.c
    1. #include "chip.h"
    2. #include "timer.h"
    3. #include "led.h"
    4. #include "smg.h"

    5. uint32_t cnt=0;

    6. /************************************************************************************************
    7. 函数名: void TIMER0_IRQHandler (void)
    8. 函数功能:定时器中断服务函数
    9. 参数:无
    10. 返回值:无
    11. *************************************************************************************************/
    12. <font color="#ff0000">void TIMER0_IRQHandler (void)
    13. {  
    14.                 static uint16_t i=0;
    15.                 Chip_TIMER_ClearMatch(LPC_TIMER0,0);//清除定时中断标志

    16.                 cnt++;
    17.                 //LPC_GPIO2->PIN ^= 0xff;   
    18.                 DataPort(dofly_WeiMa[i]); //取位码

    19.                 LAT_W_A(1);     //位锁存
    20.                 my_delay(5);
    21.                 LAT_W_A(0);
    22.                 my_delay(5);

    23.                 DataPort(dofly_DuanMa[showbuf[i]]); //取显示数据,段码
    24.                 LAT_D_B(1);     //段锁存
    25.                 my_delay(5);
    26.                 LAT_D_B(0);
    27.                 my_delay(5);

    28.                 //my_delay(10000);//扫描间隙延时,时间太长会闪烁,太短会造成重影
    29.                 i++;
    30.                 if(8==i)    //检测8位扫描完全结束?如扫描完成则从第一个开始再次扫描8位
    31.                 i=0;

    32. }</font>

    33. /********************************************************************************************
    34. 函数名称:TIMR_init()
    35. 函数功能:定时器初始化
    36. 参数:预分配值,定时器时间
    37. 返回值:无
    38. *********************************************************************************************/
    39. void Time_Init( uint32_t arr, uint32_t psc)
    40. {

    41.                         Chip_TIMER_Init(LPC_TIMER0);//设置外设功率
    42.                         //Chip_TIMER_SetMatch(LPC_TIMER0,0,(100000000/4)*psc-1);//设置匹配值
    43.         
    44.             Chip_TIMER_SetMatch(LPC_TIMER0,0,(100000/4)*psc-1);//设置匹配值 x ms
    45.         
    46.                         Chip_TIMER_MatchEnableInt(LPC_TIMER0,0);//设置and定时器中断
    47.                         Chip_TIMER_ResetOnMatchEnable(LPC_TIMER0,0);//设置定时器MR0复位               
    48.                         Chip_TIMER_PrescaleSet(LPC_TIMER0,arr-1);//设置设置分频系数
    49.                         Chip_TIMER_Enable(LPC_TIMER0);//使能TIMER0
    50.                         NVIC_EnableIRQ(TIMER0_IRQn);//使能中断


    51. }


    52. void my_delay(uint32_t delay)
    53. {
    54. while(--delay);
    55. }
    复制代码
    main.c:
    1. #include "chip.h"
    2. #include "led.h"
    3. #include "key.h"
    4. #include "uart.h"
    5. #include "timer.h"
    6. #include "smg.h"


    7. int main(void){
    8.         
    9.         SystemCoreClockUpdate();                //系统时钟初始化
    10.         UARTInit(0,115200);//串口0初始化
    11.         Time_Init( 1 ,2); //定时器2ms中断 刷新时间可适当调整
    12.   //LED_Config();  //LED初始化
    13.         SMG_Config();
    14.         
    15.   smgdata=0;
    16.         
    17.         while(1){

    18. //                //如果不用定时器就只能while
    19. //                DataPort(dofly_WeiMa[i]); //取位码

    20. //                LAT_W_A(1);     //位锁存
    21. //                my_delay(5);
    22. //                LAT_W_A(0);
    23. //                my_delay(5);

    24. //                DataPort(dofly_DuanMa[i]); //取显示数据,段码
    25. //                LAT_D_B(1);     //段锁存
    26. //                my_delay(5);
    27. //                LAT_D_B(0);
    28. //                my_delay(5);

    29. //                my_delay(10000);//扫描间隙延时,时间太长会闪烁,太短会造成重影
    30. //                i++;
    31. //                if(8==i)    //检测8位扫描完全结束?如扫描完成则从第一个开始再次扫描8位
    32. //                        i=0;
    33.                  
    34.      //把数据拆分成数码管对应位的数字
    35.                  SMG_ANALYSISDATA(smgdata);
    36.                  my_delay(10000000);//显示的时间
    37.                  smgdata=smgdata+10;
    38.                  if(smgdata>100000000) smgdata=0;

    39.         }
    40. }

    复制代码
    编译下载,查看现象:
    34 (1).gif 代码下载:
    【08】LPC1768_定时器实验.rar (4.26 MB, 下载次数: 28)
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-29 13:34 , Processed in 0.103624 second(s), 19 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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