想用msp430 g2553做一个时钟的程序该怎么写?

2019-07-15 15:54发布

想用msp430 g2553做一个时钟,要实现四位数码管显示小时和分钟,中间冒号每秒闪烁一次,三个按键控制调节时间,程序写了一部分,想请教下大家帮忙写下“时间”和“按键控制”部分的程序。谢谢!!!
#include <msp430g2553.h>
//宏定义======================================================================================//
#define DIO_high        (P2OUT |= BIT2)                //高电平   DIO ==> P1.5 (IIC总线需要三根线DIO、CLK、STB)
#define DIO_low                (P2OUT &= ~BIT2)        //低电平
#define CLK_high        (P2OUT |= BIT1)                //高电平   CLK ==> P1.4 (IIC总线需要三根线DIO、CLK、STB)
#define CLK_low                (P2OUT &= ~BIT1)        //低电平
#define STB_high        (P2OUT |= BIT0)                //高电平   STB ==> P1.2 (IIC总线需要三根线DIO、CLK、STB)
#define STB_low                (P2OUT &= ~BIT0)        //低电平

#define DIO_IN          (P2DIR &= ~BIT2)         //输入状态(DIO设为输入)
#define DIO_OUT          (P2DIR |= BIT2)          //输出状态
#define DIO_READ         (P2IN & BIT2)                  //读引脚电平

//变量声明=====================================================================================//
unsigned char sec_count;                                //20ms计数值(记50次即到达1s)
unsigned char disp_flag;                                //显示刷新标志

unsigned char const num[20] = {        0x3f,
                                0x06,
                                0x5b,
                                0x4f,
                                0x66,
                                0x6d,
                                0x7d,
                                0x07,
                                0x7f,
                                0x6f,
                                                      };                 //0~9显示代码
