历史上的今天
返回首页

历史上的今天

今天是:2025年03月03日(星期一)

正在发生

2020年03月03日 | 基于MSP430f149单片机的简单秒表

2020-03-03 来源:eefocus

单片机:MSP430f149


实现功能:按下一个按键,计时开始,再次按下该按键计时暂停,即由一个按键实现暂停看开始功能,设置另一个按键,按下该按键三秒以上,秒表清零。要求计时精度,10毫秒。


该实验用到了MSP430单片机的timerA的定时功能,显示设备而用到了LCD1602.


代码如下:

#include

#include "Config.h"

int second = 0, minute = 0, count = 0, flag = 0, a = 0, b = 0, c = 0;

unsigned char FlagLcd;

//*************************************************************************

// 初始化IO口子程序

//*************************************************************************

void Port_init()

{

        P4SEL = 0x00;

        P4DIR = 0xFF;                   //数据口输出模式

        P5SEL = 0x00;

        P5DIR|= BIT5 + BIT6 + BIT7;     //控制口设置为输出模式

        P1SEL = 0x00;                   //P1普通IO功能

        P1DIR = 0xF0;                   //P10~P13输入模式,外部电路已接上拉电阻

        P1IE  = 0x0f;                   //开启 位中断

        P1IES = 0x00;                   //上升沿触发中断

        P1IFG = 0x00;                   //软件清零中断标志寄存器

}

 

//***********************************************************************

// 显示屏命令写入函数

//***********************************************************************

void LCD_write_com(unsigned char com) 

{

RS_CLR;

RW_CLR;

EN_SET;

DataPort = com;                 //命令写入端口

delay_ms(5);

EN_CLR;

}

 

//***********************************************************************

// 显示屏数据写入函数

//***********************************************************************

void LCD_write_data(unsigned char data) 

{

RS_SET;

RW_CLR;

EN_SET;

DataPort = data;                //数据写入端口

delay_ms(5);

EN_CLR;

}

 

//***********************************************************************

// 显示屏清空显示

//***********************************************************************

void LCD_clear(void) 

{

LCD_write_com(0x01);            //清屏幕显示

delay_ms(5);

}

 

//***********************************************************************

// 显示屏字符串写入函数

//***********************************************************************

void LCD_write_str(unsigned char x,unsigned char y,int w) 

{

    if (y == 0) 

    {

    LCD_write_com(0x80 + x);        //第一行显示

    }

    else 

    {

    LCD_write_com(0xC0 + x);        //第二行显示

    }

 

    LCD_write_data(48+w);

   

}

 

//***********************************************************************

// 显示屏单字符写入函数

//***********************************************************************

void LCD_write_char(unsigned char x,unsigned char y,unsigned char data) 

{

    if (y == 0) 

    {

    LCD_write_com(0x80 + x);        //第一行显示

    }

    else 

    {

    LCD_write_com(0xC0 + x);        //第二行显示

    }

    

    LCD_write_data( data);  

}

 

//***********************************************************************

// 显示屏初始化函数

//***********************************************************************

void LCD_init(void) 

{

    LCD_write_com(0x38); //显示模式设置  

    delay_ms(5);

    LCD_write_com(0x08); //显示关闭

    delay_ms(5);

    LCD_write_com(0x01); //显示清屏

    delay_ms(5);

    LCD_write_com(0x06); //显示光标移动设置

    delay_ms(5);

    LCD_write_com(0x0C); //显示开及光标设置

    delay_ms(5);

}

//***********************************************************************

//             TIMERA初始化,设置为UP模式计数

//***********************************************************************

void TIMERA_Init(void)                                   //UP模式计数,计数周期为CCR0+1

{

  TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE;     //SMCLK做时钟源,8分频,增加计数模式,开中断

  TACCR0 = 9999;                                         //CCR0=9999,10ms中断一次

}

//***********************************************************************

//             关闭计时,暂停计数

//***********************************************************************

void TimerA_end(void)

{

    TACTL &= 0xfffd;

}

//**********************************************************************

// 扫描按键P1^2是否长按

//**********************************************************************

