找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4178|回复: 0
打印 上一主题 下一主题
收起左侧

基于MSP430G2553单片机的简易频率计程序(1Hz-60KHz)

[复制链接]
跳转到指定楼层
楼主
一个简易频率计,通过定时器A采用计数法完成信号频率测量,并将被测频率值通过LCD12864液晶串行显示。频率可测量范围在1Hz60KHz之间。




单片机源程序如下:

  1. /*
  2. * 头文件
  3. */
  4. #include<msp430g2553.h>
  5. #include "stdio.h"
  6. /*
  7. * 全局变量的定义和宏定义
  8. */
  9. unsigned int  start,end;
  10. unsigned long int F = 0;
  11. unsigned char TA_overflow;
  12. unsigned int TA_i = 0;
  13. unsigned int port_i;
  14. unsigned chartab[]={"0123456789"};
  15. unsigned char a[8];
  16. unsigned char int_to_string[10];
  17. unsigned char int_array[10];
  18. #define uchar unsigned char
  19. #define uint unsigned int
  20. #define CS_0   P2OUT &= ~BIT0  //片选为低电平
  21. #define CS_1   P2OUT |= BIT0      //片选为高电平
  22. #define SID_0  P2OUT &= ~BIT1  //串行数据输入为0
  23. #define SID_1  P2OUT |= BIT1      //串行数据输入为1
  24. #define SCLK_0 P2OUT &= ~BIT2  //时钟线拉低
  25. #define SCLK_1 P2OUT |= BIT2      //时钟线拉高
  26. #define PSB_0  P2OUT &= ~BIT3  //出行输入
  27. #define LCD_DIR_OUT P2DIR |= BIT0 + BIT1 + BIT2 + BIT3           //4个端口设置为输出

  28. /********************************************************************
  29. * 名称 : SendByte
  30. * 功能 : 发送数据
  31. * 输入 : Dbyte
  32. * 输出 : 无
  33. ***********************************************************************/

  34. void SendByte(uchar Dbyte)
  35. {
  36.        uchari;
  37.        LCD_DIR_OUT;
  38.        for(i= 0;i < 8;i++)
  39.        {
  40.               if((Dbyte<< i) & 0x80)
  41.               {
  42.                      SID_1;
  43.               }
  44.               else
  45.               {
  46.                      SID_0;
  47.               }
  48.               SCLK_0;
  49.               _delay_cycles(2);
  50.               SCLK_1;
  51.        }
  52. }

  53. /********************************************************************
  54. * 名称 : Write_Instruction
  55. * 功能 : 向LCD写指令
  56. * 输入 : data
  57. * 输出 : 无
  58. ***********************************************************************/
  59. void Write_Instruction(uchar data)
  60. {
  61.        LCD_DIR_OUT;
  62.        CS_1;
  63.        SendByte(0xf8);
  64.        SendByte(data& 0xf0);
  65.        SendByte((data<< 4) & 0xf0);
  66.        _delay_cycles(20);
  67. }

  68. /********************************************************************
  69. * 名称 : Write_Data
  70. * 功能 :向LCD写入数据
  71. * 输入 : data
  72. * 输出 : 无
  73. ***********************************************************************/
  74. void Write_Data(uchar data)
  75. {
  76.        LCD_DIR_OUT;
  77.        CS_1;
  78.        SendByte(0xfa);
  79.        SendByte(data& 0xf0);
  80.        SendByte((data<< 4) & 0xf0);
  81.        _delay_cycles(20);
  82. }

  83. /********************************************************************
  84. * 名称 : LCD12864_Delay()
  85. * 功能 : 初始化LCD12864
  86. * 输入 : 无
  87. * 输出 : 无
  88. ***********************************************************************/
  89. void LCD_Init()
  90. {
  91.        LCD_DIR_OUT;   //设置输入方向为输出
  92.        PSB_0;          //LCD为串行输入方式
  93.        Write_Instruction(0x30);      //基本指令集
  94.        _delay_cycles(10000);
  95.        Write_Instruction(0x02);      //地址归位
  96.        _delay_cycles(10000);
  97.        Write_Instruction(0x0c); //整体显示打开,游标关闭
  98.        _delay_cycles(10000);
  99.        Write_Instruction(0x01);      //清除显示
  100.        _delay_cycles(10000);
  101.        Write_Instruction(0x06);       //游标右移
  102.        _delay_cycles(10000);
  103.        Write_Instruction(0x80);      //设定显示的起始地址
  104.        _delay_cycles(10000);
  105. }

  106. /********************************************************************
  107. * 名称 : Write_Pos
  108. * 功能 : 确定输入数据的位置
  109. * 输入 : x,y
  110. * 输出 : 无
  111. ***********************************************************************/
  112. void Write_Pos(uchar x,uchar y)
  113. {
  114.    uchar pos;
  115.    if(x == 1)         //第一行显示
  116.            x = 0x80;
  117.    else if(x == 2)    //第二行显示
  118.            x = 0x90;
  119.    else if(x == 3)    //第三行显示
  120.            x = 0x88;
  121.    else if(x == 4)    //第四行显示
  122.            x = 0x98;
  123.    pos = x + y-1;
  124.    Write_Instruction(pos);//显示地址
  125. }

  126. /********************************************************************
  127. * 名称 : Write_Word_To_12864
  128. * 功能 : 在坐标x,y处写入数据
  129. * 输入 : x,y,*word
  130. * 输出 : 无
  131. ***********************************************************************/
  132. void Write_Word_To_12864(uchar x,uchary,uchar *word)
  133. {
  134.        uchari;
  135.        LCD_Init();
  136.        Write_Pos(x,y);
  137.        for(i= 0;*(word+i)!='\0';i++)
  138.        {
  139.               Write_Data(word[i]);
  140.        }
  141. }

  142. void ShowInit()
  143. {
  144.        Write_Word_To_12864(1,1,"频率计:");
  145.        _delay_cycles(50000);
  146.        Write_Pos(2,7);
  147.        Write_Data('H');
  148.        Write_Data('z');
  149.        _delay_cycles(10000);
  150. }

  151. void ShowF()
  152. {
  153.        Write_Pos(2,4);

  154.        if(F>= 100000)
  155.        {
  156.               Write_Data(tab[F/100000]);
  157.               Write_Data(tab[F%100000/10000]);
  158.               Write_Data(tab[F%10000/1000]);
  159.               Write_Data(tab[F%1000/100]);
  160.               Write_Data(tab[F%100/10]);
  161.               Write_Data(tab[F%10]);
  162.               _delay_cycles(1000);
  163.        }
  164.        elseif(F >= 10000)
  165.        {
  166.               Write_Data(tab[F/10000]);
  167.               Write_Data(tab[F%10000/1000]);
  168.               Write_Data(tab[F%1000/100]);
  169.               Write_Data(tab[F%100/10]);
  170.               Write_Data(tab[F%10]);
  171.               _delay_cycles(1000);
  172.        }
  173.        elseif(F >= 1000)
  174.        {
  175.               Write_Data(tab[F/1000]);
  176.               Write_Data(tab[F%1000/100]);
  177.               Write_Data(tab[F%100/10]);
  178.               Write_Data(tab[F%10]);
  179.               _delay_cycles(1000);
  180.        }
  181.        elseif(F >= 100)
  182.        {
  183.               Write_Data(tab[F/100]);
  184.               Write_Data(tab[F%100/10]);
  185.               Write_Data(tab[F%10]);
  186.               _delay_cycles(1000);
  187.        }
  188.        elseif(F >= 10)
  189.        {
  190.               Write_Data(tab[F/10]);
  191.               Write_Data(tab[F%10]);
  192.               _delay_cycles(1000);
  193.        }
  194.        else
  195.        {
  196.               Write_Data(tab[F]);
  197.               _delay_cycles(1000);
  198.        }
  199. }
  200. /********************************************************************
  201. * 名称 : Init_uart0
  202. * 功能 : 初始化串口
  203. * 输入 : 无
  204. * 输出 : 无
  205. ***********************************************************************/
  206. void Init_uart0()
  207. {
  208.   UCA0CTL1|=UCSWRST;   //UCA0软件复位
  209.   //UCA0CTL0&=~UC7BIT;//字符长度为8
  210.   UCA0CTL1|=UCSSEL_2;//选择系统时钟:SMCLK
  211.   UCA0BR0=0x6D;  //波特率为9600
  212.   UCA0BR1=0;
  213.   UCA0MCTL=0;//UCA0MCTL=UCBRS0;
  214.   IE2=UCA0RXIE+UCA0TXIE;//开接收使能
  215.   UCA0CTL1&=~UCSWRST;
  216.   P1SEL|=BIT1+BIT2; //将P1.1 P1.2设为第二功能
  217.   P1SEL2|=BIT1+BIT2;
  218. }

  219. /********************************************************************
  220. * 名称 : Uart0Sends
  221. * 功能 : 串口发送数据
  222. * 输入 : *s
  223. * 输出 : 无
  224. ***********************************************************************/
  225. void Uart0SendsData(char *s)
  226. {
  227.   while(*s!='\0')
  228.    {
  229.     UCA0TXBUF=*s;
  230.     while((IFG2&UCA0TXIFG)==0); //查询发送是否结束
  231.     IFG2&=~UCA0TXIFG; //清除发送一标志位
  232.     s++;
  233.    }
  234. }


  235. /********************************************************************
  236. * 名称 : Init_In
  237. * 功能 :初始化外部终端
  238. * 输入 : 无
  239. * 输出 : 无
  240. ***********************************************************************/
  241. void Init_In()
  242. {
  243.        P1DIR|= BIT6;
  244.        P1DIR&= ~BIT3;
  245.        P1IES|= BIT3;
  246.        P1IE|= BIT3;
  247.        P1IFG&= ~BIT3;
  248.        _EINT();
  249. }


  250. void Init_Timer()
  251. {
  252.          TACCTL0 = CCIE;                             // CCR0 interruptenabled
  253.          TACCR0 = 1;
  254.          TACTL = TASSEL_1 + MC_1 + TAIE + TACLR;  //up mode
  255. }

  256. /********************************************************************
  257. * 名称 : Int_To_String
  258. * 功能 :将一个int型数据转换为String型
  259. * 输入 : now_f
  260. * 输出 : 无
  261. ***********************************************************************/
  262. void Int_To_String(unsigned long int now_f)
  263. {
  264.        intj = 0;
  265.        for(j= 0; ;j++)
  266.        {
  267.               int_array[j]= now_f % 10 + 48 ;
  268.               now_f= now_f / 10;
  269.               if(now_f== 0) break;
  270.        }
  271.        inti = j ;
  272.        for(i= j , j = 0; i >= 0; i--,j++)
  273.        {
  274.               int_to_string[j]= int_array[i];
  275.        }
  276. }
  277. void main()
  278. {
  279.        WDTCTL= WDTPW + WDTHOLD;
  280.          P1DIR |= BIT7;                            // P1.0 output
  281.          P1DIR |= BIT0;

  282.         if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
  283.          {
  284.            while(1);                               // Ifcalibration constants erased
  285.                                                    // do not load, trap CPU!!
  286.          }
  287.         //1Mhz
  288.          BCSCTL1 = CALBC1_1MHZ;                    // Set range
  289.          DCOCTL = CALDCO_1MHZ;                     // Set DCO step +modulation */


  290.        LCD_Init();
  291.        Init_In();
  292.        Init_Timer();
  293.        Init_uart0();
  294.        ShowInit();
  295.        while(1)
  296.        {
  297.               ShowF();
  298.        }
  299. }
  300. #pragma vector=PORT1_VECTOR
  301. __interrupt void port_1()
  302. {

  303.        if(P1IFG& BIT3)
  304.        {
  305.               P1OUT^= BIT6;
  306.               port_i++;
  307.               if(port_i>=100)
  308.               {
  309.                      port_i= 0;
  310.                      F=(unsigned long int)((1000000*100.0)/((TA_overflow*65536)+TAR));
  311.                      TA_overflow= 0;
  312.                      TACTL|= TACLR;
  313.               }
  314.        }
  315.        P1IFG&= ~BIT3;
  316. }

  317. // Timer A0 interrupt service routine
  318. #pragma vector=TIMER0_A0_VECTOR
  319. __interrupt void Timer_A (void)
  320. {
  321.        P1OUT^= BIT7;
  322.        TA_i++;
  323.        if(TA_i== 2000)
  324.        {P1OUT^= BIT0;
  325.               TA_i= 0;
  326.               Int_To_String(F);
  327.               unsignedchar *s = int_to_string;
  328.               Uart0SendsData(s);
  329.               Uart0SendsData("1000");
  330.        }
  331. }


  332. #pragma vector=TIMER0_A1_VECTOR
  333. __interrupt void Timer_A1()
  334. {
  335.        switch(TA0IV)
  336.        {
  337.               case2:break;
  338.               case4:break;
  339.               case10:TA_overflow++;break;
  340.        }
  341. }

  342. /********************************************************************
  343. * 名称 : usart0_rx
  344. * 功能:串口中断入口
  345. ***********************************************************************/
  346. #pragma vector=USCIAB0RX_VECTOR
  347. __interrupt void usart0_rx(void)
  348. {
  349. while((IFG2&UCA0RXIFG)==0);
  350. //a=RXBUF0;
  351. //i++;
  352. a[0]=UCA0RXBUF;
  353. }

复制代码


基于MSP430G2553的简易频率计.docx (1.11 MB, 下载次数: 43)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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