//==========================================================================================//
void delayms(unsigned int temp)         //延时
{
        unsigned int i,j;
        for(j=temp;j>0;j--)
             for(i=0;i<3210;i++);
}
//=========================================================================================//
void LED_ON3(void)
{
        unsigned char ledcc;                                                //闪烁三次计数
        unsigned int x;                                                                //
        for(ledcc=0; ledcc<6; ledcc++)                                //LED灯闪烁三次
        {
                P1OUT ^= BIT0 + BIT6;                                        //翻转
                for(x=0; x<50000; x++);                                        //延时
        }
}
//==========================================================================================//
void init_port(void)
{
        P2SEL = 0X00;                                        //P2口全部设为普通I/O口
        P2DIR |=  BIT2;                                        //DIO ==> P3.5 (IIC总线需要三根线DIO、CLK、STB)
        P2DIR |=  BIT1;                                        //CLK ==> P3.4 (IIC总线需要三根线DIO、CLK、STB)
        P2DIR |=  BIT0;                                        //STB ==> P3.2 (IIC总线需要三根线DIO、CLK、STB)
        DIO_high;                                                //
        CLK_high;                                                //
        STB_high;                                                //初始时DIO、CLK、STB初始化时全部置“1”
        P1DIR |= BIT0 + BIT6;                        //P1.0红 {MOD}LED,P1.6绿 {MOD}LED
        P1OUT &= ~(BIT0 + BIT6);                //上电时全灭
}
//写数据====================================================================================//
void send_data(unsigned char dat)          //写数据
{
    unsigned char j;
    STB_low;                                                 //STB下降沿
    for(j=0; j<8; j++)                       //一个字节8位数据
    {
            CLK_low;                                      //CLK低电平
            if((dat&0x01) == 1)                        //最低位为"1"
                    DIO_high;                                //输出高电平
            else
                    DIO_low;                                //最低位为"0"
        CLK_high;                                     //CLK高电平
        dat = dat>>1;                                 //右移一位
    }
}
//*读数据*==================================================================================//
unsigned char read_data(void)            //读数据
{
        unsigned char i,k;                          //
        STB_low;                                              //STB下降沿
        DIO_high;                                                //"读数据"需要DIO下降沿
        delayms(1);                                         //延时配合时序
        for(i=0;i<8;i++)                                  //需要读出8位数据
        {
                CLK_low;                                         //CLK低电平
                k = k >> 1;                                    //k右移一位
                if(DIO_READ == 0)               //如果读到DIO为"0"
                {
                        k = k & 0x7f;                    //最高位清0(右移8次后即为最低位)
                }
                else
                {                               //如果读到DIO为"1"
                        k = k | 0x80;                          //最高位置1(右移8次后即为最低位)
                }
                CLK_high;                                         //CLK高电平
        }
        return(k);                                                 //返回k的值
}
//==========================================================================================//
void TM1638_init(void)                                                                //TM1638初始化
{
        unsigned char i;
        STB_high;                                                                                //为了进入send_data()后产生"下降沿"
    send_data(0x80);                                                                //关显示
    STB_high;                                                       //写完数据后STB需置1
    send_data(0x03);                                                                //显示模式
    STB_high;                                                       //写完数据后STB需置1
    send_data(0x40);                                                                //自动地址加1模式

        send_data(0xc0);                                                                //上电后从起始地址00H-15H全部清零(全灭)
        for(i=0; i<17; i++)                                                                //共16个单元清零(00H-15H)
        {
                send_data(0x00);                                                        //全灭
        }
}
//==========================================================================================//
void start_disp(void)
{
        unsigned int x;
        STB_high;                                                                             //为了进入send_data()后产生"下降沿"
        send_data(0xc0);                                                                //起始地址
        send_data(num[9]);send_data(num[3]);                        //分_L
        send_data(num[5]);send_data(num[2]);                        //分_H
        send_data(num[3]);send_data(num[1]);                        //时_L
        send_data(num[2]);send_data(num[0]);                        //时_H
        STB_high;                                                                                 //
        send_data(0x8f);                                                                //开显示
        for(x=0; x<50000; x++);                                                        //延时
}
//主函数==============================================================================================//
void main(void)
{
        WDTCTL = WDTPW + WDTHOLD;                                           //停止看门狗定时器
        init_port();                                                        //I/O口初始化
        LED_ON3();                                                        //开机后红 {MOD}LED、绿 {MOD}LED一起闪烁三次
        BCSCTL1 = CALBC1_1MHZ;                                                 //
        DCOCTL = CALDCO_1MHZ;                                                //上面两句将内部DCO校准至1MHz
        TM1638_init();                                                        //TM1638初始化
        start_disp();                                                        //开机显示"23:59"

        CCTL0 = CCIE;                                             //CCR0 interrupt enabled CCR0中断使能
        CCR0 = 20971;                                                                        //CCR0计数值为20971----> 20971/1048576 = 0.02000 s = 20ms
        TACTL = TASSEL_2 + MC_1 + TACLR;                           //SMCLK, upmode 选SMCLK作为计数时钟,增计数模式
        _BIS_SR(GIE);                                                         //Enter LPM0 w/ interrupt 进入低功耗模式0,并开总中断允许

        P1OUT &= ~BIT6;                                                                        //绿LED灯灭(运行时只闪烁红 {MOD}LED)

        while(1)                                                                                //系统主循环
        {
                if(disp_flag == 25)                                                        //到0.5s吗?
                {
                        STB_high;                                                             //为了进入send_data()后产生"下降沿"
                        send_data(0xc0+8);                                                //起始地址
                        send_data(num[9]);send_data(num[9]);        //显示冒号
                        STB_high;                                                                 //
                }
                if(disp_flag == 50)                                                        //到1s吗?
                {
                        disp_flag = 0x00;                                                //显示刷新标志清0
                        STB_high;                                                                //
                        send_data(0xc0+8);                                                //起始地址
                        send_data(0x00);send_data(0x00);                                 //清冒号(冒号灭)
                        STB_high;                                                                //
                }
        }
}
//============================================================================================//
#pragma vector=tiMER0_A0_VECTOR                                // Timer A0 interrupt service routine (Timer_A0 中断服务程序)
__interrupt void Timer_A (void)                                //每20ms产生一次定时器中断
{
        sec_count++;                                                        //计数值每20ms加1
        disp_flag++;                                                        //
        if(sec_count == 25)                                                //加25次后,即到了0.5s (25 * 20ms = 500ms = 0.5s)
        {
                sec_count = 0x00;                                        //计数值清0
                P1OUT ^= 0x01;                           //Toggle P1.0 每0.5s翻转一次(即0.5s亮、0.5s灭,也即1s亮一次)
        }
}
//============================================================================================//



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
michael_llh
1楼-- · 2019-07-15 21:27
请大家帮忙写的话比较难,除非你给报酬是吧,这个很现实的东西。所以你要自己动手写,具体遇到问题来问大家,那我相信大家都会帮你的。但是你这样让别人帮忙写一般不大可能,别人没有这个时间,也没有这个义务帮你写,你说是吗?
洧十二
2楼-- · 2019-07-15 22:42
谢谢。。。。。。。。。。。。
西瓜不甜1995
3楼-- · 2019-07-16 01:36
正好需要 字数补丁
yencheer
4楼-- · 2019-07-16 05:30
学习

一周热门 更多>