void GetKey()//长按,返回2;短按,返回1。

{

    unsigned char keyRetu=0; //返回的按键值

    static unsigned char s_keyState=0,keyTime=0; //按键状态,按键按下的时间

    switch (s_keyState)

    {

    case 0:

      {

        if((P1IN&0x02)==0x00) //检测到有按键,转到状态1,相当于是消抖过程。

        {

            s_keyState=1;

        } 

      }

       break;

    case 1:

      {

        if((P1IN&0x02)==0x00) //再次检测到有按键,转到状态2

        {

            s_keyState=2;

            keyTime=0; //清零按键时间计数器

        }

        else

        {

            s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0

        }

      }

        break;

    case 2:

      {

        if((P1IN&0x02)==0x02) //检测到按键松开

        {

            s_keyState=0; //状态转到状态0

            keyRetu=1; //输出1

        }

        else

        {

            if(++keyTime>=150) //按下时间>1s

                {

                    s_keyState=3; //转到状态3

                    keyTime=0; //清零按键时间计数器

                    keyRetu=2; // 输出2

                }

        }

      }

        break;

    case 3:

      {

        if((P1IN&0x02)==0x02) //检测到按键松开

        {

            s_keyState=0; //状态转到状态0

        }

        else

        {

            s_keyState=3; //转到状态3

        }

      }

        break;

    }

    if(keyRetu==2)

    {

      a = 0;

      b = 0;

      c = 0;

      count = 0;

      second = 0;

      minute = 0;  

    }

}

 

//***********************************************************************

//             TIMERA中断服务程序,需要判断中断类型

//***********************************************************************

#pragma vector = TIMERA1_VECTOR

__interrupt void Timer_A(void)

{

  switch(TAIV)                                  //需要判断中断的类型

  {

  case 2:break;

  case 4:break;

  case 10:count++;break;                         //设置标志位Flag

  }

  if(count==100)                                 //100次为1秒

  {

    second++;

    count=0;                       

  }

  if(second == 60)

  {

    minute++;

    second = 0;

  }

  GetKey();

}

//**********************************************************************

// P1口中断服务程序,需要判断

//**********************************************************************

#pragma vector = PORT1_VECTOR

__interrupt void P1_IRQ(void)

{

  switch(P1IFG&0x0F)

  {

  case 0x01: {

                  

                  flag++;

                  P1IFG=0x00;

              }

              break;

  default:P1IFG = 0x00;break;                   

  }

}

//***********************************************************************

//      主程序

//***********************************************************************

void main(void)

{

     WDT_Init();                        //看门狗设置                        

     Clock_Init();                       //系统时钟设置

     Port_init();                        //系统初始化,设置IO口属性

推荐阅读

史海拾趣

EF Johnson Technologies Inc公司的发展小趣事

作为一家具有社会责任感的企业,EF Johnson公司始终关注环境保护和社会公益。公司积极响应国家节能减排政策,采用环保材料和清洁能源进行生产活动。同时,EF Johnson还积极参与社会公益活动,捐赠资金和物资支持教育事业和贫困地区的发展。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实基础。

佰鸿(BrtLed)公司的发展小趣事

佰鸿公司在2008年成立之初,正值LED行业蓬勃发展的时期。面对激烈的市场竞争,公司经过深入的市场调研,确立了LED大功率路灯制造商、方案提供商、系统集成商的市场定位。随后,佰鸿在大功率路灯照明市政LED改造方面投入大量精力,成功完成了兰池大道、咸阳快速干道等多个大型LED路灯方案设计及老旧路灯改造项目。这些项目的成功实施,不仅为佰鸿在市场上站稳了脚跟,也为其后续发展奠定了坚实的基础。

Cables To Go公司的发展小趣事

品牌建设是公司发展的重要一环。Cables To Go公司注重品牌形象的塑造和传播,通过参加行业展会、举办产品发布会等方式提升品牌知名度。同时,公司还积极参与社会公益活动,展现企业的社会责任感和担当精神。这些举措有效地提升了Cables To Go的品牌形象和影响力,为公司的长期发展奠定了坚实的基础。

振华(CEC)公司的发展小趣事

中国振华电子集团有限公司(简称振华)自成立之初,就致力于电子产品的研发与生产。初期,公司面临着技术落后、资金短缺等诸多困难,但创始人及团队凭借坚定的信念和不懈的努力,成功开发出了一系列具有市场竞争力的电子产品。随着产品质量的提升和市场份额的扩大,振华逐渐在电子行业中崭露头角。

BURGESS公司的发展小趣事

随着时间的推移,BURGESS不断扩展其业务范围,并于1984年首次开发租船服务。这一创新举措不仅满足了客户多样化的需求,也进一步巩固了其在行业内的领先地位。此后,BURGESS继续其国际化步伐,成功进驻美国市场,进一步扩大了其全球影响力。

Extech公司的发展小趣事

1994年,Extech公司推出了国内第一套基于“AutoCAD FOR WINDOWS”的XTMCAD软件,这一创新举措标志着公司在CAD领域迈出了坚实的步伐。XTMCAD软件凭借其先进的技术和易用性,迅速获得了市场的认可,并在同年荣获了国家教委科技进步一等奖。这一荣誉不仅是对Extech公司技术实力的肯定,也为公司未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

哪位知道 印字为 PBA1 TSOP-5 贴片 是什么IC

:L 哪位知道 印字为 PBA1  TSOP-5 贴片 是什么IC…

查看全部问答>

多线程技术在数据实时采集分析中的应用(2)

数据分析线程在读信号量和消费者指针的控制下成功读取一包数据后,根据通道标示号提取此包中每个通道的数据,写入对应的内存映射文件中,再调用数据处理函数对每个通道数据做误码分析。误码分析的结果可由主界面线程调用显示。数据分解流程如图4所 ...…

查看全部问答>

如何从零开始开发一款嵌入式产品(20年的嵌入式经验)

这是在其他网站上看到的,有多好就不说了,大家看看吧! …

查看全部问答>

Windows CE驱动程序开发.pdf

Windows CE驱动程序开发.pdf…

查看全部问答>

S3C6410 Camera接口获取图像成功,但是数据全是0.求助!!!

我用在WINCE 使用S3C6410的摄像头驱动,应用程序中使用DeviceIoControl来设置摄像头属性和获取一帧数据。 在驱动的程序中看到了它的控制代码如下: // prepare  准备好DMA缓存,设置成 CAPTURE / VIDEO / PREVIEW 模式 #define  ...…

查看全部问答>

在应用程序里如何查询某个USB连在哪一个USB controller上

在具有多个USB controller和多个USB设备的情况下, 如何查询这些USB设备连接在哪个USB controller上。 设备管理器中,如果选择“依连接排序设备”,就可以看到所 有设备的Device Tree,VC里有什么API或者什么方法可以获得 类似的信息吗? 请高 ...…

查看全部问答>

昨天收到开发板,今天做了第一块STM32的板子

看看有没有问题,第一次玩STM32,没有什么经验,硬件是按照st-link制作的,做了一些修改(st-link本来也是一块开发板)。准备自己做JTAG下载工具或者调试工具,呵呵,如果搞的定的话。PCB还没铺地,其他都OK了。发现一个错误,应该BOOT1接地,BO ...…

查看全部问答>

μC/OS-II实时性能测试指标

μC/OS-II实时性能测试指标   衡量嵌入式实时操作系统的好坏一般主要参考以下主要性能指标参数: 任务切换时间、中断响应时间、任务响应时间、任务创建/删除时间、交替信号量时间、取得/释放信号量时间、交替消息队列传输时间等。本文仅对前2个 ...…

查看全部问答>

51单片机实践群179146897

欢迎51单片机初学者加入…

查看全部问答>

各位大侠看看我的程序哪儿有问题啊

我用hot51开发板做实现测量电压和输出相同电压的功能,但是没有响应,麻烦大家指出我程序的问题,谢谢了 /* PCF8591四路电压 LCD1602显示 参考电压接至5V电源 */ /* 最小输出电压:0.00V 最大输出电压:5.00V 分辨率:0.02V */ /****************** ...…

查看全部问答>